Made many changes to eliminate gcc warnings. Made various
[external/binutils.git] / ld / ldexp.c
1 /* This module handles expression trees.
2 Copyright (C) 1991 Free Software Foundation, Inc.
3 Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
4
5 This file is part of GLD, the Gnu Linker.
6
7 GLD is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GLD is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GLD; see the file COPYING.  If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22 This module is in charge of working out the contents of expressions.
23
24 It has to keep track of the relative/absness of a symbol etc. This is
25 done by keeping all values in a struct (an etree_value_type) which
26 contains a value, a section to which it is relative and a valid bit.
27
28 */
29
30
31 #include "bfd.h"
32 #include "sysdep.h"
33
34 #include "ld.h"
35 #include "ldsym.h"
36 #include "ldmain.h"
37 #include "ldmisc.h"
38 #include "ldexp.h"
39 #include "ldgram.h"
40 #include "ldlang.h"
41
42 static void
43 exp_print_token (code)
44      token_code_type code;
45 {
46   static CONST struct  {
47     token_code_type code;
48     char *name;
49   } table[] =
50       {
51         INT,    "int",
52         NAME,"NAME",
53         PLUSEQ,"+=",
54         MINUSEQ,"-=",
55         MULTEQ,"*=",
56         DIVEQ,"/=",
57         LSHIFTEQ,"<<=",
58         RSHIFTEQ,">>=",
59         ANDEQ,"&=",
60         OREQ,"|=",
61         OROR,"||",
62         ANDAND,"&&",
63         EQ,"==",
64         NE,"!=",
65         LE,"<=",
66         GE,">=",
67         LSHIFT,"<<",
68         RSHIFT,">>=",
69         ALIGN_K,"ALIGN",
70         BLOCK,"BLOCK",
71         SECTIONS,"SECTIONS",
72         SIZEOF_HEADERS,"SIZEOF_HEADERS",
73         NEXT,"NEXT",
74         SIZEOF,"SIZEOF",
75         ADDR,"ADDR",
76         MEMORY,"MEMORY",
77
78
79
80
81
82         DEFINED,"DEFINED",
83         TARGET_K,"TARGET",
84         SEARCH_DIR,"SEARCH_DIR",
85         MAP,"MAP",
86         LONG,"LONG",
87         SHORT,"SHORT",
88         BYTE,"BYTE",
89         ENTRY,"ENTRY",
90         0,(char *)NULL} ;
91
92
93
94   unsigned int idx;
95   for (idx = 0; table[idx].name != (char*)NULL; idx++) {
96     if (table[idx].code == code) {
97       fprintf(config.map_file, "%s", table[idx].name);
98       return;
99     }
100   }
101   /* Not in table, just print it alone */
102   fprintf(config.map_file, "%c",code);
103 }
104
105 static void 
106 make_abs (ptr)
107      etree_value_type *ptr;
108 {
109     asection *s = ptr->section->bfd_section;
110     ptr->value += s->vma;
111     ptr->section = abs_output_section;
112 }
113
114 static etree_value_type
115 new_abs (value)
116      bfd_vma value;
117 {
118   etree_value_type new;
119   new.valid = true;
120   new.section = abs_output_section;
121   new.value = value;
122   return new;
123 }
124
125 static void 
126 check (os, name, op)
127      lang_output_section_statement_type *os;
128      CONST char *name;
129      CONST char *op;
130 {
131   if (os == (lang_output_section_statement_type *)NULL) {
132     einfo("%F%P: %s uses undefined section %s\n", op, name);
133   }
134   if (os->processed == false) {
135     einfo("%F%P: %s forward reference of section %s\n",op, name);
136   }
137 }
138
139 etree_type *
140 exp_intop (value)
141      bfd_vma value;
142 {
143   etree_type *new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->value)));
144   new->type.node_code = INT;
145   new->value.value = value;
146   new->type.node_class = etree_value;
147   return new;
148
149 }
150
151
152 static etree_value_type
153 new_rel (value, section)
154      bfd_vma value;
155      lang_output_section_statement_type *section;
156 {
157   etree_value_type new;
158   new.valid = true;
159   new.value = value;
160   new.section = section;
161   return new;
162 }
163
164 static etree_value_type
165 new_rel_from_section (value, section)
166      bfd_vma value;
167      lang_output_section_statement_type *section;
168 {
169   etree_value_type new;
170   new.valid = true;
171   new.value = value;
172   new.section = section;
173
174     new.value -= section->bfd_section->vma;
175
176   return new;
177 }
178
179 static etree_value_type 
180 fold_binary (tree, current_section, allocation_done, dot, dotp)
181      etree_type *tree;
182      lang_output_section_statement_type *current_section;
183      lang_phase_type  allocation_done;
184      bfd_vma dot;
185      bfd_vma *dotp;
186 {
187   etree_value_type result;
188
189   result =  exp_fold_tree(tree->binary.lhs,  current_section,
190                           allocation_done, dot, dotp);
191   if (result.valid) {
192     etree_value_type other;
193     other = exp_fold_tree(tree->binary.rhs,
194                           current_section,
195                           allocation_done, dot,dotp) ;
196     if (other.valid) {
197         /* If values are from different sections, or this is an */
198         /* absolute expression, make both source args absolute */
199       if (result.section !=  other.section ||
200           current_section == abs_output_section) 
201       {
202         make_abs(&result);
203         make_abs(&other);
204       }
205           
206       switch (tree->type.node_code) 
207         {
208         case '%':
209           /* Mod,  both absolule*/
210
211           if (other.value == 0) {
212             einfo("%F%S %% by zero\n");
213           }
214           result.value = (int)result.value % (int)other.value;
215           break;
216         case '/':
217           if (other.value == 0) {
218             einfo("%F%S / by zero\n");
219           }
220           result.value = (int)result.value / (int) other.value;
221           break;
222 #define BOP(x,y) case x : result.value = result.value y other.value;break;
223           BOP('+',+);
224           BOP('*',*);
225           BOP('-',-);
226           BOP(LSHIFT,<<);
227           BOP(RSHIFT,>>);
228           BOP(EQ,==);
229           BOP(NE,!=);
230           BOP('<',<);
231           BOP('>',>);
232           BOP(LE,<=);
233           BOP(GE,>=);
234           BOP('&',&);
235           BOP('^',^);
236           BOP('|',|);
237           BOP(ANDAND,&&);
238           BOP(OROR,||);
239         default:
240           FAIL();
241         }
242     }
243     else {
244       result.valid = false;
245     }
246   }
247   return result;
248 }
249 etree_value_type 
250 invalid ()
251 {
252   etree_value_type new;
253   new.valid = false;
254   return new;
255 }
256
257 etree_value_type 
258 fold_name (tree, current_section, allocation_done, dot)
259      etree_type *tree;
260      lang_output_section_statement_type *current_section;
261      lang_phase_type  allocation_done;
262      bfd_vma dot;
263 {
264   etree_value_type result;
265   switch (tree->type.node_code) 
266       {
267       case SIZEOF_HEADERS:
268         if (allocation_done != lang_first_phase_enum) 
269             {
270               result = new_abs(bfd_sizeof_headers(output_bfd,
271                                                 config.relocateable_output));
272
273             }
274         else {
275           result.valid = false;
276         }
277         break;
278       case DEFINED:
279         result.value =
280           ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
281         result.section = 0;
282         result.valid = true;
283         break;
284       case NAME:
285         result.valid = false;
286         if (tree->name.name[0] == '.' && tree->name.name[1] == 0) {
287
288           if (allocation_done != lang_first_phase_enum) {
289             result = new_rel_from_section(dot, current_section);
290           }
291           else {
292             result = invalid();
293           }
294         }
295         else {
296           if (allocation_done == lang_final_phase_enum) {
297             ldsym_type *sy = ldsym_get_soft(tree->name.name);
298           
299             if (sy) {
300               asymbol **sdefp = sy->sdefs_chain;
301
302               if (sdefp) {
303                 asymbol *sdef = *sdefp;
304 #if 0
305                 if (sdef->section == (asection *)NULL) {
306                   /* This is an absolute symbol */
307                   result = new_abs(sdef->value);
308                 }
309                 else
310 #endif
311  {
312                   lang_output_section_statement_type *os =
313                     lang_output_section_statement_lookup(
314                                                          sdef->section->output_section->name);
315                   /* If the symbol is from a file which we are not
316                      relocating (-R) then return an absolute for its
317                      value */
318                   if (bfd_asymbol_bfd(sdef)->usrdata && 
319                       ((lang_input_statement_type*)(bfd_asymbol_bfd(sdef)->usrdata))->just_syms_flag == true) 
320                       {
321                         result = new_abs(sdef->value +sdef->section->vma);
322
323                       }
324                   else {
325                     result = new_rel(sdef->value + sdef->section->output_offset, os);
326                   }
327                 }
328               }
329             }
330             if (result.valid == false) {
331               einfo("%F%S: undefined symbol `%s' referenced in expression\n",
332                    tree->name.name);
333             }
334
335           }
336         }
337
338         break;
339
340       case ADDR:
341
342         if (allocation_done != lang_first_phase_enum) {
343           lang_output_section_statement_type *os =
344             lang_output_section_find(tree->name.name);
345           check(os,tree->name.name,"ADDR");
346           result =    new_rel((bfd_vma)0,  os);
347         }
348         else {
349           result = invalid();
350         }
351         break;
352       case SIZEOF:
353         if(allocation_done != lang_first_phase_enum) {
354           lang_output_section_statement_type *os = 
355             lang_output_section_find(tree->name.name);
356           check(os,tree->name.name,"SIZEOF");
357           result = new_abs((bfd_vma)(os->bfd_section->_raw_size));
358         }
359         else {
360           result = invalid();
361         }
362         break;
363
364       default:
365         FAIL();
366         break;
367       }
368
369   return result;
370 }
371 etree_value_type 
372 exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
373      etree_type *tree;
374      lang_output_section_statement_type *current_section;
375      lang_phase_type  allocation_done;
376      bfd_vma dot;
377      bfd_vma *dotp;
378 {
379   etree_value_type result;
380
381   if (tree == (etree_type *)NULL) {
382     result.valid = false;
383   }
384   else {
385     switch (tree->type.node_class) 
386     {
387      case etree_value:
388       result = new_rel(tree->value.value, current_section);
389       break;
390      case etree_unary:
391       result = exp_fold_tree(tree->unary.child,
392                              current_section,
393                              allocation_done, dot, dotp);
394       if (result.valid == true)
395       {
396         switch(tree->type.node_code) 
397         {
398          case ALIGN_K:
399           if (allocation_done != lang_first_phase_enum) {
400             result = new_rel_from_section(ALIGN_N(dot,
401                                                 result.value) ,
402                                           current_section);
403
404           }
405           else {
406             result.valid = false;
407           }
408           break;
409          case ABSOLUTE:
410           if (allocation_done != lang_first_phase_enum) 
411           {
412             if (current_section 
413                 == (lang_output_section_statement_type*)NULL) 
414             {
415               /* Outside a section, so it's all ok */
416
417             }
418             else {
419               /* Inside a section, subtract the base of the section,
420                  so when it's added again (in an assignment), everything comes out fine
421                  */
422               result.section = abs_output_section;
423               result.value -= current_section->bfd_section->vma;
424               result.valid = true;
425             }
426           }
427           else 
428           {
429             result.valid = false;
430           }
431
432           break;
433          case '~':
434           make_abs(&result);
435           result.value = ~result.value;
436           break;
437          case '!':
438           make_abs(&result);
439           result.value = !result.value;
440           break;
441          case '-':
442           make_abs(&result);
443           result.value = -result.value;
444           break;
445          case NEXT:
446           if (allocation_done ==lang_allocating_phase_enum) {
447             make_abs(&result);
448             result.value = ALIGN_N(dot, result.value);
449           }
450           else {
451             /* Return next place aligned to value */
452             result.valid = false;
453           }
454           break;
455          default:
456           FAIL();
457         }
458       }
459
460       break;
461      case etree_trinary:
462
463       result = exp_fold_tree(tree->trinary.cond,
464                              current_section,
465                              allocation_done, dot, dotp);
466       if (result.valid) {
467         result = exp_fold_tree(result.value ?
468                                tree->trinary.lhs:tree->trinary.rhs,
469                                current_section,
470                                allocation_done, dot, dotp);
471       }
472
473       break;
474      case etree_binary:
475       result = fold_binary(tree, current_section, allocation_done,
476                            dot, dotp);
477       break;
478      case etree_assign:
479       if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
480         /* Assignment to dot can only be done during allocation */
481         if (allocation_done == lang_allocating_phase_enum) {
482           result = exp_fold_tree(tree->assign.src,
483                                  current_section,
484                                  lang_allocating_phase_enum, dot, dotp);
485           if (result.valid == false) {
486             einfo("%F%S invalid assignment to location counter\n");
487           }
488           else {
489             if (current_section ==
490                 (lang_output_section_statement_type  *)NULL) {
491               einfo("%F%S assignment to location counter invalid outside of SECTION\n");
492             }
493             else {
494               bfd_vma nextdot =result.value +
495                current_section->bfd_section->vma;
496               if (nextdot < dot) {
497                 einfo("%F%S cannot move location counter backwards (from %V to %V)\n", dot, nextdot);
498               }
499               else {
500                 *dotp = nextdot; 
501               }
502             }
503           }
504         }
505       }
506       else {
507         ldsym_type *sy = ldsym_get(tree->assign.dst);
508
509         /* If this symbol has just been created then we'll place it into 
510          * a section of our choice
511          */
512         result = exp_fold_tree(tree->assign.src,
513                                current_section, allocation_done,
514                                dot, dotp);
515         if (result.valid)
516         {
517           asymbol *def;
518           asymbol **def_ptr ;
519           /* Add this definition to script file */
520           if (sy->sdefs_chain) 
521           {
522             def_ptr = sy->sdefs_chain;
523             def = *def_ptr;
524                     
525           }
526           else 
527           {
528             def_ptr = (asymbol **)stat_alloc((bfd_size_type)(sizeof(asymbol **)));
529             def = (asymbol   *)bfd_make_empty_symbol(script_file->the_bfd);
530
531                   
532             def->flags = 0;
533                 
534             sy->sdefs_chain = def_ptr;
535             *def_ptr = def;
536           }
537
538           def->value = result.value;
539
540           def->section = result.section->bfd_section;
541           def->flags |= BSF_GLOBAL | BSF_EXPORT;
542
543
544           def->udata = (PTR)NULL;
545           def->name = sy->name;
546
547           if (sy->sdefs_chain == 0)
548            enter_global_ref(def_ptr, sy->name);
549         }
550
551       }
552
553   
554       break;
555      case etree_name:
556       result = fold_name(tree, current_section, allocation_done, dot);
557       break;
558      default:
559       einfo("%F%S need more of these %d\n",tree->type.node_class );
560
561     }
562   }
563
564   return result;
565 }
566
567
568 etree_value_type 
569 exp_fold_tree_no_dot (tree, current_section, allocation_done)
570      etree_type *tree;
571      lang_output_section_statement_type *current_section;
572      lang_phase_type allocation_done;
573 {
574 return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
575                      0, (bfd_vma *)NULL);
576 }
577
578 etree_type *
579 exp_binop (code, lhs, rhs)
580      int code;
581      etree_type *lhs;
582      etree_type *rhs;
583 {
584   etree_type value, *new;
585   etree_value_type r;
586
587   value.type.node_code = code;
588   value.binary.lhs = lhs;
589   value.binary.rhs = rhs;
590   value.type.node_class = etree_binary;
591   r = exp_fold_tree_no_dot(&value,
592                            abs_output_section,
593                            lang_first_phase_enum );
594   if (r.valid)
595     {
596       return exp_intop(r.value);
597     }
598   new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->binary)));
599   memcpy((char *)new, (char *)&value, sizeof(new->binary));
600   return new;
601 }
602
603 etree_type *
604 exp_trinop (code, cond, lhs, rhs)
605      int code;
606      etree_type *cond;
607      etree_type *lhs;
608      etree_type *rhs;
609 {
610   etree_type value, *new;
611   etree_value_type r;
612   value.type.node_code = code;
613   value.trinary.lhs = lhs;
614   value.trinary.cond = cond;
615   value.trinary.rhs = rhs;
616   value.type.node_class = etree_trinary;
617   r= exp_fold_tree_no_dot(&value,  (lang_output_section_statement_type
618                                     *)NULL,lang_first_phase_enum);
619   if (r.valid) {
620     return exp_intop(r.value);
621   }
622   new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->trinary)));
623   memcpy((char *)new,(char *) &value, sizeof(new->trinary));
624   return new;
625 }
626
627
628 etree_type *
629 exp_unop (code, child)
630      int code;
631      etree_type *child;
632 {
633   etree_type value, *new;
634
635   etree_value_type r;
636   value.unary.type.node_code = code;
637   value.unary.child = child;
638   value.unary.type.node_class = etree_unary;
639   r = exp_fold_tree_no_dot(&value,abs_output_section,
640                            lang_first_phase_enum);
641   if (r.valid) {
642     return exp_intop(r.value);
643   }
644   new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->unary)));
645   memcpy((char *)new, (char *)&value, sizeof(new->unary));
646   return new;
647 }
648
649
650 etree_type *
651 exp_nameop (code, name)
652      int code;
653      CONST char *name;
654 {
655   etree_type value, *new;
656   etree_value_type r;
657   value.name.type.node_code = code;
658   value.name.name = name;
659   value.name.type.node_class = etree_name;
660
661
662   r = exp_fold_tree_no_dot(&value,
663                            (lang_output_section_statement_type *)NULL,
664                            lang_first_phase_enum);
665   if (r.valid) {
666     return exp_intop(r.value);
667   }
668   new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->name)));
669   memcpy((char *)new, (char *)&value, sizeof(new->name));
670   return new;
671
672 }
673
674
675
676
677 etree_type *
678 exp_assop (code, dst, src)
679      int code;
680      CONST char *dst;
681      etree_type *src;
682 {
683   etree_type value, *new;
684
685   value.assign.type.node_code = code;
686
687
688   value.assign.src = src;
689   value.assign.dst = dst;
690   value.assign.type.node_class = etree_assign;
691
692 #if 0
693   if (exp_fold_tree_no_dot(&value, &result)) {
694     return exp_intop(result);
695   }
696 #endif
697   new = (etree_type*)stat_alloc((bfd_size_type)(sizeof(new->assign)));
698   memcpy((char *)new, (char *)&value, sizeof(new->assign));
699   return new;
700 }
701
702 void 
703 exp_print_tree (tree)
704      etree_type *tree;
705 {
706   switch (tree->type.node_class) {
707   case etree_value:
708     print_address(tree->value.value);
709     return;
710
711   case etree_assign:
712 #if 0
713     if (tree->assign.dst->sdefs != (asymbol *)NULL){
714       fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
715               tree->assign.dst->sdefs->value);
716     }
717     else {
718       fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
719     }
720 #endif
721     fprintf(config.map_file,"%s ",tree->assign.dst);
722     exp_print_token(tree->type.node_code);
723     exp_print_tree(tree->assign.src);
724     break;
725   case etree_binary:
726     fprintf(config.map_file,"(");
727     exp_print_tree(tree->binary.lhs);
728     exp_print_token(tree->type.node_code);
729     exp_print_tree(tree->binary.rhs);
730     fprintf(config.map_file,")");
731     break;
732   case etree_trinary:
733     exp_print_tree(tree->trinary.cond);
734     fprintf(config.map_file,"?");
735     exp_print_tree(tree->trinary.lhs);
736     fprintf(config.map_file,":");
737     exp_print_tree(tree->trinary.rhs);
738     break;
739   case etree_unary:
740     exp_print_token(tree->unary.type.node_code);
741     if (tree->unary.child) 
742     {
743       
744     fprintf(config.map_file,"(");
745     exp_print_tree(tree->unary.child);
746     fprintf(config.map_file,")");
747   }
748     
749     break;
750   case etree_undef:
751     fprintf(config.map_file,"????????");
752     break;
753   case etree_name:
754     if (tree->type.node_code == NAME) {
755       fprintf(config.map_file,"%s", tree->name.name);
756     }
757     else {
758       exp_print_token(tree->type.node_code);
759       if (tree->name.name)
760       fprintf(config.map_file,"(%s)", tree->name.name);
761     }
762     break;
763   default:
764     FAIL();
765     break;
766   }
767 }
768
769
770
771
772 bfd_vma
773 exp_get_vma (tree, def, name, allocation_done)
774      etree_type *tree;
775       bfd_vma def;
776      char *name;
777      lang_phase_type allocation_done;
778 {
779   etree_value_type r;
780
781   if (tree != (etree_type *)NULL) {
782     r = exp_fold_tree_no_dot(tree,
783                  abs_output_section,
784                       allocation_done);
785     if (r.valid == false && name) {
786       einfo("%F%S nonconstant expression for %s\n",name);
787     }
788     return r.value;
789   }
790   else {
791     return def;
792   }
793 }
794
795 int 
796 exp_get_value_int (tree,def,name, allocation_done)
797      etree_type *tree;
798      int def;
799      char *name;
800      lang_phase_type allocation_done;
801 {
802   return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
803 }
804