1 /* This module handles expression trees.
2 Copyright (C) 1991, 1993, 1994, 1995 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 static void exp_print_token
PARAMS ((token_code_type code
));
43 static void make_abs
PARAMS ((etree_value_type
*ptr
));
44 static etree_value_type new_abs
PARAMS ((bfd_vma value
));
45 static void check
PARAMS ((lang_output_section_statement_type
*os
,
46 const char *name
, const char *op
));
47 static etree_value_type new_rel
48 PARAMS ((bfd_vma value
, lang_output_section_statement_type
*section
));
49 static etree_value_type new_rel_from_section
50 PARAMS ((bfd_vma value
, lang_output_section_statement_type
*section
));
51 static etree_value_type fold_binary
52 PARAMS ((etree_type
*tree
,
53 lang_output_section_statement_type
*current_section
,
54 lang_phase_type allocation_done
,
55 bfd_vma dot
, bfd_vma
*dotp
));
56 static etree_value_type fold_name
57 PARAMS ((etree_type
*tree
,
58 lang_output_section_statement_type
*current_section
,
59 lang_phase_type allocation_done
,
61 static etree_value_type exp_fold_tree_no_dot
62 PARAMS ((etree_type
*tree
,
63 lang_output_section_statement_type
*current_section
,
64 lang_phase_type allocation_done
));
67 exp_print_token (code
)
77 { REL
, "relocateable" },
97 { SECTIONS
,"SECTIONS" },
98 { SIZEOF_HEADERS
,"SIZEOF_HEADERS" },
103 { DEFINED
,"DEFINED" },
104 { TARGET_K
,"TARGET" },
105 { SEARCH_DIR
,"SEARCH_DIR" },
116 for (idx
= 0; table
[idx
].name
!= (char*)NULL
; idx
++) {
117 if (table
[idx
].code
== code
) {
118 fprintf(config
.map_file
, "%s", table
[idx
].name
);
122 /* Not in table, just print it alone */
123 fprintf(config
.map_file
, "%c",code
);
128 etree_value_type
*ptr
;
130 asection
*s
= ptr
->section
->bfd_section
;
131 ptr
->value
+= s
->vma
;
132 ptr
->section
= abs_output_section
;
135 static etree_value_type
139 etree_value_type
new;
141 new.section
= abs_output_section
;
148 lang_output_section_statement_type
*os
;
152 if (os
== (lang_output_section_statement_type
*)NULL
) {
153 einfo("%F%P: %s uses undefined section %s\n", op
, name
);
155 if (os
->processed
== false) {
156 einfo("%F%P: %s forward reference of section %s\n",op
, name
);
164 etree_type
*new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->value
)));
165 new->type
.node_code
= INT
;
166 new->value
.value
= value
;
167 new->type
.node_class
= etree_value
;
172 /* Build an expression representing an unnamed relocateable value. */
175 exp_relop (section
, value
)
179 etree_type
*new = (etree_type
*) stat_alloc (sizeof (new->rel
));
180 new->type
.node_code
= REL
;
181 new->type
.node_class
= etree_rel
;
182 new->rel
.section
= section
;
183 new->rel
.value
= value
;
187 static etree_value_type
188 new_rel (value
, section
)
190 lang_output_section_statement_type
*section
;
192 etree_value_type
new;
195 new.section
= section
;
199 static etree_value_type
200 new_rel_from_section (value
, section
)
202 lang_output_section_statement_type
*section
;
204 etree_value_type
new;
207 new.section
= section
;
209 new.value
-= section
->bfd_section
->vma
;
214 static etree_value_type
215 fold_binary (tree
, current_section
, allocation_done
, dot
, dotp
)
217 lang_output_section_statement_type
*current_section
;
218 lang_phase_type allocation_done
;
222 etree_value_type result
;
224 result
= exp_fold_tree (tree
->binary
.lhs
, current_section
,
225 allocation_done
, dot
, dotp
);
228 etree_value_type other
;
230 other
= exp_fold_tree (tree
->binary
.rhs
,
232 allocation_done
, dot
,dotp
) ;
235 /* If the values are from different sections, or this is an
236 absolute expression, make both the source arguments
237 absolute. However, adding or subtracting an absolute
238 value from a relative value is meaningful, and is an
240 if (current_section
!= abs_output_section
241 && (result
.section
== abs_output_section
242 || other
.section
== abs_output_section
)
243 && (tree
->type
.node_code
== '+'
244 || tree
->type
.node_code
== '-'))
246 etree_value_type hold
;
248 /* If there is only one absolute term, make sure it is the
250 if (result
.section
== abs_output_section
)
257 else if (result
.section
!= other
.section
258 || current_section
== abs_output_section
)
264 switch (tree
->type
.node_code
)
267 if (other
.value
== 0)
268 einfo ("%F%S %% by zero\n");
269 result
.value
= ((bfd_signed_vma
) result
.value
270 % (bfd_signed_vma
) other
.value
);
274 if (other
.value
== 0)
275 einfo ("%F%S / by zero\n");
276 result
.value
= ((bfd_signed_vma
) result
.value
277 / (bfd_signed_vma
) other
.value
);
280 #define BOP(x,y) case x : result.value = result.value y other.value; break;
304 result
.valid
= false;
314 etree_value_type
new;
319 static etree_value_type
320 fold_name (tree
, current_section
, allocation_done
, dot
)
322 lang_output_section_statement_type
*current_section
;
323 lang_phase_type allocation_done
;
326 etree_value_type result
;
327 switch (tree
->type
.node_code
)
330 if (allocation_done
!= lang_first_phase_enum
)
332 result
= new_abs ((bfd_vma
)
333 bfd_sizeof_headers (output_bfd
,
334 link_info
.relocateable
));
338 result
.valid
= false;
342 if (allocation_done
== lang_first_phase_enum
)
343 result
.valid
= false;
346 struct bfd_link_hash_entry
*h
;
348 h
= bfd_link_hash_lookup (link_info
.hash
, tree
->name
.name
,
350 result
.value
= (h
!= (struct bfd_link_hash_entry
*) NULL
351 && (h
->type
== bfd_link_hash_defined
352 || h
->type
== bfd_link_hash_common
));
358 result
.valid
= false;
359 if (tree
->name
.name
[0] == '.' && tree
->name
.name
[1] == 0)
361 if (allocation_done
!= lang_first_phase_enum
)
362 result
= new_rel_from_section(dot
, current_section
);
366 else if (allocation_done
!= lang_first_phase_enum
)
368 struct bfd_link_hash_entry
*h
;
370 h
= bfd_link_hash_lookup (link_info
.hash
, tree
->name
.name
,
372 if (h
!= NULL
&& h
->type
== bfd_link_hash_defined
)
374 if (bfd_is_abs_section (h
->u
.def
.section
))
375 result
= new_abs (h
->u
.def
.value
);
376 else if (allocation_done
== lang_final_phase_enum
)
378 lang_output_section_statement_type
*os
;
380 os
= (lang_output_section_statement_lookup
381 (h
->u
.def
.section
->output_section
->name
));
383 /* FIXME: Is this correct if this section is being
385 result
= new_rel ((h
->u
.def
.value
386 + h
->u
.def
.section
->output_offset
),
390 else if (allocation_done
== lang_final_phase_enum
)
391 einfo ("%F%S: undefined symbol `%s' referenced in expression\n",
398 if (allocation_done
!= lang_first_phase_enum
) {
399 lang_output_section_statement_type
*os
=
400 lang_output_section_find(tree
->name
.name
);
401 check(os
,tree
->name
.name
,"ADDR");
402 result
= new_rel((bfd_vma
)0, os
);
409 if(allocation_done
!= lang_first_phase_enum
) {
410 lang_output_section_statement_type
*os
=
411 lang_output_section_find(tree
->name
.name
);
412 check(os
,tree
->name
.name
,"SIZEOF");
413 result
= new_abs((bfd_vma
)(os
->bfd_section
->_raw_size
));
428 exp_fold_tree (tree
, current_section
, allocation_done
, dot
, dotp
)
430 lang_output_section_statement_type
*current_section
;
431 lang_phase_type allocation_done
;
435 etree_value_type result
;
437 if (tree
== (etree_type
*)NULL
) {
438 result
.valid
= false;
441 switch (tree
->type
.node_class
)
444 result
= new_rel(tree
->value
.value
, current_section
);
447 if (allocation_done
!= lang_final_phase_enum
)
448 result
.valid
= false;
450 result
= new_rel ((tree
->rel
.value
451 + tree
->rel
.section
->output_section
->vma
452 + tree
->rel
.section
->output_offset
),
456 result
= exp_fold_tree(tree
->unary
.child
,
458 allocation_done
, dot
, dotp
);
459 if (result
.valid
== true)
461 switch(tree
->type
.node_code
)
464 if (allocation_done
!= lang_first_phase_enum
) {
465 result
= new_rel_from_section(ALIGN_N(dot
,
471 result
.valid
= false;
475 if (allocation_done
!= lang_first_phase_enum
)
478 == (lang_output_section_statement_type
*)NULL
)
480 /* Outside a section, so it's all ok */
484 /* Inside a section, subtract the base of the section,
485 so when it's added again (in an assignment), everything comes out fine
487 result
.section
= abs_output_section
;
488 result
.value
-= current_section
->bfd_section
->vma
;
494 result
.valid
= false;
500 result
.value
= ~result
.value
;
504 result
.value
= !result
.value
;
508 result
.value
= -result
.value
;
511 if (allocation_done
==lang_allocating_phase_enum
) {
513 result
.value
= ALIGN_N(dot
, result
.value
);
516 /* Return next place aligned to value */
517 result
.valid
= false;
528 result
= exp_fold_tree(tree
->trinary
.cond
,
530 allocation_done
, dot
, dotp
);
532 result
= exp_fold_tree(result
.value
?
533 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
535 allocation_done
, dot
, dotp
);
540 result
= fold_binary(tree
, current_section
, allocation_done
,
545 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
546 /* Assignment to dot can only be done during allocation */
547 if (tree
->type
.node_class
== etree_provide
)
548 einfo ("%F%S can not PROVIDE assignment to location counter\n");
549 if (allocation_done
== lang_allocating_phase_enum
) {
550 result
= exp_fold_tree(tree
->assign
.src
,
552 lang_allocating_phase_enum
, dot
, dotp
);
553 if (result
.valid
== false) {
554 einfo("%F%S invalid assignment to location counter\n");
557 if (current_section
==
558 (lang_output_section_statement_type
*)NULL
) {
559 einfo("%F%S assignment to location counter invalid outside of SECTION\n");
562 bfd_vma nextdot
=result
.value
+
563 current_section
->bfd_section
->vma
;
565 einfo("%F%S cannot move location counter backwards (from %V to %V)\n", dot
, nextdot
);
576 result
= exp_fold_tree (tree
->assign
.src
,
577 current_section
, allocation_done
,
581 struct bfd_link_hash_entry
*h
;
583 h
= bfd_link_hash_lookup (link_info
.hash
, tree
->assign
.dst
,
584 (tree
->type
.node_class
== etree_assign
587 if (h
== (struct bfd_link_hash_entry
*) NULL
)
589 if (tree
->type
.node_class
== etree_assign
)
590 einfo ("%P%F:%s: hash creation failed\n",
593 else if (tree
->type
.node_class
== etree_provide
594 && h
->type
!= bfd_link_hash_undefined
595 && h
->type
!= bfd_link_hash_common
)
597 /* Do nothing. The symbol was defined by some
602 /* FIXME: Should we worry if the symbol is already
604 h
->type
= bfd_link_hash_defined
;
605 h
->u
.def
.value
= result
.value
;
606 h
->u
.def
.section
= result
.section
->bfd_section
;
612 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
615 einfo("%F%S need more of these %d\n",tree
->type
.node_class
);
624 static etree_value_type
625 exp_fold_tree_no_dot (tree
, current_section
, allocation_done
)
627 lang_output_section_statement_type
*current_section
;
628 lang_phase_type allocation_done
;
630 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
635 exp_binop (code
, lhs
, rhs
)
640 etree_type value
, *new;
643 value
.type
.node_code
= code
;
644 value
.binary
.lhs
= lhs
;
645 value
.binary
.rhs
= rhs
;
646 value
.type
.node_class
= etree_binary
;
647 r
= exp_fold_tree_no_dot(&value
,
649 lang_first_phase_enum
);
652 return exp_intop(r
.value
);
654 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->binary
)));
655 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
660 exp_trinop (code
, cond
, lhs
, rhs
)
666 etree_type value
, *new;
668 value
.type
.node_code
= code
;
669 value
.trinary
.lhs
= lhs
;
670 value
.trinary
.cond
= cond
;
671 value
.trinary
.rhs
= rhs
;
672 value
.type
.node_class
= etree_trinary
;
673 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
674 *)NULL
,lang_first_phase_enum
);
676 return exp_intop(r
.value
);
678 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->trinary
)));
679 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
685 exp_unop (code
, child
)
689 etree_type value
, *new;
692 value
.unary
.type
.node_code
= code
;
693 value
.unary
.child
= child
;
694 value
.unary
.type
.node_class
= etree_unary
;
695 r
= exp_fold_tree_no_dot(&value
,abs_output_section
,
696 lang_first_phase_enum
);
698 return exp_intop(r
.value
);
700 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->unary
)));
701 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
707 exp_nameop (code
, name
)
711 etree_type value
, *new;
713 value
.name
.type
.node_code
= code
;
714 value
.name
.name
= name
;
715 value
.name
.type
.node_class
= etree_name
;
718 r
= exp_fold_tree_no_dot(&value
,
719 (lang_output_section_statement_type
*)NULL
,
720 lang_first_phase_enum
);
722 return exp_intop(r
.value
);
724 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->name
)));
725 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
734 exp_assop (code
, dst
, src
)
739 etree_type value
, *new;
741 value
.assign
.type
.node_code
= code
;
744 value
.assign
.src
= src
;
745 value
.assign
.dst
= dst
;
746 value
.assign
.type
.node_class
= etree_assign
;
749 if (exp_fold_tree_no_dot(&value
, &result
)) {
750 return exp_intop(result
);
753 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->assign
)));
754 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
758 /* Handle PROVIDE. */
761 exp_provide (dst
, src
)
767 n
= (etree_type
*) stat_alloc (sizeof (n
->assign
));
768 n
->assign
.type
.node_code
= '=';
769 n
->assign
.type
.node_class
= etree_provide
;
776 exp_print_tree (tree
)
779 switch (tree
->type
.node_class
) {
781 print_address(tree
->value
.value
);
784 if (tree
->rel
.section
->owner
!= NULL
)
785 fprintf (config
.map_file
, "%s:",
786 bfd_get_filename (tree
->rel
.section
->owner
));
787 fprintf (config
.map_file
, "%s+", tree
->rel
.section
->name
);
788 print_address (tree
->rel
.value
);
792 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
793 fprintf(config
.map_file
,"%s (%x) ",tree
->assign
.dst
->name
,
794 tree
->assign
.dst
->sdefs
->value
);
797 fprintf(config
.map_file
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
800 fprintf(config
.map_file
,"%s ",tree
->assign
.dst
);
801 exp_print_token(tree
->type
.node_code
);
802 exp_print_tree(tree
->assign
.src
);
805 fprintf (config
.map_file
, "PROVIDE (%s, ", tree
->assign
.dst
);
806 exp_print_tree (tree
->assign
.src
);
807 fprintf (config
.map_file
, ")");
810 fprintf(config
.map_file
,"(");
811 exp_print_tree(tree
->binary
.lhs
);
812 exp_print_token(tree
->type
.node_code
);
813 exp_print_tree(tree
->binary
.rhs
);
814 fprintf(config
.map_file
,")");
817 exp_print_tree(tree
->trinary
.cond
);
818 fprintf(config
.map_file
,"?");
819 exp_print_tree(tree
->trinary
.lhs
);
820 fprintf(config
.map_file
,":");
821 exp_print_tree(tree
->trinary
.rhs
);
824 exp_print_token(tree
->unary
.type
.node_code
);
825 if (tree
->unary
.child
)
828 fprintf(config
.map_file
,"(");
829 exp_print_tree(tree
->unary
.child
);
830 fprintf(config
.map_file
,")");
835 fprintf(config
.map_file
,"????????");
838 if (tree
->type
.node_code
== NAME
) {
839 fprintf(config
.map_file
,"%s", tree
->name
.name
);
842 exp_print_token(tree
->type
.node_code
);
844 fprintf(config
.map_file
,"(%s)", tree
->name
.name
);
857 exp_get_vma (tree
, def
, name
, allocation_done
)
861 lang_phase_type allocation_done
;
865 if (tree
!= (etree_type
*)NULL
) {
866 r
= exp_fold_tree_no_dot(tree
,
869 if (r
.valid
== false && name
) {
870 einfo("%F%S nonconstant expression for %s\n",name
);
880 exp_get_value_int (tree
,def
,name
, allocation_done
)
884 lang_phase_type allocation_done
;
886 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);
891 exp_get_abs_int (tree
, def
, name
, allocation_done
)
895 lang_phase_type allocation_done
;
897 etree_value_type res
;
898 res
= exp_fold_tree_no_dot (tree
, abs_output_section
, allocation_done
);
902 res
.value
+= res
.section
->bfd_section
->vma
;
905 einfo ("%F%S non constant expression for %s\n",name
);