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
;
53 extern lang_output_section_statement_type
*abs_output_section
;
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 asection
*s
= ptr
->section
->bfd_section
;
125 ptr
->value
+= s
->vma
;
126 ptr
->section
= abs_output_section
;
130 DEFUN(etree_value_type new_abs
,(value
),
135 etree_value_type
new;
137 new.section
= abs_output_section
;
143 DEFUN(check
, (os
, name
, op
),
144 lang_output_section_statement_type
*os AND
148 if (os
== (lang_output_section_statement_type
*)NULL
) {
149 einfo("%F%P %s uses undefined section %s\n", op
, name
);
151 if (os
->processed
== false) {
152 einfo("%F%P %s forward reference of section %s\n",op
, name
);
157 DEFUN(exp_intop
,(value
),
160 etree_type
*new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->value
)));
161 new->type
.node_code
= INT
;
162 new->value
.value
= value
;
163 new->type
.node_class
= etree_value
;
170 DEFUN(etree_value_type new_rel
,(value
, section
),
172 lang_output_section_statement_type
*section
)
174 etree_value_type
new;
177 new.section
= section
;
182 DEFUN(etree_value_type
183 new_rel_from_section
, (value
, section
),
185 lang_output_section_statement_type
*section
)
187 etree_value_type
new;
190 new.section
= section
;
192 new.value
-= section
->bfd_section
->vma
;
197 static etree_value_type
198 DEFUN(fold_binary
,(tree
, current_section
, allocation_done
, dot
, dotp
),
200 lang_output_section_statement_type
*current_section AND
201 lang_phase_type allocation_done AND
205 etree_value_type result
;
207 result
= exp_fold_tree(tree
->binary
.lhs
, current_section
,
208 allocation_done
, dot
, dotp
);
210 etree_value_type other
;
211 other
= exp_fold_tree(tree
->binary
.rhs
,
213 allocation_done
, dot
,dotp
) ;
215 /* If values are from different sections, or this is an */
216 /* absolute expression, make both source args absolute */
217 if (result
.section
!= other
.section
||
218 current_section
== abs_output_section
)
224 switch (tree
->type
.node_code
)
227 /* Mod, both absolule*/
229 if (other
.value
== 0) {
230 einfo("%F%S % by zero\n");
232 result
.value
= (int)result
.value
% (int)other
.value
;
235 if (other
.value
== 0) {
236 einfo("%F%S / by zero\n");
238 result
.value
= (int)result
.value
/ (int) other
.value
;
240 #define BOP(x,y) case x : result.value = result.value y other.value;break;
262 result
.valid
= false;
270 etree_value_type
new;
276 DEFUN(fold_name
, (tree
, current_section
, allocation_done
, dot
),
278 lang_output_section_statement_type
*current_section AND
279 lang_phase_type allocation_done AND
282 etree_value_type result
;
283 switch (tree
->type
.node_code
)
286 if (allocation_done
!= lang_first_phase_enum
)
288 result
= new_abs(bfd_sizeof_headers(output_bfd
,
289 config
.relocateable_output
));
293 result
.valid
= false;
298 ldsym_get_soft(tree
->name
.name
) != (ldsym_type
*)NULL
;
303 result
.valid
= false;
304 if (tree
->name
.name
[0] == '.' && tree
->name
.name
[1] == 0) {
306 if (allocation_done
!= lang_first_phase_enum
) {
307 result
= new_rel_from_section(dot
, current_section
);
314 if (allocation_done
== lang_final_phase_enum
) {
315 ldsym_type
*sy
= ldsym_get_soft(tree
->name
.name
);
318 asymbol
**sdefp
= sy
->sdefs_chain
;
321 asymbol
*sdef
= *sdefp
;
323 if (sdef
->section
== (asection
*)NULL
) {
324 /* This is an absolute symbol */
325 result
= new_abs(sdef
->value
);
330 lang_output_section_statement_type
*os
=
331 lang_output_section_statement_lookup(
332 sdef
->section
->output_section
->name
);
333 /* If the symbol is from a file which we are not
334 relocating (-R) then return an absolute for its
336 if (sdef
->the_bfd
->usrdata
&&
337 ((lang_input_statement_type
*)(sdef
->the_bfd
->usrdata
))->just_syms_flag
== true)
339 result
= new_abs(sdef
->value
+sdef
->section
->vma
);
343 result
= new_rel(sdef
->value
+ sdef
->section
->output_offset
, os
);
348 if (result
.valid
== false) {
349 einfo("%F%S: undefined symbol `%s' referenced in expression.\n",
360 if (allocation_done
!= lang_first_phase_enum
) {
361 lang_output_section_statement_type
*os
=
362 lang_output_section_find(tree
->name
.name
);
363 check(os
,tree
->name
.name
,"ADDR");
364 result
= new_rel((bfd_vma
)0, os
);
371 if(allocation_done
!= lang_first_phase_enum
) {
372 lang_output_section_statement_type
*os
=
373 lang_output_section_find(tree
->name
.name
);
374 check(os
,tree
->name
.name
,"SIZEOF");
375 result
= new_abs((bfd_vma
)(os
->bfd_section
->_raw_size
));
390 DEFUN(exp_fold_tree
,(tree
, current_section
, allocation_done
,
393 lang_output_section_statement_type
*current_section AND
394 lang_phase_type allocation_done AND
398 etree_value_type result
;
400 if (tree
== (etree_type
*)NULL
) {
401 result
.valid
= false;
404 switch (tree
->type
.node_class
)
407 result
= new_rel(tree
->value
.value
, current_section
);
410 result
= exp_fold_tree(tree
->unary
.child
,
412 allocation_done
, dot
, dotp
);
413 if (result
.valid
== true)
415 switch(tree
->type
.node_code
)
418 if (allocation_done
!= lang_first_phase_enum
) {
419 result
= new_rel_from_section(ALIGN(dot
,
425 result
.valid
= false;
430 result
.value
= ~result
.value
;
434 result
.value
= !result
.value
;
438 result
.value
= -result
.value
;
441 if (allocation_done
==lang_allocating_phase_enum
) {
443 result
.value
= ALIGN(dot
, result
.value
);
446 /* Return next place aligned to value */
447 result
.valid
= false;
458 result
= exp_fold_tree(tree
->trinary
.cond
,
460 allocation_done
, dot
, dotp
);
462 result
= exp_fold_tree(result
.value
?
463 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
465 allocation_done
, dot
, dotp
);
470 result
= fold_binary(tree
, current_section
, allocation_done
,
474 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
475 /* Assignment to dot can only be done during allocation */
476 if (allocation_done
== lang_allocating_phase_enum
) {
477 result
= exp_fold_tree(tree
->assign
.src
,
479 lang_allocating_phase_enum
, dot
, dotp
);
480 if (result
.valid
== false) {
481 einfo("%F%S invalid assignment to location counter\n");
484 if (current_section
==
485 (lang_output_section_statement_type
*)NULL
) {
486 einfo("%F%S assignment to location counter invalid outside of SECTION\n");
489 unsigned long nextdot
=result
.value
+
490 current_section
->bfd_section
->vma
;
492 einfo("%F%S cannot move location counter backwards");
502 ldsym_type
*sy
= ldsym_get(tree
->assign
.dst
);
504 /* If this symbol has just been created then we'll place it into
505 * a section of our choice
507 result
= exp_fold_tree(tree
->assign
.src
,
508 current_section
, allocation_done
,
514 /* Add this definition to script file */
517 def_ptr
= sy
->sdefs_chain
;
523 def_ptr
= (asymbol
**)stat_alloc((bfd_size_type
)(sizeof(asymbol
**)));
524 def
= (asymbol
*)bfd_make_empty_symbol(script_file
->the_bfd
);
529 sy
->sdefs_chain
= def_ptr
;
533 def
->value
= result
.value
;
535 def
->section
= result
.section
->bfd_section
;
536 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
539 def
->udata
= (PTR
)NULL
;
540 def
->name
= sy
->name
;
542 if (sy
->sdefs_chain
== 0) Q_enter_global_ref(def_ptr
);
550 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
553 einfo("%F%S Need more of these %d",tree
->type
.node_class
);
563 DEFUN(exp_fold_tree_no_dot
,(tree
, current_section
, allocation_done
),
565 lang_output_section_statement_type
*current_section AND
566 lang_phase_type allocation_done
)
568 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
573 DEFUN(exp_binop
,(code
, lhs
, rhs
),
578 etree_type value
, *new;
581 value
.type
.node_code
= code
;
582 value
.binary
.lhs
= lhs
;
583 value
.binary
.rhs
= rhs
;
584 value
.type
.node_class
= etree_binary
;
585 r
= exp_fold_tree_no_dot(&value
,
587 lang_first_phase_enum
);
590 return exp_intop(r
.value
);
592 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->binary
)));
593 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
598 DEFUN(exp_trinop
,(code
, cond
, lhs
, rhs
),
604 etree_type value
, *new;
606 value
.type
.node_code
= code
;
607 value
.trinary
.lhs
= lhs
;
608 value
.trinary
.cond
= cond
;
609 value
.trinary
.rhs
= rhs
;
610 value
.type
.node_class
= etree_trinary
;
611 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
612 *)NULL
,lang_first_phase_enum
);
614 return exp_intop(r
.value
);
616 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->trinary
)));
617 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
623 DEFUN(exp_unop
,(code
, child
),
627 etree_type value
, *new;
630 value
.unary
.type
.node_code
= code
;
631 value
.unary
.child
= child
;
632 value
.unary
.type
.node_class
= etree_unary
;
633 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
634 lang_first_phase_enum
);
636 return exp_intop(r
.value
);
638 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->unary
)));
639 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
645 DEFUN(exp_nameop
,(code
, name
),
650 etree_type value
, *new;
652 value
.name
.type
.node_code
= code
;
653 value
.name
.name
= name
;
654 value
.name
.type
.node_class
= etree_name
;
657 r
= exp_fold_tree_no_dot(&value
,
658 (lang_output_section_statement_type
*)NULL
,
659 lang_first_phase_enum
);
661 return exp_intop(r
.value
);
663 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->name
)));
664 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
673 DEFUN(exp_assop
,(code
, dst
, src
),
678 etree_type value
, *new;
680 value
.assign
.type
.node_code
= code
;
683 value
.assign
.src
= src
;
684 value
.assign
.dst
= dst
;
685 value
.assign
.type
.node_class
= etree_assign
;
688 if (exp_fold_tree_no_dot(&value
, &result
)) {
689 return exp_intop(result
);
692 new = (etree_type
*)stat_alloc((bfd_size_type
)(sizeof(new->assign
)));
693 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
698 DEFUN(exp_print_tree
,(tree
),
701 switch (tree
->type
.node_class
) {
703 print_address(tree
->value
.value
);
708 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
709 fprintf(config
.map_file
,"%s (%x) ",tree
->assign
.dst
->name
,
710 tree
->assign
.dst
->sdefs
->value
);
713 fprintf(config
.map_file
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
716 fprintf(config
.map_file
,"%s ",tree
->assign
.dst
);
717 exp_print_token(tree
->type
.node_code
);
718 exp_print_tree(tree
->assign
.src
);
721 fprintf(config
.map_file
,"(");
722 exp_print_tree(tree
->binary
.lhs
);
723 exp_print_token(tree
->type
.node_code
);
724 exp_print_tree(tree
->binary
.rhs
);
725 fprintf(config
.map_file
,")");
728 exp_print_tree(tree
->trinary
.cond
);
729 fprintf(config
.map_file
,"?");
730 exp_print_tree(tree
->trinary
.lhs
);
731 fprintf(config
.map_file
,":");
732 exp_print_tree(tree
->trinary
.rhs
);
735 exp_print_token(tree
->unary
.type
.node_code
);
736 if (tree
->unary
.child
)
739 fprintf(config
.map_file
,"(");
740 exp_print_tree(tree
->unary
.child
);
741 fprintf(config
.map_file
,")");
746 fprintf(config
.map_file
,"????????");
749 if (tree
->type
.node_code
== NAME
) {
750 fprintf(config
.map_file
,"%s", tree
->name
.name
);
753 exp_print_token(tree
->type
.node_code
);
755 fprintf(config
.map_file
,"(%s)", tree
->name
.name
);
768 DEFUN(exp_get_vma
,(tree
, def
, name
, allocation_done
),
772 lang_phase_type allocation_done
)
776 if (tree
!= (etree_type
*)NULL
) {
777 r
= exp_fold_tree_no_dot(tree
,
780 if (r
.valid
== false && name
) {
781 einfo("%F%S Nonconstant expression for %s\n",name
);
791 DEFUN(exp_get_value_int
,(tree
,def
,name
, allocation_done
),
795 lang_phase_type allocation_done
)
797 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);