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( sdef
->section
->output_section
->name
);
318 result
= new_rel(sdef
->value
, os
);
322 if (result
.valid
== false) {
323 info("%F%S: undefined symbol `%s' referenced in expression.\n",
334 if (allocation_done
!= lang_first_phase_enum
) {
335 lang_output_section_statement_type
*os
=
336 lang_output_section_find(tree
->name
.name
);
337 check(os
,tree
->name
.name
,"ADDR");
338 result
= new_rel((bfd_vma
)0, os
);
345 if(allocation_done
!= lang_first_phase_enum
) {
346 lang_output_section_statement_type
*os
=
347 lang_output_section_find(tree
->name
.name
);
348 check(os
,tree
->name
.name
,"SIZEOF");
349 result
= new_abs((bfd_vma
)(os
->bfd_section
->size
));
363 etree_value_type
exp_fold_tree(tree
, current_section
, allocation_done
,
366 lang_output_section_statement_type
*current_section
;
367 lang_phase_type allocation_done
;
371 etree_value_type result
;
373 if (tree
== (etree_type
*)NULL
) {
374 result
.valid
= false;
377 switch (tree
->type
.node_class
)
380 result
= new_rel(tree
->value
.value
, current_section
);
383 result
= exp_fold_tree(tree
->unary
.child
,
385 allocation_done
, dot
, dotp
);
386 if (result
.valid
== true)
388 switch(tree
->type
.node_code
)
391 if (allocation_done
!= lang_first_phase_enum
) {
392 result
= new_rel_from_section(ALIGN(dot
,
398 result
.valid
= false;
402 result
.value
= -result
.value
;
405 result
.valid
= false;
415 result
= exp_fold_tree(tree
->trinary
.cond
,
417 allocation_done
, dot
, dotp
);
419 result
= exp_fold_tree(result
.value
?
420 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
422 allocation_done
, dot
, dotp
);
427 result
= fold_binary(tree
, current_section
, allocation_done
,
431 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
432 /* Assignment to dot can only be done during allocation */
433 if (allocation_done
== lang_allocating_phase_enum
) {
434 result
= exp_fold_tree(tree
->assign
.src
,
436 lang_allocating_phase_enum
, dot
, dotp
);
437 if (result
.valid
== false) {
438 info("%F%S invalid assignment to location counter\n");
441 if (current_section
==
442 (lang_output_section_statement_type
*)NULL
) {
443 info("%F%S assignment to location counter invalid outside of SECTION\n");
446 unsigned long nextdot
=result
.value
+
447 current_section
->bfd_section
->vma
;
449 info("%F%S cannot move location counter backwards");
459 ldsym_type
*sy
= ldsym_get(tree
->assign
.dst
);
461 /* If this symbol has just been created then we'll place it into
462 * a section of our choice
464 result
= exp_fold_tree(tree
->assign
.src
,
465 current_section
, allocation_done
,
470 asymbol
**def_ptr
= (asymbol
**)ldmalloc(sizeof(asymbol
**));
471 /* Add this definition to script file */
472 def
= (asymbol
*)bfd_make_empty_symbol(script_file
->the_bfd
);
476 def
->value
= result
.value
;
477 if (result
.section
!=
478 (lang_output_section_statement_type
*)NULL
) {
479 if (current_section
!=
480 (lang_output_section_statement_type
*)NULL
) {
482 def
->section
= result
.section
->bfd_section
;
483 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
486 /* Force to absolute */
487 def
->value
+= result
.section
->bfd_section
->vma
;
488 def
->section
= (asection
*)NULL
;
489 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
495 def
->section
= (asection
*)NULL
;
496 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
500 def
->udata
= (PTR
)NULL
;
501 def
->name
= sy
->name
;
502 Q_enter_global_ref(def_ptr
);
510 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
513 info("%F%S Need more of these %d",tree
->type
.node_class
);
522 etree_value_type
exp_fold_tree_no_dot(tree
, current_section
, allocation_done
)
524 lang_output_section_statement_type
*current_section
;
525 lang_phase_type allocation_done
;
527 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
532 exp_binop(code
, lhs
, rhs
)
537 etree_type value
, *new;
540 value
.type
.node_code
= code
;
541 value
.binary
.lhs
= lhs
;
542 value
.binary
.rhs
= rhs
;
543 value
.type
.node_class
= etree_binary
;
544 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
*)NULL
,
545 lang_first_phase_enum
);
548 return exp_intop(r
.value
);
550 new = (etree_type
*)ldmalloc(sizeof(new->binary
));
551 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
556 exp_trinop(code
, cond
, lhs
, rhs
)
562 etree_type value
, *new;
564 value
.type
.node_code
= code
;
565 value
.trinary
.lhs
= lhs
;
566 value
.trinary
.cond
= cond
;
567 value
.trinary
.rhs
= rhs
;
568 value
.type
.node_class
= etree_trinary
;
569 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
570 *)NULL
,lang_first_phase_enum
);
572 return exp_intop(r
.value
);
574 new = (etree_type
*)ldmalloc(sizeof(new->trinary
));
575 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
581 exp_unop(code
, child
)
585 etree_type value
, *new;
588 value
.unary
.type
.node_code
= code
;
589 value
.unary
.child
= child
;
590 value
.unary
.type
.node_class
= etree_unary
;
591 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
592 lang_first_phase_enum
);
594 return exp_intop(r
.value
);
596 new = (etree_type
*)ldmalloc(sizeof(new->unary
));
597 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
603 exp_nameop(code
, name
)
608 etree_type value
, *new;
611 value
.name
.type
.node_code
= code
;
612 value
.name
.name
= name
;
613 value
.name
.type
.node_class
= etree_name
;
616 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
617 lang_first_phase_enum
);
619 return exp_intop(r
.value
);
621 new = (etree_type
*)ldmalloc(sizeof(new->name
));
622 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
631 exp_assop(code
, dst
, src
)
636 etree_type value
, *new;
638 value
.assign
.type
.node_code
= code
;
641 value
.assign
.src
= src
;
642 value
.assign
.dst
= dst
;
643 value
.assign
.type
.node_class
= etree_assign
;
646 if (exp_fold_tree_no_dot(&value
, &result
)) {
647 return exp_intop(result
);
650 new = (etree_type
*)ldmalloc(sizeof(new->assign
));
651 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
656 exp_print_tree(outfile
, tree
)
660 switch (tree
->type
.node_class
) {
662 fprintf(outfile
,"0x%08lx",(bfd_vma
)(tree
->value
.value
));
666 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
667 fprintf(outfile
,"%s (%x) ",tree
->assign
.dst
->name
,
668 tree
->assign
.dst
->sdefs
->value
);
671 fprintf(outfile
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
674 fprintf(outfile
,"%s ",tree
->assign
.dst
);
675 exp_print_token(outfile
,tree
->type
.node_code
);
676 exp_print_tree(outfile
,tree
->assign
.src
);
679 exp_print_tree(outfile
,tree
->binary
.lhs
);
680 exp_print_token(outfile
,tree
->type
.node_code
);
681 exp_print_tree(outfile
,tree
->binary
.rhs
);
684 exp_print_tree(outfile
,tree
->trinary
.cond
);
685 fprintf(outfile
,"?");
686 exp_print_tree(outfile
,tree
->trinary
.lhs
);
687 fprintf(outfile
,":");
688 exp_print_tree(outfile
,tree
->trinary
.rhs
);
691 exp_print_token(outfile
,tree
->unary
.type
.node_code
);
692 fprintf(outfile
,"(");
693 exp_print_tree(outfile
,tree
->unary
.child
);
694 fprintf(outfile
,")");
697 fprintf(outfile
,"????????");
700 if (tree
->type
.node_code
== NAME
) {
701 fprintf(outfile
,"%s", tree
->name
.name
);
704 exp_print_token(outfile
,tree
->type
.node_code
);
705 fprintf(outfile
,"(%s)", tree
->name
.name
);
718 exp_get_vma(tree
, def
, name
, allocation_done
)
722 lang_phase_type allocation_done
;
726 if (tree
!= (etree_type
*)NULL
) {
727 r
= exp_fold_tree_no_dot(tree
,
728 (lang_output_section_statement_type
*)NULL
,
730 if (r
.valid
== false && name
) {
731 info("%F%S Nonconstant expression for %s\n",name
);
741 exp_get_value_int(tree
,def
,name
, allocation_done
)
745 lang_phase_type allocation_done
;
747 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);