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. */
23 Revision 1.1 1991/03/21 21:28:34 gumby
26 * Revision 1.1 1991/03/13 00:48:16 chrisb
29 * Revision 1.6 1991/03/10 09:31:22 rich
31 * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
32 * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
33 * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
34 * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
35 * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
37 * As of this round of changes, ld now builds on all hosts of (Intel960)
38 * interest and copy passes my copy test on big endian hosts again.
40 * Revision 1.5 1991/03/09 03:25:04 sac
41 * Added support for LONG, SHORT and BYTE keywords in scripts
43 * Revision 1.4 1991/03/06 02:27:15 sac
44 * Added LONG, SHORT and BYTE keywords
46 * Revision 1.3 1991/02/22 17:14:59 sac
47 * Added RCS keywords and copyrights
52 * Written by Steve Chamberlain
55 * This module handles expression trees.
66 #include "ldgram.tab.h"
70 extern char *output_filename
;
71 extern unsigned int undefined_global_sym_count
;
72 extern unsigned int defined_global_sym_count
;
73 extern bfd
*output_bfd
;
74 extern size_t largest_section
;
75 extern lang_statement_list_type file_chain
;
76 extern args_type command_line
;
77 extern ld_config_type config
;
79 extern lang_input_statement_type
*script_file
;
80 extern unsigned int defined_global_sym_count
;
82 extern bfd_vma print_dot
;
86 exp_print_token(outfile
, code
)
117 ALIGNMENT
,"ALIGNMENT",
118 SIZEOF_HEADERS
,"SIZEOF_HEADERS",
130 SEARCH_DIR
,"SEARCH_DIR",
141 for (idx
= 0; table
[idx
].name
!= (char*)NULL
; idx
++) {
142 if (table
[idx
].code
== code
) {
143 fprintf(outfile
, "%s", table
[idx
].name
);
147 /* Not in table, just print it alone */
148 fprintf(outfile
, "%c",code
);
153 etree_value_type
*ptr
;
155 if (ptr
->section
!= (lang_output_section_statement_type
*)NULL
) {
156 asection
*s
= ptr
->section
->bfd_section
;
157 ptr
->value
+= s
->vma
;
158 ptr
->section
= (lang_output_section_statement_type
*)NULL
;
163 etree_value_type
new_abs(value
)
166 etree_value_type
new;
168 new.section
= (lang_output_section_statement_type
*)NULL
;
173 static void check(os
)
174 lang_output_section_statement_type
*os
;
176 if (os
== (lang_output_section_statement_type
*)NULL
) {
177 info("%F%P undefined section");
179 if (os
->processed
== false) {
180 info("%F%P forward reference of section");
184 etree_type
*exp_intop(value
)
187 etree_type
*new = (etree_type
*)ldmalloc(sizeof(new->value
));
188 new->type
.node_code
= INT
;
189 new->value
.value
= value
;
190 new->type
.node_class
= etree_value
;
197 etree_value_type
new_rel(value
, section
)
199 lang_output_section_statement_type
*section
;
201 etree_value_type
new;
204 new.section
= section
;
209 etree_value_type
new_rel_from_section(value
, section
)
211 lang_output_section_statement_type
*section
;
213 etree_value_type
new;
216 new.section
= section
;
217 if (new.section
!= (lang_output_section_statement_type
*)NULL
) {
218 new.value
-= section
->bfd_section
->vma
;
223 static etree_value_type
224 fold_binary(tree
, current_section
, allocation_done
, dot
, dotp
)
226 lang_output_section_statement_type
*current_section
;
227 lang_phase_type allocation_done
;
231 etree_value_type result
;
233 result
= exp_fold_tree(tree
->binary
.lhs
, current_section
,
234 allocation_done
, dot
, dotp
);
236 etree_value_type other
;
237 other
= exp_fold_tree(tree
->binary
.rhs
,
239 allocation_done
, dot
,dotp
) ;
241 /* If values are from different sections, or this is an */
242 /* absolute expression, make both source args absolute */
243 if (result
.section
!= other
.section
||
244 current_section
== (lang_output_section_statement_type
*)NULL
) {
250 switch (tree
->type
.node_code
)
253 /* Mod, both absolule*/
255 if (other
.value
== 0) {
256 info("%F%S % by zero\n");
258 result
.value
%= other
.value
;
261 if (other
.value
== 0) {
262 info("%F%S / by zero\n");
264 result
.value
/= other
.value
;
266 #define BOP(x,y) case x : result.value = result.value y other.value;break;
290 etree_value_type
invalid()
292 etree_value_type
new;
297 etree_value_type
fold_name(tree
, current_section
, allocation_done
, dot
)
299 lang_output_section_statement_type
*current_section
;
300 lang_phase_type allocation_done
;
304 etree_value_type result
;
305 switch (tree
->type
.node_code
)
309 ldsym_get_soft(tree
->name
.name
) != (ldsym_type
*)NULL
;
314 result
.valid
= false;
315 if (tree
->name
.name
[0] == '.' && tree
->name
.name
[1] == 0) {
317 if (allocation_done
!= lang_first_phase_enum
) {
318 result
= new_rel_from_section(dot
, current_section
);
325 if (allocation_done
== lang_final_phase_enum
) {
326 ldsym_type
*sy
= ldsym_get_soft(tree
->name
.name
);
329 asymbol
**sdefp
= sy
->sdefs_chain
;
332 asymbol
*sdef
= *sdefp
;
333 if (sdef
->section
== (asection
*)NULL
) {
334 /* This is an absolute symbol */
335 result
= new_abs(sdef
->value
);
338 lang_output_section_statement_type
*os
=
339 lang_output_section_statement_lookup( sdef
->section
->output_section
->name
);
340 result
= new_rel(sdef
->value
, os
);
344 if (result
.valid
== false) {
345 info("%F%S: undefined symbol `%s' referenced in expression.\n",
356 if (allocation_done
!= lang_first_phase_enum
) {
357 lang_output_section_statement_type
*os
=
358 lang_output_section_find(tree
->name
.name
);
360 result
= new_rel((bfd_vma
)0, os
);
367 if(allocation_done
!= lang_first_phase_enum
) {
368 lang_output_section_statement_type
*os
=
369 lang_output_section_find(tree
->name
.name
);
371 result
= new_abs((bfd_vma
)(os
->bfd_section
->size
));
385 etree_value_type
exp_fold_tree(tree
, current_section
, allocation_done
,
388 lang_output_section_statement_type
*current_section
;
389 lang_phase_type allocation_done
;
393 etree_value_type result
;
395 if (tree
== (etree_type
*)NULL
) {
396 result
.valid
= false;
399 switch (tree
->type
.node_class
)
402 result
= new_rel(tree
->value
.value
, current_section
);
405 result
= exp_fold_tree(tree
->unary
.child
,
407 allocation_done
, dot
, dotp
);
408 if (result
.valid
== true)
410 switch(tree
->type
.node_code
)
413 if (allocation_done
!= lang_first_phase_enum
) {
414 result
= new_rel_from_section(ALIGN(dot
,
420 result
.valid
= false;
424 result
.value
= -result
.value
;
427 result
.valid
= false;
437 result
= exp_fold_tree(tree
->trinary
.cond
,
439 allocation_done
, dot
, dotp
);
441 result
= exp_fold_tree(result
.value
?
442 tree
->trinary
.lhs
:tree
->trinary
.rhs
,
444 allocation_done
, dot
, dotp
);
449 result
= fold_binary(tree
, current_section
, allocation_done
,
453 if (tree
->assign
.dst
[0] == '.' && tree
->assign
.dst
[1] == 0) {
454 /* Assignment to dot can only be done during allocation */
455 if (allocation_done
== lang_allocating_phase_enum
) {
456 result
= exp_fold_tree(tree
->assign
.src
,
458 lang_allocating_phase_enum
, dot
, dotp
);
459 if (result
.valid
== false) {
460 info("%F%S invalid assignment to location counter\n");
463 if (current_section
==
464 (lang_output_section_statement_type
*)NULL
) {
465 info("%F%S assignment to location counter invalid outside of SECTION\n");
468 unsigned long nextdot
=result
.value
+
469 current_section
->bfd_section
->vma
;
471 info("%F%S cannot move location counter backwards");
481 ldsym_type
*sy
= ldsym_get(tree
->assign
.dst
);
483 /* If this symbol has just been created then we'll place it into
484 * a section of our choice
486 result
= exp_fold_tree(tree
->assign
.src
,
487 current_section
, allocation_done
,
492 asymbol
**def_ptr
= (asymbol
**)ldmalloc(sizeof(asymbol
**));
493 /* Add this definition to script file */
494 def
= (asymbol
*)bfd_make_empty_symbol(script_file
->the_bfd
);
498 def
->value
= result
.value
;
499 if (result
.section
!=
500 (lang_output_section_statement_type
*)NULL
) {
501 if (current_section
!=
502 (lang_output_section_statement_type
*)NULL
) {
504 def
->section
= result
.section
->bfd_section
;
505 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
;
508 /* Force to absolute */
509 def
->value
+= result
.section
->bfd_section
->vma
;
510 def
->section
= (asection
*)NULL
;
511 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
517 def
->section
= (asection
*)NULL
;
518 def
->flags
= BSF_GLOBAL
| BSF_EXPORT
| BSF_ABSOLUTE
;
522 def
->udata
= (void *)NULL
;
523 def
->name
= sy
->name
;
524 Q_enter_global_ref(def_ptr
);
532 result
= fold_name(tree
, current_section
, allocation_done
, dot
);
535 info("%F%S Need more of these %d",tree
->type
.node_class
);
544 etree_value_type
exp_fold_tree_no_dot(tree
, current_section
, allocation_done
)
546 lang_output_section_statement_type
*current_section
;
547 lang_phase_type allocation_done
;
549 return exp_fold_tree(tree
, current_section
, allocation_done
, (bfd_vma
)
554 exp_binop(code
, lhs
, rhs
)
559 etree_type value
, *new;
562 value
.type
.node_code
= code
;
563 value
.binary
.lhs
= lhs
;
564 value
.binary
.rhs
= rhs
;
565 value
.type
.node_class
= etree_binary
;
566 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
*)NULL
,
567 lang_first_phase_enum
);
570 return exp_intop(r
.value
);
572 new = (etree_type
*)ldmalloc(sizeof(new->binary
));
573 memcpy((char *)new, (char *)&value
, sizeof(new->binary
));
578 exp_trinop(code
, cond
, lhs
, rhs
)
584 etree_type value
, *new;
586 value
.type
.node_code
= code
;
587 value
.trinary
.lhs
= lhs
;
588 value
.trinary
.cond
= cond
;
589 value
.trinary
.rhs
= rhs
;
590 value
.type
.node_class
= etree_trinary
;
591 r
= exp_fold_tree_no_dot(&value
, (lang_output_section_statement_type
592 *)NULL
,lang_first_phase_enum
);
594 return exp_intop(r
.value
);
596 new = (etree_type
*)ldmalloc(sizeof(new->trinary
));
597 memcpy((char *)new,(char *) &value
, sizeof(new->trinary
));
603 exp_unop(code
, child
)
607 etree_type value
, *new;
610 value
.unary
.type
.node_code
= code
;
611 value
.unary
.child
= child
;
612 value
.unary
.type
.node_class
= etree_unary
;
613 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
614 lang_first_phase_enum
);
616 return exp_intop(r
.value
);
618 new = (etree_type
*)ldmalloc(sizeof(new->unary
));
619 memcpy((char *)new, (char *)&value
, sizeof(new->unary
));
625 exp_nameop(code
, name
)
630 etree_type value
, *new;
633 value
.name
.type
.node_code
= code
;
634 value
.name
.name
= name
;
635 value
.name
.type
.node_class
= etree_name
;
638 r
= exp_fold_tree_no_dot(&value
,(lang_output_section_statement_type
*)NULL
,
639 lang_first_phase_enum
);
641 return exp_intop(r
.value
);
643 new = (etree_type
*)ldmalloc(sizeof(new->name
));
644 memcpy((char *)new, (char *)&value
, sizeof(new->name
));
653 exp_assop(code
, dst
, src
)
658 etree_type value
, *new;
660 value
.assign
.type
.node_code
= code
;
663 value
.assign
.src
= src
;
664 value
.assign
.dst
= dst
;
665 value
.assign
.type
.node_class
= etree_assign
;
668 if (exp_fold_tree_no_dot(&value
, &result
)) {
669 return exp_intop(result
);
672 new = (etree_type
*)ldmalloc(sizeof(new->assign
));
673 memcpy((char *)new, (char *)&value
, sizeof(new->assign
));
678 exp_print_tree(outfile
, tree
)
682 switch (tree
->type
.node_class
) {
684 fprintf(outfile
,"0x%08lx",(bfd_vma
)(tree
->value
.value
));
688 if (tree
->assign
.dst
->sdefs
!= (asymbol
*)NULL
){
689 fprintf(outfile
,"%s (%x) ",tree
->assign
.dst
->name
,
690 tree
->assign
.dst
->sdefs
->value
);
693 fprintf(outfile
,"%s (UNDEFINED)",tree
->assign
.dst
->name
);
696 fprintf(outfile
,"%s ",tree
->assign
.dst
);
697 exp_print_token(outfile
,tree
->type
.node_code
);
698 exp_print_tree(outfile
,tree
->assign
.src
);
701 exp_print_tree(outfile
,tree
->binary
.lhs
);
702 exp_print_token(outfile
,tree
->type
.node_code
);
703 exp_print_tree(outfile
,tree
->binary
.rhs
);
706 exp_print_tree(outfile
,tree
->trinary
.cond
);
707 fprintf(outfile
,"?");
708 exp_print_tree(outfile
,tree
->trinary
.lhs
);
709 fprintf(outfile
,":");
710 exp_print_tree(outfile
,tree
->trinary
.rhs
);
713 exp_print_token(outfile
,tree
->unary
.type
.node_code
);
714 fprintf(outfile
,"(");
715 exp_print_tree(outfile
,tree
->unary
.child
);
716 fprintf(outfile
,")");
719 fprintf(outfile
,"????????");
722 if (tree
->type
.node_code
== NAME
) {
723 fprintf(outfile
,"%s", tree
->name
.name
);
726 exp_print_token(outfile
,tree
->type
.node_code
);
727 fprintf(outfile
,"(%s)", tree
->name
.name
);
740 exp_get_vma(tree
, def
, name
, allocation_done
)
744 lang_phase_type allocation_done
;
748 if (tree
!= (etree_type
*)NULL
) {
749 r
= exp_fold_tree_no_dot(tree
,
750 (lang_output_section_statement_type
*)NULL
,
752 if (r
.valid
== false && name
) {
753 info("%F%S Nonconstant expression for %s\n",name
);
763 exp_get_value_int(tree
,def
,name
, allocation_done
)
767 lang_phase_type allocation_done
;
769 return (int)exp_get_vma(tree
,(bfd_vma
)def
,name
, allocation_done
);