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).
5 This file is part of GLD, the Gnu Linker.
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)
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.
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. */
22 This module is in charge of working out the contents of expressions.
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.
42 extern char *output_filename
;
43 extern unsigned int undefined_global_sym_count
;
44 extern unsigned int defined_global_sym_count
;
45 extern bfd
*output_bfd
;
46 extern bfd_size_type largest_section
;
47 extern lang_statement_list_type file_chain
;
48 extern args_type command_line
;
49 extern ld_config_type config
;
51 extern lang_input_statement_type
*script_file
;
52 extern unsigned int defined_global_sym_count
;
54 extern bfd_vma print_dot
;
58 DEFUN(exp_print_token
,( code
),
87 SIZEOF_HEADERS
,"SIZEOF_HEADERS",
99 SEARCH_DIR
,"SEARCH_DIR",
110 for (idx
= 0; table
[idx
].name
!= (char*)NULL
; idx
++) {
111 if (table
[idx
].code
== code
) {
112 fprintf(config
.map_file
, "%s", table
[idx
].name
);
116 /* Not in table, just print it alone */
117 fprintf(config
.map_file
, "%c",code
);
121 DEFUN(make_abs
,(ptr
),
122 etree_value_type
*ptr
)
124 if (ptr
->section
!= (lang_output_section_statement_type
*)NULL
) {
125 asection
*s
= ptr
->section
->bfd_section
;
126 ptr
->value
+= s
->vma
;
127 ptr
->section
= (lang_output_section_statement_type
*)NULL
;
133 DEFUN(etree_value_type new_abs
,(value
),
136 etree_value_type
new;
138 new.section
= (lang_output_section_statement_type
*)NULL
;
144 DEFUN(check
, (os
, name
, op
),
145 lang_output_section_statement_type
*os AND
149 if (os
== (lang_output_section_statement_type
*)NULL
) {
150 einfo("%F%P %s uses undefined section %s\n", op
, name
);
152 if (os
->processed
== false) {
153 einfo("%F%P %s forward reference of section %s\n",op
, name
);
158 DEFUN(exp_intop
,(value
),
161 etree_type
*new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->value
)));
162 new->type
.node_code
= INT
;
163 new->value
.value
= value
;
164 new->type
.node_class
= etree_value
;
171 DEFUN(etree_value_type new_rel
,(value
, section
),
173 lang_output_section_statement_type
*section
)
175 etree_value_type
new;
178 new.section
= section
;
183 DEFUN(etree_value_type
184 new_rel_from_section
, (value
, section
),
186 lang_output_section_statement_type
*section
)
188 etree_value_type
new;
191 new.section
= section
;
192 if (new.section
!= (lang_output_section_statement_type
*)NULL
) {
193 new.value
-= section
->bfd_section
->vma
;
198 static etree_value_type
199 DEFUN(fold_binary
,(tree
, current_section
, allocation_done
, dot
, dotp
),
201 lang_output_section_statement_type
*current_section AND
202 lang_phase_type allocation_done AND
206 etree_value_type result
;
208 result
= exp_fold_tree(tree
->binary
.lhs
, current_section
,
209 allocation_done
, dot
, dotp
);
211 etree_value_type other
;
212 other
= exp_fold_tree(tree
->binary
.rhs
,
214 allocation_done
, dot
,dotp
) ;
216 /* If values are from different sections, or this is an */
217 /* absolute expression, make both source args absolute */
218 if (result
.section
!= other
.section
||
219 current_section
== (lang_output_section_statement_type
*)NULL
) {
225 switch (tree
->type
.node_code
)
228 /* Mod, both absolule*/
230 if (other
.value
== 0) {
231 einfo("%F%S % by zero\n");
233 result
.value
%= other
.value
;
236 if (other
.value
== 0) {
237 einfo("%F%S / by zero\n");
239 result
.value
/= other
.value
;
241 #define BOP(x,y) case x : result.value = result.value y other.value;break;
263 result
.valid
= false;
271 etree_value_type
new;
277 DEFUN(fold_name
, (tree
, current_section
, allocation_done
, dot
),
279 lang_output_section_statement_type
*current_section AND
280 lang_phase_type allocation_done AND
283 etree_value_type result
;
284 switch (tree
->type
.node_code
)
287 if (allocation_done
!= lang_first_phase_enum
)
289 result
= new_abs(bfd_sizeof_headers(output_bfd
,
290 config
.relocateable_output
));
294 result
.valid
= false;
299 ldsym_get_soft(tree
->name
.name
) != (ldsym_type
*)NULL
;
304 result
.valid
= false;
305 if (tree
->name
.name
[0] == '.' && tree
->name
.name
[1] == 0) {
307 if (allocation_done
!= lang_first_phase_enum
) {
308 result
= new_rel_from_section(dot
, current_section
);
315 if (allocation_done
== lang_final_phase_enum
) {
316 ldsym_type
*sy
= ldsym_get_soft(tree
->name
.name
);
319 asymbol
**sdefp
= sy
->sdefs_chain
;
322 asymbol
*sdef
= *sdefp
;
323 if (sdef
->section
== (asection
*)NULL
) {
324 /* This is an absolute symbol */
325 result
= new_abs(sdef
->value
);
328 lang_output_section_statement_type
*os
=
329 lang_output_section_statement_lookup(
330 sdef
->section
->output_section
->name
);
331 /* If the symbol is from a file which we are not
332 relocating (-R) then return an absolute for its
334 if (sdef
->the_bfd
->usrdata
&&
335 ((lang_input_statement_type
*)(sdef
->the_bfd
->usrdata
))->just_syms_flag
== true)
337 result
= new_abs(sdef
->value
+ (sdef
->section
?
338 sdef
->section
->vma
: 0));
341 result
= new_rel(sdef
->value
+ sdef
->section
->output_offset
, os
);
346 if (result
.valid
== false) {
347 einfo("%F%S: undefined symbol `%s' referenced in expression.\n",
358 if (allocation_done
!= lang_first_phase_enum
) {
359 lang_output_section_statement_type
*os
=
360 lang_output_section_find(tree
->name
.name
);
361 check(os
,tree
->name
.name
,"ADDR");
362 result
= new_rel((bfd_vma
)0, os
);
369 if(allocation_done
!= lang_first_phase_enum
) {
370 lang_output_section_statement_type
*os
=
371 lang_output_section_find(tree
->name
.name
);
372 check(os
,tree
->name
.name
,"SIZEOF");
373 result
= new_abs((bfd_vma
)(os
->bfd_section
->_raw_size
));
388 DEFUN(exp_fold_tree
,(tree
, current_section
, allocation_done
,
391 lang_output_section_statement_type
*current_section AND
392 lang_phase_type allocation_done AND
396 etree_value_type result
;
398 if (tree
== (etree_type
*)NULL
) {
399 result
.valid
= false;
402 switch (tree
->type
.node_class
)
405 result
= new_rel(tree
->value
.value
, current_section
);
408 result
= exp_fold_tree(tree
->unary
.child
,
410 allocation_done
, dot
, dotp
);
411 if (result
.valid
== true)
413 switch(tree
->type
.node_code
)
416 if (allocation_done
!= lang_first_phase_enum
) {
417 result
= new_rel_from_section(ALIGN(dot
,
423 result
.valid
= false;
428 result
.value
= ~result
.value
;
432 result
.value
= !result
.value
;
436 result
.value
= -result
.value
;
439 if (allocation_done
==lang_allocating_phase_enum
) {
441 result
.value
= ALIGN(dot
, result
.value
);
444 /* Return next place aligned to value */
445 result
.valid
= false;
456 result
= exp_fold_tree(tree
->trinary
.cond
,
458 allocation_done
, dot
, dotp
);
460 result
= exp_fold_tree(result
.value
?
461 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
463 allocation_done
, dot
, dotp
);
468 result
= fold_binary(tree
, current_section
, allocation_done
,
472 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
473 /* Assignment to dot can only be done during allocation */
474 if (allocation_done
== lang_allocating_phase_enum
) {
475 result
= exp_fold_tree(tree
->assign
.src
,
477 lang_allocating_phase_enum
, dot
, dotp
);
478 if (result
.valid
== false) {
479 einfo("%F%S invalid assignment to location counter\n");
482 if (current_section
==
483 (lang_output_section_statement_type
*)NULL
) {
484 einfo("%F%S assignment to location counter invalid outside of SECTION\n");
487 unsigned long nextdot
=result
.value
+
488 current_section
->bfd_section
->vma
;
490 einfo("%F%S cannot move location counter backwards");
500 ldsym_type
*sy
= ldsym_get(tree
->assign
.dst
);
502 /* If this symbol has just been created then we'll place it into
503 * a section of our choice
505 result
= exp_fold_tree(tree
->assign
.src
,
506 current_section
, allocation_done
,
512 /* Add this definition to script file */
515 def_ptr
= sy
->sdefs_chain
;
521 def_ptr
= (asymbol
**)ldmalloc((bfd_size_type
)(sizeof(asymbol
**)));
523 *)bfd_make_empty_symbol(script_file
->the_bfd
);
530 def
->value
= result
.value
;
531 if (result
.section
!=
532 (lang_output_section_statement_type
*)NULL
) {
533 if (current_section
!=
534 (lang_output_section_statement_type
*)NULL
) {
536 def
->section
= result
.section
->bfd_section
;
537 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
540 /* Force to absolute */
541 def
->value
+= result
.section
->bfd_section
->vma
;
542 def
->section
= &bfd_abs_section
;
543 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
549 def
->section
= &bfd_abs_section
;
550 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
554 def
->udata
= (PTR
)NULL
;
555 def
->name
= sy
->name
;
557 if (sy
->sdefs_chain
== 0) Q_enter_global_ref(def_ptr
);
565 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
568 einfo("%F%S Need more of these %d",tree
->type
.node_class
);
578 DEFUN(exp_fold_tree_no_dot
,(tree
, current_section
, allocation_done
),
580 lang_output_section_statement_type
*current_section AND
581 lang_phase_type allocation_done
)
583 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
588 DEFUN(exp_binop
,(code
, lhs
, rhs
),
593 etree_type value
, *new;
596 value
.type
.node_code
= code
;
597 value
.binary
.lhs
= lhs
;
598 value
.binary
.rhs
= rhs
;
599 value
.type
.node_class
= etree_binary
;
600 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
*)NULL
,
601 lang_first_phase_enum
);
604 return exp_intop(r
.value
);
606 new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->binary
)));
607 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
612 DEFUN(exp_trinop
,(code
, cond
, lhs
, rhs
),
618 etree_type value
, *new;
620 value
.type
.node_code
= code
;
621 value
.trinary
.lhs
= lhs
;
622 value
.trinary
.cond
= cond
;
623 value
.trinary
.rhs
= rhs
;
624 value
.type
.node_class
= etree_trinary
;
625 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
626 *)NULL
,lang_first_phase_enum
);
628 return exp_intop(r
.value
);
630 new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->trinary
)));
631 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
637 DEFUN(exp_unop
,(code
, child
),
641 etree_type value
, *new;
644 value
.unary
.type
.node_code
= code
;
645 value
.unary
.child
= child
;
646 value
.unary
.type
.node_class
= etree_unary
;
647 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
648 lang_first_phase_enum
);
650 return exp_intop(r
.value
);
652 new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->unary
)));
653 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
659 DEFUN(exp_nameop
,(code
, name
),
664 etree_type value
, *new;
667 value
.name
.type
.node_code
= code
;
668 value
.name
.name
= name
;
669 value
.name
.type
.node_class
= etree_name
;
672 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
673 lang_first_phase_enum
);
675 return exp_intop(r
.value
);
677 new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->name
)));
678 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
687 DEFUN(exp_assop
,(code
, dst
, src
),
692 etree_type value
, *new;
694 value
.assign
.type
.node_code
= code
;
697 value
.assign
.src
= src
;
698 value
.assign
.dst
= dst
;
699 value
.assign
.type
.node_class
= etree_assign
;
702 if (exp_fold_tree_no_dot(&value
, &result
)) {
703 return exp_intop(result
);
706 new = (etree_type
*)ldmalloc((bfd_size_type
)(sizeof(new->assign
)));
707 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
712 DEFUN(exp_print_tree
,(tree
),
715 switch (tree
->type
.node_class
) {
717 print_address(tree
->value
.value
);
722 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
723 fprintf(config
.map_file
,"%s (%x) ",tree
->assign
.dst
->name
,
724 tree
->assign
.dst
->sdefs
->value
);
727 fprintf(config
.map_file
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
730 fprintf(config
.map_file
,"%s ",tree
->assign
.dst
);
731 exp_print_token(tree
->type
.node_code
);
732 exp_print_tree(tree
->assign
.src
);
735 exp_print_tree(tree
->binary
.lhs
);
736 exp_print_token(tree
->type
.node_code
);
737 exp_print_tree(tree
->binary
.rhs
);
740 exp_print_tree(tree
->trinary
.cond
);
741 fprintf(config
.map_file
,"?");
742 exp_print_tree(tree
->trinary
.lhs
);
743 fprintf(config
.map_file
,":");
744 exp_print_tree(tree
->trinary
.rhs
);
747 exp_print_token(tree
->unary
.type
.node_code
);
748 fprintf(config
.map_file
,"(");
749 exp_print_tree(tree
->unary
.child
);
750 fprintf(config
.map_file
,")");
753 fprintf(config
.map_file
,"????????");
756 if (tree
->type
.node_code
== NAME
) {
757 fprintf(config
.map_file
,"%s", tree
->name
.name
);
760 exp_print_token(tree
->type
.node_code
);
761 fprintf(config
.map_file
,"(%s)", tree
->name
.name
);
774 DEFUN(exp_get_vma
,(tree
, def
, name
, allocation_done
),
778 lang_phase_type allocation_done
)
782 if (tree
!= (etree_type
*)NULL
) {
783 r
= exp_fold_tree_no_dot(tree
,
784 (lang_output_section_statement_type
*)NULL
,
786 if (r
.valid
== false && name
) {
787 einfo("%F%S Nonconstant expression for %s\n",name
);
797 DEFUN(exp_get_value_int
,(tree
,def
,name
, allocation_done
),
801 lang_phase_type allocation_done
)
803 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);