1 /* Copyright (C) 1991 Free Software Foundation, Inc.
3 This file is part of GLD, the Gnu Linker.
5 GLD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
10 GLD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GLD; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 * Written by Steve Chamberlain
27 * This module handles expression trees.
38 #include "ldgram.tab.h"
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 size_t 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 exp_print_token(outfile
, code
)
89 ALIGNMENT
,"ALIGNMENT",
90 SIZEOF_HEADERS
,"SIZEOF_HEADERS",
102 SEARCH_DIR
,"SEARCH_DIR",
113 for (idx
= 0; table
[idx
].name
!= (char*)NULL
; idx
++) {
114 if (table
[idx
].code
== code
) {
115 fprintf(outfile
, "%s", table
[idx
].name
);
119 /* Not in table, just print it alone */
120 fprintf(outfile
, "%c",code
);
125 etree_value_type
*ptr
;
127 if (ptr
->section
!= (lang_output_section_statement_type
*)NULL
) {
128 asection
*s
= ptr
->section
->bfd_section
;
129 ptr
->value
+= s
->vma
;
130 ptr
->section
= (lang_output_section_statement_type
*)NULL
;
135 etree_value_type
new_abs(value
)
138 etree_value_type
new;
140 new.section
= (lang_output_section_statement_type
*)NULL
;
146 DEFUN(check
, (os
, name
, op
),
147 lang_output_section_statement_type
*os AND
151 if (os
== (lang_output_section_statement_type
*)NULL
) {
152 info("%F%P %s uses undefined section %s\n", op
, name
);
154 if (os
->processed
== false) {
155 info("%F%P %s forward reference of section %s\n",op
, name
);
159 etree_type
*exp_intop(value
)
162 etree_type
*new = (etree_type
*)ldmalloc(sizeof(new->value
));
163 new->type
.node_code
= INT
;
164 new->value
.value
= value
;
165 new->type
.node_class
= etree_value
;
172 etree_value_type
new_rel(value
, section
)
174 lang_output_section_statement_type
*section
;
176 etree_value_type
new;
179 new.section
= section
;
184 etree_value_type
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 fold_binary(tree
, current_section
, allocation_done
, dot
, dotp
)
201 lang_output_section_statement_type
*current_section
;
202 lang_phase_type allocation_done
;
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 info("%F%S % by zero\n");
233 result
.value
%= other
.value
;
236 if (other
.value
== 0) {
237 info("%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;
268 etree_value_type
invalid()
270 etree_value_type
new;
275 etree_value_type
fold_name(tree
, current_section
, allocation_done
, dot
)
277 lang_output_section_statement_type
*current_section
;
278 lang_phase_type allocation_done
;
282 etree_value_type result
;
283 switch (tree
->type
.node_code
)
287 ldsym_get_soft(tree
->name
.name
) != (ldsym_type
*)NULL
;
292 result
.valid
= false;
293 if (tree
->name
.name
[0] == '.' && tree
->name
.name
[1] == 0) {
295 if (allocation_done
!= lang_first_phase_enum
) {
296 result
= new_rel_from_section(dot
, current_section
);
303 if (allocation_done
== lang_final_phase_enum
) {
304 ldsym_type
*sy
= ldsym_get_soft(tree
->name
.name
);
307 asymbol
**sdefp
= sy
->sdefs_chain
;
310 asymbol
*sdef
= *sdefp
;
311 if (sdef
->section
== (asection
*)NULL
) {
312 /* This is an absolute symbol */
313 result
= new_abs(sdef
->value
);
316 lang_output_section_statement_type
*os
=
317 lang_output_section_statement_lookup(
318 sdef
->section
->output_section
->name
);
319 /* If the symbol is from a file which we are not
320 relocating (-R) then return an absolute for its
322 if (sdef
->the_bfd
->usrdata
&&
323 ((lang_input_statement_type
*)(sdef
->the_bfd
->usrdata
))->just_syms_flag
== true)
325 result
= new_abs(sdef
->value
+ (sdef
->section
?
326 sdef
->section
->vma
: 0));
329 result
= new_rel(sdef
->value
+ sdef
->section
->output_offset
, os
);
334 if (result
.valid
== false) {
335 info("%F%S: undefined symbol `%s' referenced in expression.\n",
346 if (allocation_done
!= lang_first_phase_enum
) {
347 lang_output_section_statement_type
*os
=
348 lang_output_section_find(tree
->name
.name
);
349 check(os
,tree
->name
.name
,"ADDR");
350 result
= new_rel((bfd_vma
)0, os
);
357 if(allocation_done
!= lang_first_phase_enum
) {
358 lang_output_section_statement_type
*os
=
359 lang_output_section_find(tree
->name
.name
);
360 check(os
,tree
->name
.name
,"SIZEOF");
361 result
= new_abs((bfd_vma
)(os
->bfd_section
->size
));
375 etree_value_type
exp_fold_tree(tree
, current_section
, allocation_done
,
378 lang_output_section_statement_type
*current_section
;
379 lang_phase_type allocation_done
;
383 etree_value_type result
;
385 if (tree
== (etree_type
*)NULL
) {
386 result
.valid
= false;
389 switch (tree
->type
.node_class
)
392 result
= new_rel(tree
->value
.value
, current_section
);
395 result
= exp_fold_tree(tree
->unary
.child
,
397 allocation_done
, dot
, dotp
);
398 if (result
.valid
== true)
400 switch(tree
->type
.node_code
)
403 if (allocation_done
!= lang_first_phase_enum
) {
404 result
= new_rel_from_section(ALIGN(dot
,
410 result
.valid
= false;
415 result
.value
= ~result
.value
;
419 result
.value
= !result
.value
;
423 result
.value
= -result
.value
;
426 result
.valid
= false;
436 result
= exp_fold_tree(tree
->trinary
.cond
,
438 allocation_done
, dot
, dotp
);
440 result
= exp_fold_tree(result
.value
?
441 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
443 allocation_done
, dot
, dotp
);
448 result
= fold_binary(tree
, current_section
, allocation_done
,
452 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
453 /* Assignment to dot can only be done during allocation */
454 if (allocation_done
== lang_allocating_phase_enum
) {
455 result
= exp_fold_tree(tree
->assign
.src
,
457 lang_allocating_phase_enum
, dot
, dotp
);
458 if (result
.valid
== false) {
459 info("%F%S invalid assignment to location counter\n");
462 if (current_section
==
463 (lang_output_section_statement_type
*)NULL
) {
464 info("%F%S assignment to location counter invalid outside of SECTION\n");
467 unsigned long nextdot
=result
.value
+
468 current_section
->bfd_section
->vma
;
470 info("%F%S cannot move location counter backwards");
480 ldsym_type
*sy
= ldsym_get(tree
->assign
.dst
);
482 /* If this symbol has just been created then we'll place it into
483 * a section of our choice
485 result
= exp_fold_tree(tree
->assign
.src
,
486 current_section
, allocation_done
,
491 asymbol
**def_ptr
= (asymbol
**)ldmalloc(sizeof(asymbol
**));
492 /* Add this definition to script file */
493 def
= (asymbol
*)bfd_make_empty_symbol(script_file
->the_bfd
);
497 def
->value
= result
.value
;
498 if (result
.section
!=
499 (lang_output_section_statement_type
*)NULL
) {
500 if (current_section
!=
501 (lang_output_section_statement_type
*)NULL
) {
503 def
->section
= result
.section
->bfd_section
;
504 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
507 /* Force to absolute */
508 def
->value
+= result
.section
->bfd_section
->vma
;
509 def
->section
= (asection
*)NULL
;
510 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
516 def
->section
= (asection
*)NULL
;
517 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
521 def
->udata
= (PTR
)NULL
;
522 def
->name
= sy
->name
;
523 Q_enter_global_ref(def_ptr
);
531 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
534 info("%F%S Need more of these %d",tree
->type
.node_class
);
543 etree_value_type
exp_fold_tree_no_dot(tree
, current_section
, allocation_done
)
545 lang_output_section_statement_type
*current_section
;
546 lang_phase_type allocation_done
;
548 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
553 exp_binop(code
, lhs
, rhs
)
558 etree_type value
, *new;
561 value
.type
.node_code
= code
;
562 value
.binary
.lhs
= lhs
;
563 value
.binary
.rhs
= rhs
;
564 value
.type
.node_class
= etree_binary
;
565 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
*)NULL
,
566 lang_first_phase_enum
);
569 return exp_intop(r
.value
);
571 new = (etree_type
*)ldmalloc(sizeof(new->binary
));
572 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
577 exp_trinop(code
, cond
, lhs
, rhs
)
583 etree_type value
, *new;
585 value
.type
.node_code
= code
;
586 value
.trinary
.lhs
= lhs
;
587 value
.trinary
.cond
= cond
;
588 value
.trinary
.rhs
= rhs
;
589 value
.type
.node_class
= etree_trinary
;
590 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
591 *)NULL
,lang_first_phase_enum
);
593 return exp_intop(r
.value
);
595 new = (etree_type
*)ldmalloc(sizeof(new->trinary
));
596 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
602 exp_unop(code
, child
)
606 etree_type value
, *new;
609 value
.unary
.type
.node_code
= code
;
610 value
.unary
.child
= child
;
611 value
.unary
.type
.node_class
= etree_unary
;
612 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
613 lang_first_phase_enum
);
615 return exp_intop(r
.value
);
617 new = (etree_type
*)ldmalloc(sizeof(new->unary
));
618 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
624 exp_nameop(code
, name
)
629 etree_type value
, *new;
632 value
.name
.type
.node_code
= code
;
633 value
.name
.name
= name
;
634 value
.name
.type
.node_class
= etree_name
;
637 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
638 lang_first_phase_enum
);
640 return exp_intop(r
.value
);
642 new = (etree_type
*)ldmalloc(sizeof(new->name
));
643 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
652 exp_assop(code
, dst
, src
)
657 etree_type value
, *new;
659 value
.assign
.type
.node_code
= code
;
662 value
.assign
.src
= src
;
663 value
.assign
.dst
= dst
;
664 value
.assign
.type
.node_class
= etree_assign
;
667 if (exp_fold_tree_no_dot(&value
, &result
)) {
668 return exp_intop(result
);
671 new = (etree_type
*)ldmalloc(sizeof(new->assign
));
672 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
677 exp_print_tree(outfile
, tree
)
681 switch (tree
->type
.node_class
) {
683 fprintf(outfile
,"0x%08lx",(bfd_vma
)(tree
->value
.value
));
687 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
688 fprintf(outfile
,"%s (%x) ",tree
->assign
.dst
->name
,
689 tree
->assign
.dst
->sdefs
->value
);
692 fprintf(outfile
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
695 fprintf(outfile
,"%s ",tree
->assign
.dst
);
696 exp_print_token(outfile
,tree
->type
.node_code
);
697 exp_print_tree(outfile
,tree
->assign
.src
);
700 exp_print_tree(outfile
,tree
->binary
.lhs
);
701 exp_print_token(outfile
,tree
->type
.node_code
);
702 exp_print_tree(outfile
,tree
->binary
.rhs
);
705 exp_print_tree(outfile
,tree
->trinary
.cond
);
706 fprintf(outfile
,"?");
707 exp_print_tree(outfile
,tree
->trinary
.lhs
);
708 fprintf(outfile
,":");
709 exp_print_tree(outfile
,tree
->trinary
.rhs
);
712 exp_print_token(outfile
,tree
->unary
.type
.node_code
);
713 fprintf(outfile
,"(");
714 exp_print_tree(outfile
,tree
->unary
.child
);
715 fprintf(outfile
,")");
718 fprintf(outfile
,"????????");
721 if (tree
->type
.node_code
== NAME
) {
722 fprintf(outfile
,"%s", tree
->name
.name
);
725 exp_print_token(outfile
,tree
->type
.node_code
);
726 fprintf(outfile
,"(%s)", tree
->name
.name
);
739 exp_get_vma(tree
, def
, name
, allocation_done
)
743 lang_phase_type allocation_done
;
747 if (tree
!= (etree_type
*)NULL
) {
748 r
= exp_fold_tree_no_dot(tree
,
749 (lang_output_section_statement_type
*)NULL
,
751 if (r
.valid
== false && name
) {
752 info("%F%S Nonconstant expression for %s\n",name
);
762 exp_get_value_int(tree
,def
,name
, allocation_done
)
766 lang_phase_type allocation_done
;
768 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);