New file used for rebuilding dependencies.
[deliverable/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 "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
This page took 0.047594 seconds and 4 git commands to generate.