CVS says it was empty, so refresh it.
[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$
2fa0b342
DHW
21*/
22
23/*
24 * Written by Steve Chamberlain
25 * steve@cygnus.com
26 *
27 * This module handles expression trees.
28 */
29
30
31#include "sysdep.h"
32#include "bfd.h"
33
34#include "ld.h"
35#include "ldmain.h"
36#include "ldmisc.h"
37#include "ldexp.h"
38#include "ldgram.tab.h"
39#include "ldsym.h"
40#include "ldlang.h"
41
42extern char *output_filename;
43extern unsigned int undefined_global_sym_count;
44extern unsigned int defined_global_sym_count;
45extern bfd *output_bfd;
46extern size_t largest_section;
47extern lang_statement_list_type file_chain;
48extern args_type command_line;
49extern ld_config_type config;
50
51extern lang_input_statement_type *script_file;
52extern unsigned int defined_global_sym_count;
53
54extern bfd_vma print_dot;
55
56
57static void
58exp_print_token(outfile, code)
59FILE *outfile;
60token_code_type code;
61{
62 static struct {
63 token_code_type code;
64 char *name;
65 } table[] =
66 {
67 INT, "int",
2fa0b342
DHW
68 NAME,"NAME",
69 PLUSEQ,"+=",
70 MINUSEQ,"-=",
71 MULTEQ,"*=",
72 DIVEQ,"/=",
73 LSHIFTEQ,"<<=",
74 RSHIFTEQ,">>=",
75 ANDEQ,"&=",
76 OREQ,"|=",
77 OROR,"||",
78 ANDAND,"&&",
79 EQ,"==",
80 NE,"!=",
81 LE,"<=",
82 GE,">=",
83 LSHIFT,"<<",
84 RSHIFT,">>=",
85 ALIGN_K,"ALIGN",
86 BLOCK,"BLOCK",
87 SECTIONS,"SECTIONS",
2fa0b342
DHW
88 SIZEOF_HEADERS,"SIZEOF_HEADERS",
89 NEXT,"NEXT",
90 SIZEOF,"SIZEOF",
91 ADDR,"ADDR",
92 MEMORY,"MEMORY",
6812f0e8
SC
93
94
95
96
97
2fa0b342
DHW
98 DEFINED,"DEFINED",
99 TARGET_K,"TARGET",
100 SEARCH_DIR,"SEARCH_DIR",
101 MAP,"MAP",
102 LONG,"LONG",
103 SHORT,"SHORT",
104 BYTE,"BYTE",
105 ENTRY,"ENTRY",
106 0,(char *)NULL} ;
107
108
109
110 unsigned int idx;
111 for (idx = 0; table[idx].name != (char*)NULL; idx++) {
112 if (table[idx].code == code) {
113 fprintf(outfile, "%s", table[idx].name);
114 return;
115 }
116 }
117 /* Not in table, just print it alone */
118 fprintf(outfile, "%c",code);
119}
120
121static void
122make_abs(ptr)
123etree_value_type *ptr;
124{
125 if (ptr->section != (lang_output_section_statement_type *)NULL) {
126 asection *s = ptr->section->bfd_section;
127 ptr->value += s->vma;
128 ptr->section = (lang_output_section_statement_type *)NULL;
129 }
130
131}
132static
133etree_value_type new_abs(value)
134bfd_vma value;
135{
136 etree_value_type new;
137 new.valid = true;
138 new.section = (lang_output_section_statement_type *)NULL;
139 new.value = value;
140 return new;
141}
142
3a399523
SC
143static void
144DEFUN(check, (os, name, op),
145 lang_output_section_statement_type *os AND
146 CONST char *name AND
147 CONST char *op)
2fa0b342
DHW
148{
149 if (os == (lang_output_section_statement_type *)NULL) {
3a399523 150 info("%F%P %s uses undefined section %s\n", op, name);
2fa0b342
DHW
151 }
152 if (os->processed == false) {
3a399523 153 info("%F%P %s forward reference of section %s\n",op, name);
2fa0b342
DHW
154 }
155}
156
157etree_type *exp_intop(value)
158bfd_vma value;
159{
160 etree_type *new = (etree_type *)ldmalloc(sizeof(new->value));
161 new->type.node_code = INT;
162 new->value.value = value;
163 new->type.node_class = etree_value;
164 return new;
165
166}
167
168
169static
170etree_value_type new_rel(value, section)
171bfd_vma value;
172lang_output_section_statement_type *section;
173{
174 etree_value_type new;
175 new.valid = true;
176 new.value = value;
177 new.section = section;
178 return new;
179}
180
181static
182etree_value_type new_rel_from_section(value, section)
183bfd_vma value;
184lang_output_section_statement_type *section;
185{
186 etree_value_type new;
187 new.valid = true;
188 new.value = value;
189 new.section = section;
190 if (new.section != (lang_output_section_statement_type *)NULL) {
191 new.value -= section->bfd_section->vma;
192 }
193 return new;
194}
195
196static etree_value_type
197fold_binary(tree, current_section, allocation_done, dot, dotp)
198etree_type *tree;
199lang_output_section_statement_type *current_section;
200lang_phase_type allocation_done;
201bfd_vma dot;
202bfd_vma *dotp;
203{
204 etree_value_type result;
205
206 result = exp_fold_tree(tree->binary.lhs, current_section,
207 allocation_done, dot, dotp);
208 if (result.valid) {
209 etree_value_type other;
210 other = exp_fold_tree(tree->binary.rhs,
211 current_section,
212 allocation_done, dot,dotp) ;
213 if (other.valid) {
214 /* If values are from different sections, or this is an */
215 /* absolute expression, make both source args absolute */
216 if (result.section != other.section ||
217 current_section == (lang_output_section_statement_type *)NULL) {
218
219 make_abs(&result);
220 make_abs(&other);
221 }
222
223 switch (tree->type.node_code)
224 {
225 case '%':
226 /* Mod, both absolule*/
227
228 if (other.value == 0) {
229 info("%F%S % by zero\n");
230 }
231 result.value %= other.value;
232 break;
233 case '/':
234 if (other.value == 0) {
235 info("%F%S / by zero\n");
236 }
237 result.value /= other.value;
238 break;
239#define BOP(x,y) case x : result.value = result.value y other.value;break;
240 BOP('+',+);
241 BOP('*',*);
242 BOP('-',-);
243 BOP(LSHIFT,<<);
244 BOP(RSHIFT,>>);
245 BOP(EQ,==);
246 BOP(NE,!=);
247 BOP('<',<);
248 BOP('>',>);
249 BOP(LE,<=);
250 BOP(GE,>=);
251 BOP('&',&);
252 BOP('^',^);
253 BOP('|',|);
254 BOP(ANDAND,&&);
255 BOP(OROR,||);
256 default:
257 FAIL();
258 }
259 }
070aa819
SC
260 else {
261 result.valid = false;
262 }
2fa0b342
DHW
263 }
264 return result;
265}
266etree_value_type invalid()
267{
268 etree_value_type new;
269 new.valid = false;
270 return new;
271}
272
273etree_value_type fold_name(tree, current_section, allocation_done, dot)
274etree_type *tree;
275lang_output_section_statement_type *current_section;
276lang_phase_type allocation_done;
277bfd_vma dot;
278
279{
280 etree_value_type result;
281 switch (tree->type.node_code)
ac004870 282 {
65c552e3
SC
283 case SIZEOF_HEADERS:
284 if (allocation_done != lang_first_phase_enum)
285 {
286 result = new_abs(bfd_sizeof_headers(output_bfd,
287 config.relocateable_output));
288
289 }
290 else {
291 result.valid = false;
292 }
293 break;
ac004870
SC
294 case DEFINED:
295 result.value =
296 ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
297 result.section = 0;
298 result.valid = true;
299 break;
300 case NAME:
301 result.valid = false;
302 if (tree->name.name[0] == '.' && tree->name.name[1] == 0) {
303
304 if (allocation_done != lang_first_phase_enum) {
305 result = new_rel_from_section(dot, current_section);
306 }
307 else {
308 result = invalid();
309 }
2fa0b342
DHW
310 }
311 else {
ac004870
SC
312 if (allocation_done == lang_final_phase_enum) {
313 ldsym_type *sy = ldsym_get_soft(tree->name.name);
2fa0b342 314
ac004870
SC
315 if (sy) {
316 asymbol **sdefp = sy->sdefs_chain;
317
318 if (sdefp) {
319 asymbol *sdef = *sdefp;
320 if (sdef->section == (asection *)NULL) {
321 /* This is an absolute symbol */
322 result = new_abs(sdef->value);
323 }
324 else {
325 lang_output_section_statement_type *os =
326 lang_output_section_statement_lookup(
327 sdef->section->output_section->name);
328 /* If the symbol is from a file which we are not
329 relocating (-R) then return an absolute for its
330 value */
331 if (sdef->the_bfd->usrdata &&
332 ((lang_input_statement_type*)(sdef->the_bfd->usrdata))->just_syms_flag == true)
333 {
b0f36869 334 result = new_abs(sdef->value + (sdef->section ?
65c552e3 335 sdef->section->vma : 0));
ac004870
SC
336 }
337 else {
a37cc0c0 338 result = new_rel(sdef->value + sdef->section->output_offset, os);
ac004870
SC
339 }
340 }
2fa0b342
DHW
341 }
342 }
ac004870
SC
343 if (result.valid == false) {
344 info("%F%S: undefined symbol `%s' referenced in expression.\n",
2fa0b342 345 tree->name.name);
ac004870 346 }
2fa0b342 347
ac004870 348 }
2fa0b342 349 }
2fa0b342 350
ac004870 351 break;
2fa0b342 352
ac004870 353 case ADDR:
2fa0b342 354
ac004870
SC
355 if (allocation_done != lang_first_phase_enum) {
356 lang_output_section_statement_type *os =
357 lang_output_section_find(tree->name.name);
358 check(os,tree->name.name,"ADDR");
359 result = new_rel((bfd_vma)0, os);
360 }
361 else {
362 result = invalid();
363 }
364 break;
365 case SIZEOF:
366 if(allocation_done != lang_first_phase_enum) {
367 lang_output_section_statement_type *os =
368 lang_output_section_find(tree->name.name);
369 check(os,tree->name.name,"SIZEOF");
370 result = new_abs((bfd_vma)(os->bfd_section->size));
371 }
372 else {
373 result = invalid();
374 }
375 break;
2fa0b342 376
ac004870
SC
377 default:
378 FAIL();
379 break;
380 }
2fa0b342
DHW
381
382 return result;
383}
384etree_value_type exp_fold_tree(tree, current_section, allocation_done,
385 dot, dotp)
386etree_type *tree;
387lang_output_section_statement_type *current_section;
388lang_phase_type allocation_done;
389bfd_vma dot;
390bfd_vma *dotp;
391{
392 etree_value_type result;
393
394 if (tree == (etree_type *)NULL) {
395 result.valid = false;
396 }
397 else {
398 switch (tree->type.node_class)
d4c02e29
SC
399 {
400 case etree_value:
401 result = new_rel(tree->value.value, current_section);
402 break;
403 case etree_unary:
404 result = exp_fold_tree(tree->unary.child,
405 current_section,
406 allocation_done, dot, dotp);
407 if (result.valid == true)
2fa0b342 408 {
d4c02e29
SC
409 switch(tree->type.node_code)
410 {
411 case ALIGN_K:
412 if (allocation_done != lang_first_phase_enum) {
413 result = new_rel_from_section(ALIGN(dot,
414 result.value) ,
415 current_section);
416
417 }
418 else {
419 result.valid = false;
420 }
421 break;
422 case '~':
423 make_abs(&result);
424 result.value = ~result.value;
425 break;
426 case '!':
427 make_abs(&result);
428 result.value = !result.value;
429 break;
430 case '-':
431 make_abs(&result);
432 result.value = -result.value;
433 break;
434 case NEXT:
65c552e3
SC
435 if (allocation_done ==lang_allocating_phase_enum) {
436 make_abs(&result);
437 result.value = ALIGN(dot, result.value);
438 }
439 else {
440 /* Return next place aligned to value */
d4c02e29 441 result.valid = false;
65c552e3 442 }
d4c02e29
SC
443 break;
444 default:
445 FAIL();
446 }
2fa0b342 447 }
2fa0b342 448
d4c02e29
SC
449 break;
450 case etree_trinary:
2fa0b342 451
d4c02e29 452 result = exp_fold_tree(tree->trinary.cond,
2fa0b342
DHW
453 current_section,
454 allocation_done, dot, dotp);
d4c02e29
SC
455 if (result.valid) {
456 result = exp_fold_tree(result.value ?
457 tree->trinary.lhs:tree->trinary.rhs,
2fa0b342 458 current_section,
d4c02e29
SC
459 allocation_done, dot, dotp);
460 }
461
462 break;
463 case etree_binary:
464 result = fold_binary(tree, current_section, allocation_done,
465 dot, dotp);
466 break;
467 case etree_assign:
468 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
469 /* Assignment to dot can only be done during allocation */
470 if (allocation_done == lang_allocating_phase_enum) {
471 result = exp_fold_tree(tree->assign.src,
472 current_section,
473 lang_allocating_phase_enum, dot, dotp);
474 if (result.valid == false) {
475 info("%F%S invalid assignment to location counter\n");
2fa0b342
DHW
476 }
477 else {
d4c02e29
SC
478 if (current_section ==
479 (lang_output_section_statement_type *)NULL) {
480 info("%F%S assignment to location counter invalid outside of SECTION\n");
2fa0b342
DHW
481 }
482 else {
d4c02e29
SC
483 unsigned long nextdot =result.value +
484 current_section->bfd_section->vma;
485 if (nextdot < dot) {
486 info("%F%S cannot move location counter backwards");
487 }
488 else {
489 *dotp = nextdot;
490 }
2fa0b342
DHW
491 }
492 }
493 }
494 }
d4c02e29
SC
495 else {
496 ldsym_type *sy = ldsym_get(tree->assign.dst);
497
498 /* If this symbol has just been created then we'll place it into
499 * a section of our choice
500 */
501 result = exp_fold_tree(tree->assign.src,
502 current_section, allocation_done,
503 dot, dotp);
504 if (result.valid)
505 {
506 asymbol *def;
507 asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **));
508 /* Add this definition to script file */
509 def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd);
510 *def_ptr = def;
511
512
513 def->value = result.value;
514 if (result.section !=
515 (lang_output_section_statement_type *)NULL) {
516 if (current_section !=
517 (lang_output_section_statement_type *)NULL) {
2fa0b342 518
d4c02e29
SC
519 def->section = result.section->bfd_section;
520 def->flags = BSF_GLOBAL | BSF_EXPORT;
521 }
522 else {
523 /* Force to absolute */
524 def->value += result.section->bfd_section->vma;
525 def->section = (asection *)NULL;
526 def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
527 }
528
529
530 }
531 else {
532 def->section = (asection *)NULL;
533 def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
534 }
535
536
537 def->udata = (PTR)NULL;
538 def->name = sy->name;
539 Q_enter_global_ref(def_ptr);
2fa0b342 540 }
2fa0b342 541
d4c02e29 542 }
2fa0b342
DHW
543
544
d4c02e29
SC
545 break;
546 case etree_name:
547 result = fold_name(tree, current_section, allocation_done, dot);
548 break;
549 default:
550 info("%F%S Need more of these %d",tree->type.node_class );
2fa0b342 551
d4c02e29 552 }
2fa0b342
DHW
553 }
554
555 return result;
556}
557
558
559etree_value_type exp_fold_tree_no_dot(tree, current_section, allocation_done)
560etree_type *tree;
561lang_output_section_statement_type *current_section;
562lang_phase_type allocation_done;
563{
564return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
565 0, (bfd_vma *)NULL);
566}
567
568etree_type *
569exp_binop(code, lhs, rhs)
570int code;
571etree_type *lhs;
572etree_type *rhs;
573{
574 etree_type value, *new;
575 etree_value_type r;
576
577 value.type.node_code = code;
578 value.binary.lhs = lhs;
579 value.binary.rhs = rhs;
580 value.type.node_class = etree_binary;
581 r = exp_fold_tree_no_dot(&value, (lang_output_section_statement_type *)NULL,
582 lang_first_phase_enum );
583 if (r.valid)
584 {
585 return exp_intop(r.value);
586 }
587 new = (etree_type *)ldmalloc(sizeof(new->binary));
588 memcpy((char *)new, (char *)&value, sizeof(new->binary));
589 return new;
590}
591
592etree_type *
593exp_trinop(code, cond, lhs, rhs)
594int code;
595etree_type *cond;
596etree_type *lhs;
597etree_type *rhs;
598{
599 etree_type value, *new;
600 etree_value_type r;
601 value.type.node_code = code;
602 value.trinary.lhs = lhs;
603 value.trinary.cond = cond;
604 value.trinary.rhs = rhs;
605 value.type.node_class = etree_trinary;
606 r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type
607 *)NULL,lang_first_phase_enum);
608 if (r.valid) {
609 return exp_intop(r.value);
610 }
611 new = (etree_type *)ldmalloc(sizeof(new->trinary));
612 memcpy((char *)new,(char *) &value, sizeof(new->trinary));
613 return new;
614}
615
616
617etree_type *
618exp_unop(code, child)
619int code;
620etree_type *child;
621{
622 etree_type value, *new;
623
624 etree_value_type r;
625 value.unary.type.node_code = code;
626 value.unary.child = child;
627 value.unary.type.node_class = etree_unary;
628r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
629 lang_first_phase_enum);
630if (r.valid) {
631 return exp_intop(r.value);
632 }
633 new = (etree_type *)ldmalloc(sizeof(new->unary));
634 memcpy((char *)new, (char *)&value, sizeof(new->unary));
635 return new;
636}
637
638
639etree_type *
640exp_nameop(code, name)
641int code;
642char *name;
643{
644
645 etree_type value, *new;
646
647 etree_value_type r;
648 value.name.type.node_code = code;
649 value.name.name = name;
650 value.name.type.node_class = etree_name;
651
652
653 r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
654 lang_first_phase_enum);
655 if (r.valid) {
656 return exp_intop(r.value);
657 }
658 new = (etree_type *)ldmalloc(sizeof(new->name));
659 memcpy((char *)new, (char *)&value, sizeof(new->name));
660 return new;
661
662}
663
664
665
666
667etree_type *
668exp_assop(code, dst, src)
669int code;
670char *dst;
671etree_type *src;
672{
673 etree_type value, *new;
674
675 value.assign.type.node_code = code;
676
677
678 value.assign.src = src;
679 value.assign.dst = dst;
680 value.assign.type.node_class = etree_assign;
681
682#if 0
683 if (exp_fold_tree_no_dot(&value, &result)) {
684 return exp_intop(result);
685 }
686#endif
687 new = (etree_type*)ldmalloc(sizeof(new->assign));
688 memcpy((char *)new, (char *)&value, sizeof(new->assign));
689 return new;
690}
691
692void
693exp_print_tree(outfile, tree)
694FILE *outfile;
695etree_type *tree;
696{
697 switch (tree->type.node_class) {
698 case etree_value:
699 fprintf(outfile,"0x%08lx",(bfd_vma)(tree->value.value));
700 return;
701 case etree_assign:
702#if 0
703 if (tree->assign.dst->sdefs != (asymbol *)NULL){
704 fprintf(outfile,"%s (%x) ",tree->assign.dst->name,
705 tree->assign.dst->sdefs->value);
706 }
707 else {
708 fprintf(outfile,"%s (UNDEFINED)",tree->assign.dst->name);
709 }
710#endif
711 fprintf(outfile,"%s ",tree->assign.dst);
712 exp_print_token(outfile,tree->type.node_code);
713 exp_print_tree(outfile,tree->assign.src);
714 break;
715 case etree_binary:
716 exp_print_tree(outfile,tree->binary.lhs);
717 exp_print_token(outfile,tree->type.node_code);
718 exp_print_tree(outfile,tree->binary.rhs);
719 break;
720 case etree_trinary:
721 exp_print_tree(outfile,tree->trinary.cond);
722 fprintf(outfile,"?");
723 exp_print_tree(outfile,tree->trinary.lhs);
724 fprintf(outfile,":");
725 exp_print_tree(outfile,tree->trinary.rhs);
726 break;
727 case etree_unary:
728 exp_print_token(outfile,tree->unary.type.node_code);
729 fprintf(outfile,"(");
730 exp_print_tree(outfile,tree->unary.child);
731 fprintf(outfile,")");
732 break;
733 case etree_undef:
734 fprintf(outfile,"????????");
735 break;
736 case etree_name:
737 if (tree->type.node_code == NAME) {
738 fprintf(outfile,"%s", tree->name.name);
739 }
740 else {
741 exp_print_token(outfile,tree->type.node_code);
742 fprintf(outfile,"(%s)", tree->name.name);
743 }
744 break;
745 default:
746 FAIL();
747 break;
748 }
749}
750
751
752
753
754bfd_vma
755exp_get_vma(tree, def, name, allocation_done)
756etree_type *tree;
757bfd_vma def;
758char *name;
759lang_phase_type allocation_done;
760{
761 etree_value_type r;
762
763 if (tree != (etree_type *)NULL) {
764 r = exp_fold_tree_no_dot(tree,
765 (lang_output_section_statement_type *)NULL,
766 allocation_done);
767 if (r.valid == false && name) {
768 info("%F%S Nonconstant expression for %s\n",name);
769 }
770 return r.value;
771 }
772 else {
773 return def;
774 }
775}
776
777int
778exp_get_value_int(tree,def,name, allocation_done)
779etree_type *tree;
780int def;
781char *name;
782lang_phase_type allocation_done;
783{
784 return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
785}
65c552e3 786
This page took 0.143982 seconds and 4 git commands to generate.