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