Initial revision
[deliverable/binutils-gdb.git] / ld / ldexp.c
CommitLineData
2fa0b342
DHW
1/* Copyright (C) 1991 Free Software Foundation, Inc.
2
3This file is part of GLD, the Gnu Linker.
4
5GLD is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 1, or (at your option)
8any later version.
9
10GLD is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GLD; see the file COPYING. If not, write to
17the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19/*
20 $Id$
21
22 $Log$
23 Revision 1.1 1991/03/21 21:28:34 gumby
24 Initial revision
25
26 * Revision 1.1 1991/03/13 00:48:16 chrisb
27 * Initial revision
28 *
29 * Revision 1.6 1991/03/10 09:31:22 rich
30 * Modified Files:
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
36 *
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.
39 *
40 * Revision 1.5 1991/03/09 03:25:04 sac
41 * Added support for LONG, SHORT and BYTE keywords in scripts
42 *
43 * Revision 1.4 1991/03/06 02:27:15 sac
44 * Added LONG, SHORT and BYTE keywords
45 *
46 * Revision 1.3 1991/02/22 17:14:59 sac
47 * Added RCS keywords and copyrights
48 *
49*/
50
51/*
52 * Written by Steve Chamberlain
53 * steve@cygnus.com
54 *
55 * This module handles expression trees.
56 */
57
58
59#include "sysdep.h"
60#include "bfd.h"
61
62#include "ld.h"
63#include "ldmain.h"
64#include "ldmisc.h"
65#include "ldexp.h"
66#include "ldgram.tab.h"
67#include "ldsym.h"
68#include "ldlang.h"
69
70extern char *output_filename;
71extern unsigned int undefined_global_sym_count;
72extern unsigned int defined_global_sym_count;
73extern bfd *output_bfd;
74extern size_t largest_section;
75extern lang_statement_list_type file_chain;
76extern args_type command_line;
77extern ld_config_type config;
78
79extern lang_input_statement_type *script_file;
80extern unsigned int defined_global_sym_count;
81
82extern bfd_vma print_dot;
83
84
85static void
86exp_print_token(outfile, code)
87FILE *outfile;
88token_code_type code;
89{
90 static struct {
91 token_code_type code;
92 char *name;
93 } table[] =
94 {
95 INT, "int",
96 CHAR,"char",
97 NAME,"NAME",
98 PLUSEQ,"+=",
99 MINUSEQ,"-=",
100 MULTEQ,"*=",
101 DIVEQ,"/=",
102 LSHIFTEQ,"<<=",
103 RSHIFTEQ,">>=",
104 ANDEQ,"&=",
105 OREQ,"|=",
106 OROR,"||",
107 ANDAND,"&&",
108 EQ,"==",
109 NE,"!=",
110 LE,"<=",
111 GE,">=",
112 LSHIFT,"<<",
113 RSHIFT,">>=",
114 ALIGN_K,"ALIGN",
115 BLOCK,"BLOCK",
116 SECTIONS,"SECTIONS",
117 ALIGNMENT,"ALIGNMENT",
118 SIZEOF_HEADERS,"SIZEOF_HEADERS",
119 NEXT,"NEXT",
120 SIZEOF,"SIZEOF",
121 ADDR,"ADDR",
122 MEMORY,"MEMORY",
123 DSECT,"DSECT",
124 NOLOAD,"NOLOAD",
125 COPY,"COPY",
126 INFO,"INFO",
127 OVERLAY,"OVERLAY",
128 DEFINED,"DEFINED",
129 TARGET_K,"TARGET",
130 SEARCH_DIR,"SEARCH_DIR",
131 MAP,"MAP",
132 LONG,"LONG",
133 SHORT,"SHORT",
134 BYTE,"BYTE",
135 ENTRY,"ENTRY",
136 0,(char *)NULL} ;
137
138
139
140 unsigned int idx;
141 for (idx = 0; table[idx].name != (char*)NULL; idx++) {
142 if (table[idx].code == code) {
143 fprintf(outfile, "%s", table[idx].name);
144 return;
145 }
146 }
147 /* Not in table, just print it alone */
148 fprintf(outfile, "%c",code);
149}
150
151static void
152make_abs(ptr)
153etree_value_type *ptr;
154{
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;
159 }
160
161}
162static
163etree_value_type new_abs(value)
164bfd_vma value;
165{
166 etree_value_type new;
167 new.valid = true;
168 new.section = (lang_output_section_statement_type *)NULL;
169 new.value = value;
170 return new;
171}
172
173static void check(os)
174lang_output_section_statement_type *os;
175{
176 if (os == (lang_output_section_statement_type *)NULL) {
177 info("%F%P undefined section");
178 }
179 if (os->processed == false) {
180 info("%F%P forward reference of section");
181 }
182}
183
184etree_type *exp_intop(value)
185bfd_vma value;
186{
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;
191 return new;
192
193}
194
195
196static
197etree_value_type new_rel(value, section)
198bfd_vma value;
199lang_output_section_statement_type *section;
200{
201 etree_value_type new;
202 new.valid = true;
203 new.value = value;
204 new.section = section;
205 return new;
206}
207
208static
209etree_value_type new_rel_from_section(value, section)
210bfd_vma value;
211lang_output_section_statement_type *section;
212{
213 etree_value_type new;
214 new.valid = true;
215 new.value = value;
216 new.section = section;
217 if (new.section != (lang_output_section_statement_type *)NULL) {
218 new.value -= section->bfd_section->vma;
219 }
220 return new;
221}
222
223static etree_value_type
224fold_binary(tree, current_section, allocation_done, dot, dotp)
225etree_type *tree;
226lang_output_section_statement_type *current_section;
227lang_phase_type allocation_done;
228bfd_vma dot;
229bfd_vma *dotp;
230{
231 etree_value_type result;
232
233 result = exp_fold_tree(tree->binary.lhs, current_section,
234 allocation_done, dot, dotp);
235 if (result.valid) {
236 etree_value_type other;
237 other = exp_fold_tree(tree->binary.rhs,
238 current_section,
239 allocation_done, dot,dotp) ;
240 if (other.valid) {
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) {
245
246 make_abs(&result);
247 make_abs(&other);
248 }
249
250 switch (tree->type.node_code)
251 {
252 case '%':
253 /* Mod, both absolule*/
254
255 if (other.value == 0) {
256 info("%F%S % by zero\n");
257 }
258 result.value %= other.value;
259 break;
260 case '/':
261 if (other.value == 0) {
262 info("%F%S / by zero\n");
263 }
264 result.value /= other.value;
265 break;
266#define BOP(x,y) case x : result.value = result.value y other.value;break;
267 BOP('+',+);
268 BOP('*',*);
269 BOP('-',-);
270 BOP(LSHIFT,<<);
271 BOP(RSHIFT,>>);
272 BOP(EQ,==);
273 BOP(NE,!=);
274 BOP('<',<);
275 BOP('>',>);
276 BOP(LE,<=);
277 BOP(GE,>=);
278 BOP('&',&);
279 BOP('^',^);
280 BOP('|',|);
281 BOP(ANDAND,&&);
282 BOP(OROR,||);
283 default:
284 FAIL();
285 }
286 }
287 }
288 return result;
289}
290etree_value_type invalid()
291{
292 etree_value_type new;
293 new.valid = false;
294 return new;
295}
296
297etree_value_type fold_name(tree, current_section, allocation_done, dot)
298etree_type *tree;
299lang_output_section_statement_type *current_section;
300lang_phase_type allocation_done;
301bfd_vma dot;
302
303{
304 etree_value_type result;
305 switch (tree->type.node_code)
306 {
307 case DEFINED:
308 result.value =
309 ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
310 result.section = 0;
311 result.valid = true;
312 break;
313 case NAME:
314 result.valid = false;
315 if (tree->name.name[0] == '.' && tree->name.name[1] == 0) {
316
317 if (allocation_done != lang_first_phase_enum) {
318 result = new_rel_from_section(dot, current_section);
319 }
320 else {
321 result = invalid();
322 }
323 }
324 else {
325 if (allocation_done == lang_final_phase_enum) {
326 ldsym_type *sy = ldsym_get_soft(tree->name.name);
327
328 if (sy) {
329 asymbol **sdefp = sy->sdefs_chain;
330
331 if (sdefp) {
332 asymbol *sdef = *sdefp;
333 if (sdef->section == (asection *)NULL) {
334 /* This is an absolute symbol */
335 result = new_abs(sdef->value);
336 }
337 else {
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);
341 }
342 }
343 }
344 if (result.valid == false) {
345 info("%F%S: undefined symbol `%s' referenced in expression.\n",
346 tree->name.name);
347 }
348
349 }
350 }
351
352 break;
353
354 case ADDR:
355
356 if (allocation_done != lang_first_phase_enum) {
357 lang_output_section_statement_type *os =
358 lang_output_section_find(tree->name.name);
359 check(os);
360 result = new_rel((bfd_vma)0, os);
361 }
362 else {
363 result = invalid();
364 }
365 break;
366 case SIZEOF:
367 if(allocation_done != lang_first_phase_enum) {
368 lang_output_section_statement_type *os =
369 lang_output_section_find(tree->name.name);
370 check(os);
371 result = new_abs((bfd_vma)(os->bfd_section->size));
372 }
373 else {
374 result = invalid();
375 }
376 break;
377
378 default:
379 FAIL();
380 break;
381 }
382
383 return result;
384}
385etree_value_type exp_fold_tree(tree, current_section, allocation_done,
386 dot, dotp)
387etree_type *tree;
388lang_output_section_statement_type *current_section;
389lang_phase_type allocation_done;
390bfd_vma dot;
391bfd_vma *dotp;
392{
393 etree_value_type result;
394
395 if (tree == (etree_type *)NULL) {
396 result.valid = false;
397 }
398 else {
399 switch (tree->type.node_class)
400 {
401 case etree_value:
402 result = new_rel(tree->value.value, current_section);
403 break;
404 case etree_unary:
405 result = exp_fold_tree(tree->unary.child,
406 current_section,
407 allocation_done, dot, dotp);
408 if (result.valid == true)
409 {
410 switch(tree->type.node_code)
411 {
412 case ALIGN_K:
413 if (allocation_done != lang_first_phase_enum) {
414 result = new_rel_from_section(ALIGN(dot,
415 result.value) ,
416 current_section);
417
418 }
419 else {
420 result.valid = false;
421 }
422 break;
423 case '-':
424 result.value = -result.value;
425 break;
426 case NEXT:
427 result.valid = false;
428 break;
429 default:
430 FAIL();
431 }
432 }
433
434 break;
435 case etree_trinary:
436
437 result = exp_fold_tree(tree->trinary.cond,
438 current_section,
439 allocation_done, dot, dotp);
440 if (result.valid) {
441 result = exp_fold_tree(result.value ?
442 tree->trinary.lhs:tree->trinary.rhs,
443 current_section,
444 allocation_done, dot, dotp);
445 }
446
447 break;
448 case etree_binary:
449 result = fold_binary(tree, current_section, allocation_done,
450 dot, dotp);
451 break;
452 case etree_assign:
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,
457 current_section,
458 lang_allocating_phase_enum, dot, dotp);
459 if (result.valid == false) {
460 info("%F%S invalid assignment to location counter\n");
461 }
462 else {
463 if (current_section ==
464 (lang_output_section_statement_type *)NULL) {
465 info("%F%S assignment to location counter invalid outside of SECTION\n");
466 }
467 else {
468 unsigned long nextdot =result.value +
469 current_section->bfd_section->vma;
470 if (nextdot < dot) {
471 info("%F%S cannot move location counter backwards");
472 }
473 else {
474 *dotp = nextdot;
475 }
476 }
477 }
478 }
479 }
480 else {
481 ldsym_type *sy = ldsym_get(tree->assign.dst);
482
483 /* If this symbol has just been created then we'll place it into
484 * a section of our choice
485 */
486 result = exp_fold_tree(tree->assign.src,
487 current_section, allocation_done,
488 dot, dotp);
489 if (result.valid)
490 {
491 asymbol *def;
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);
495 *def_ptr = def;
496
497
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) {
503
504 def->section = result.section->bfd_section;
505 def->flags = BSF_GLOBAL | BSF_EXPORT;
506 }
507 else {
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;
512 }
513
514
515 }
516 else {
517 def->section = (asection *)NULL;
518 def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
519 }
520
521
522 def->udata = (void *)NULL;
523 def->name = sy->name;
524 Q_enter_global_ref(def_ptr);
525 }
526
527 }
528
529
530 break;
531 case etree_name:
532 result = fold_name(tree, current_section, allocation_done, dot);
533 break;
534 default:
535 info("%F%S Need more of these %d",tree->type.node_class );
536
537 }
538 }
539
540 return result;
541}
542
543
544etree_value_type exp_fold_tree_no_dot(tree, current_section, allocation_done)
545etree_type *tree;
546lang_output_section_statement_type *current_section;
547lang_phase_type allocation_done;
548{
549return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
550 0, (bfd_vma *)NULL);
551}
552
553etree_type *
554exp_binop(code, lhs, rhs)
555int code;
556etree_type *lhs;
557etree_type *rhs;
558{
559 etree_type value, *new;
560 etree_value_type r;
561
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 );
568 if (r.valid)
569 {
570 return exp_intop(r.value);
571 }
572 new = (etree_type *)ldmalloc(sizeof(new->binary));
573 memcpy((char *)new, (char *)&value, sizeof(new->binary));
574 return new;
575}
576
577etree_type *
578exp_trinop(code, cond, lhs, rhs)
579int code;
580etree_type *cond;
581etree_type *lhs;
582etree_type *rhs;
583{
584 etree_type value, *new;
585 etree_value_type r;
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);
593 if (r.valid) {
594 return exp_intop(r.value);
595 }
596 new = (etree_type *)ldmalloc(sizeof(new->trinary));
597 memcpy((char *)new,(char *) &value, sizeof(new->trinary));
598 return new;
599}
600
601
602etree_type *
603exp_unop(code, child)
604int code;
605etree_type *child;
606{
607 etree_type value, *new;
608
609 etree_value_type r;
610 value.unary.type.node_code = code;
611 value.unary.child = child;
612 value.unary.type.node_class = etree_unary;
613r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
614 lang_first_phase_enum);
615if (r.valid) {
616 return exp_intop(r.value);
617 }
618 new = (etree_type *)ldmalloc(sizeof(new->unary));
619 memcpy((char *)new, (char *)&value, sizeof(new->unary));
620 return new;
621}
622
623
624etree_type *
625exp_nameop(code, name)
626int code;
627char *name;
628{
629
630 etree_type value, *new;
631
632 etree_value_type r;
633 value.name.type.node_code = code;
634 value.name.name = name;
635 value.name.type.node_class = etree_name;
636
637
638 r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
639 lang_first_phase_enum);
640 if (r.valid) {
641 return exp_intop(r.value);
642 }
643 new = (etree_type *)ldmalloc(sizeof(new->name));
644 memcpy((char *)new, (char *)&value, sizeof(new->name));
645 return new;
646
647}
648
649
650
651
652etree_type *
653exp_assop(code, dst, src)
654int code;
655char *dst;
656etree_type *src;
657{
658 etree_type value, *new;
659
660 value.assign.type.node_code = code;
661
662
663 value.assign.src = src;
664 value.assign.dst = dst;
665 value.assign.type.node_class = etree_assign;
666
667#if 0
668 if (exp_fold_tree_no_dot(&value, &result)) {
669 return exp_intop(result);
670 }
671#endif
672 new = (etree_type*)ldmalloc(sizeof(new->assign));
673 memcpy((char *)new, (char *)&value, sizeof(new->assign));
674 return new;
675}
676
677void
678exp_print_tree(outfile, tree)
679FILE *outfile;
680etree_type *tree;
681{
682 switch (tree->type.node_class) {
683 case etree_value:
684 fprintf(outfile,"0x%08lx",(bfd_vma)(tree->value.value));
685 return;
686 case etree_assign:
687#if 0
688 if (tree->assign.dst->sdefs != (asymbol *)NULL){
689 fprintf(outfile,"%s (%x) ",tree->assign.dst->name,
690 tree->assign.dst->sdefs->value);
691 }
692 else {
693 fprintf(outfile,"%s (UNDEFINED)",tree->assign.dst->name);
694 }
695#endif
696 fprintf(outfile,"%s ",tree->assign.dst);
697 exp_print_token(outfile,tree->type.node_code);
698 exp_print_tree(outfile,tree->assign.src);
699 break;
700 case etree_binary:
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);
704 break;
705 case etree_trinary:
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);
711 break;
712 case etree_unary:
713 exp_print_token(outfile,tree->unary.type.node_code);
714 fprintf(outfile,"(");
715 exp_print_tree(outfile,tree->unary.child);
716 fprintf(outfile,")");
717 break;
718 case etree_undef:
719 fprintf(outfile,"????????");
720 break;
721 case etree_name:
722 if (tree->type.node_code == NAME) {
723 fprintf(outfile,"%s", tree->name.name);
724 }
725 else {
726 exp_print_token(outfile,tree->type.node_code);
727 fprintf(outfile,"(%s)", tree->name.name);
728 }
729 break;
730 default:
731 FAIL();
732 break;
733 }
734}
735
736
737
738
739bfd_vma
740exp_get_vma(tree, def, name, allocation_done)
741etree_type *tree;
742bfd_vma def;
743char *name;
744lang_phase_type allocation_done;
745{
746 etree_value_type r;
747
748 if (tree != (etree_type *)NULL) {
749 r = exp_fold_tree_no_dot(tree,
750 (lang_output_section_statement_type *)NULL,
751 allocation_done);
752 if (r.valid == false && name) {
753 info("%F%S Nonconstant expression for %s\n",name);
754 }
755 return r.value;
756 }
757 else {
758 return def;
759 }
760}
761
762int
763exp_get_value_int(tree,def,name, allocation_done)
764etree_type *tree;
765int def;
766char *name;
767lang_phase_type allocation_done;
768{
769 return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
770}
This page took 0.049153 seconds and 4 git commands to generate.