* README: Add notes on how to build if you don't have ar.
[deliverable/binutils-gdb.git] / ld / ldexp.c
CommitLineData
c611e285 1/* This module handles expression trees.
1abb243d 2Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
c611e285 3Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
2fa0b342
DHW
4
5This file is part of GLD, the Gnu Linker.
6
7GLD is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
c611e285 9the Free Software Foundation; either version 2, or (at your option)
2fa0b342
DHW
10any later version.
11
12GLD is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GLD; see the file COPYING. If not, write to
e3e69b13 19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2fa0b342
DHW
20
21/*
c611e285 22This module is in charge of working out the contents of expressions.
2fa0b342 23
c611e285
SC
24It has to keep track of the relative/absness of a symbol etc. This is
25done by keeping all values in a struct (an etree_value_type) which
26contains a value, a section to which it is relative and a valid bit.
27
28*/
2fa0b342
DHW
29
30
2fa0b342 31#include "bfd.h"
c611e285 32#include "sysdep.h"
31ddb156 33#include "bfdlink.h"
2fa0b342
DHW
34
35#include "ld.h"
36#include "ldmain.h"
37#include "ldmisc.h"
38#include "ldexp.h"
c611e285 39#include "ldgram.h"
2fa0b342
DHW
40#include "ldlang.h"
41
31ddb156
ILT
42static void exp_print_token PARAMS ((token_code_type code));
43static void make_abs PARAMS ((etree_value_type *ptr));
44static etree_value_type new_abs PARAMS ((bfd_vma value));
45static void check PARAMS ((lang_output_section_statement_type *os,
46 const char *name, const char *op));
47static etree_value_type new_rel
48 PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
49static etree_value_type new_rel_from_section
50 PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
51static etree_value_type fold_binary
52 PARAMS ((etree_type *tree,
53 lang_output_section_statement_type *current_section,
54 lang_phase_type allocation_done,
55 bfd_vma dot, bfd_vma *dotp));
56static etree_value_type fold_name
57 PARAMS ((etree_type *tree,
58 lang_output_section_statement_type *current_section,
59 lang_phase_type allocation_done,
60 bfd_vma dot));
61static etree_value_type exp_fold_tree_no_dot
62 PARAMS ((etree_type *tree,
63 lang_output_section_statement_type *current_section,
64 lang_phase_type allocation_done));
65
2fa0b342 66static void
8bf66be8
DM
67exp_print_token (code)
68 token_code_type code;
2fa0b342 69{
31ddb156
ILT
70 static CONST struct
71 {
72 token_code_type code;
73 char *name;
74 } table[] =
c611e285 75 {
31ddb156
ILT
76 { INT, "int" },
77 { REL, "relocateable" },
78 { NAME,"NAME" },
79 { PLUSEQ,"+=" },
80 { MINUSEQ,"-=" },
81 { MULTEQ,"*=" },
82 { DIVEQ,"/=" },
83 { LSHIFTEQ,"<<=" },
84 { RSHIFTEQ,">>=" },
85 { ANDEQ,"&=" },
86 { OREQ,"|=" },
87 { OROR,"||" },
88 { ANDAND,"&&" },
89 { EQ,"==" },
90 { NE,"!=" },
91 { LE,"<=" },
92 { GE,">=" },
93 { LSHIFT,"<<" },
94 { RSHIFT,">>=" },
95 { ALIGN_K,"ALIGN" },
96 { BLOCK,"BLOCK" },
97 { SECTIONS,"SECTIONS" },
98 { SIZEOF_HEADERS,"SIZEOF_HEADERS" },
99 { NEXT,"NEXT" },
100 { SIZEOF,"SIZEOF" },
101 { ADDR,"ADDR" },
102 { MEMORY,"MEMORY" },
103 { DEFINED,"DEFINED" },
104 { TARGET_K,"TARGET" },
105 { SEARCH_DIR,"SEARCH_DIR" },
106 { MAP,"MAP" },
107 { QUAD,"QUAD" },
108 { LONG,"LONG" },
109 { SHORT,"SHORT" },
110 { BYTE,"BYTE" },
111 { ENTRY,"ENTRY" },
112 { 0,(char *)NULL }
113 };
2fa0b342 114 unsigned int idx;
31ddb156 115
2fa0b342
DHW
116 for (idx = 0; table[idx].name != (char*)NULL; idx++) {
117 if (table[idx].code == code) {
2e2bf962 118 fprintf(config.map_file, "%s", table[idx].name);
2fa0b342
DHW
119 return;
120 }
121 }
122 /* Not in table, just print it alone */
2e2bf962 123 fprintf(config.map_file, "%c",code);
2fa0b342
DHW
124}
125
126static void
8bf66be8
DM
127make_abs (ptr)
128 etree_value_type *ptr;
2fa0b342 129{
2fa0b342
DHW
130 asection *s = ptr->section->bfd_section;
131 ptr->value += s->vma;
76971f0d 132 ptr->section = abs_output_section;
2fa0b342 133}
c611e285 134
8bf66be8
DM
135static etree_value_type
136new_abs (value)
137 bfd_vma value;
2fa0b342
DHW
138{
139 etree_value_type new;
140 new.valid = true;
76971f0d 141 new.section = abs_output_section;
2fa0b342
DHW
142 new.value = value;
143 return new;
144}
145
3a399523 146static void
8bf66be8
DM
147check (os, name, op)
148 lang_output_section_statement_type *os;
149 CONST char *name;
150 CONST char *op;
2fa0b342
DHW
151{
152 if (os == (lang_output_section_statement_type *)NULL) {
fcf276c4 153 einfo("%F%P: %s uses undefined section %s\n", op, name);
2fa0b342
DHW
154 }
155 if (os->processed == false) {
fcf276c4 156 einfo("%F%P: %s forward reference of section %s\n",op, name);
2fa0b342
DHW
157 }
158}
159
c611e285 160etree_type *
8bf66be8
DM
161exp_intop (value)
162 bfd_vma value;
2fa0b342 163{
e3e69b13 164 etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
2fa0b342
DHW
165 new->type.node_code = INT;
166 new->value.value = value;
167 new->type.node_class = etree_value;
168 return new;
169
170}
171
31ddb156
ILT
172/* Build an expression representing an unnamed relocateable value. */
173
174etree_type *
175exp_relop (section, value)
176 asection *section;
177 bfd_vma value;
178{
179 etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
180 new->type.node_code = REL;
181 new->type.node_class = etree_rel;
182 new->rel.section = section;
183 new->rel.value = value;
184 return new;
185}
2fa0b342 186
8bf66be8
DM
187static etree_value_type
188new_rel (value, section)
189 bfd_vma value;
190 lang_output_section_statement_type *section;
2fa0b342
DHW
191{
192 etree_value_type new;
193 new.valid = true;
194 new.value = value;
195 new.section = section;
196 return new;
197}
198
8bf66be8
DM
199static etree_value_type
200new_rel_from_section (value, section)
201 bfd_vma value;
202 lang_output_section_statement_type *section;
2fa0b342
DHW
203{
204 etree_value_type new;
205 new.valid = true;
206 new.value = value;
207 new.section = section;
76971f0d 208
2fa0b342 209 new.value -= section->bfd_section->vma;
76971f0d 210
2fa0b342
DHW
211 return new;
212}
213
214static etree_value_type
8bf66be8
DM
215fold_binary (tree, current_section, allocation_done, dot, dotp)
216 etree_type *tree;
217 lang_output_section_statement_type *current_section;
1abb243d 218 lang_phase_type allocation_done;
8bf66be8
DM
219 bfd_vma dot;
220 bfd_vma *dotp;
2fa0b342
DHW
221{
222 etree_value_type result;
223
1abb243d 224 result = exp_fold_tree (tree->binary.lhs, current_section,
2fa0b342 225 allocation_done, dot, dotp);
1abb243d
ILT
226 if (result.valid)
227 {
228 etree_value_type other;
229
230 other = exp_fold_tree (tree->binary.rhs,
231 current_section,
232 allocation_done, dot,dotp) ;
233 if (other.valid)
2fa0b342 234 {
1abb243d
ILT
235 /* If the values are from different sections, or this is an
236 absolute expression, make both the source arguments
237 absolute. However, adding or subtracting an absolute
238 value from a relative value is meaningful, and is an
239 exception. */
240 if (current_section != abs_output_section
e3e69b13
ILT
241 && (other.section == abs_output_section
242 || (result.section == abs_output_section
243 && tree->type.node_code == '+'))
1abb243d
ILT
244 && (tree->type.node_code == '+'
245 || tree->type.node_code == '-'))
246 {
247 etree_value_type hold;
2fa0b342 248
1abb243d
ILT
249 /* If there is only one absolute term, make sure it is the
250 second one. */
e3e69b13 251 if (other.section != abs_output_section)
1abb243d
ILT
252 {
253 hold = result;
254 result = other;
255 other = hold;
256 }
257 }
258 else if (result.section != other.section
259 || current_section == abs_output_section)
260 {
261 make_abs(&result);
262 make_abs(&other);
263 }
264
265 switch (tree->type.node_code)
266 {
267 case '%':
268 if (other.value == 0)
269 einfo ("%F%S %% by zero\n");
270 result.value = ((bfd_signed_vma) result.value
271 % (bfd_signed_vma) other.value);
272 break;
273
274 case '/':
275 if (other.value == 0)
276 einfo ("%F%S / by zero\n");
277 result.value = ((bfd_signed_vma) result.value
278 / (bfd_signed_vma) other.value);
279 break;
280
281#define BOP(x,y) case x : result.value = result.value y other.value; break;
282 BOP('+',+);
283 BOP('*',*);
284 BOP('-',-);
285 BOP(LSHIFT,<<);
286 BOP(RSHIFT,>>);
287 BOP(EQ,==);
288 BOP(NE,!=);
289 BOP('<',<);
290 BOP('>',>);
291 BOP(LE,<=);
292 BOP(GE,>=);
293 BOP('&',&);
294 BOP('^',^);
295 BOP('|',|);
296 BOP(ANDAND,&&);
297 BOP(OROR,||);
298
299 default:
300 FAIL();
301 }
302 }
303 else
304 {
305 result.valid = false;
2fa0b342
DHW
306 }
307 }
1abb243d 308
2fa0b342
DHW
309 return result;
310}
1abb243d 311
c611e285 312etree_value_type
8bf66be8 313invalid ()
2fa0b342
DHW
314{
315 etree_value_type new;
316 new.valid = false;
317 return new;
318}
319
31ddb156 320static etree_value_type
8bf66be8
DM
321fold_name (tree, current_section, allocation_done, dot)
322 etree_type *tree;
323 lang_output_section_statement_type *current_section;
324 lang_phase_type allocation_done;
325 bfd_vma dot;
2fa0b342
DHW
326{
327 etree_value_type result;
328 switch (tree->type.node_code)
ac004870 329 {
65c552e3
SC
330 case SIZEOF_HEADERS:
331 if (allocation_done != lang_first_phase_enum)
31ddb156
ILT
332 {
333 result = new_abs ((bfd_vma)
334 bfd_sizeof_headers (output_bfd,
335 link_info.relocateable));
336 }
337 else
338 {
339 result.valid = false;
340 }
65c552e3 341 break;
ac004870 342 case DEFINED:
1abb243d
ILT
343 if (allocation_done == lang_first_phase_enum)
344 result.valid = false;
345 else
346 {
347 struct bfd_link_hash_entry *h;
348
e3e69b13
ILT
349 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
350 tree->name.name,
351 false, false, true);
1abb243d
ILT
352 result.value = (h != (struct bfd_link_hash_entry *) NULL
353 && (h->type == bfd_link_hash_defined
e3e69b13 354 || h->type == bfd_link_hash_defweak
1abb243d
ILT
355 || h->type == bfd_link_hash_common));
356 result.section = 0;
357 result.valid = true;
358 }
ac004870
SC
359 break;
360 case NAME:
361 result.valid = false;
31ddb156
ILT
362 if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
363 {
364 if (allocation_done != lang_first_phase_enum)
365 result = new_rel_from_section(dot, current_section);
366 else
367 result = invalid();
ac004870 368 }
1abb243d 369 else if (allocation_done != lang_first_phase_enum)
31ddb156
ILT
370 {
371 struct bfd_link_hash_entry *h;
372
e3e69b13
ILT
373 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
374 tree->name.name,
375 false, false, true);
376 if (h != NULL
377 && (h->type == bfd_link_hash_defined
378 || h->type == bfd_link_hash_defweak))
31ddb156 379 {
1abb243d
ILT
380 if (bfd_is_abs_section (h->u.def.section))
381 result = new_abs (h->u.def.value);
e3e69b13
ILT
382 else if (allocation_done == lang_final_phase_enum
383 || allocation_done == lang_allocating_phase_enum)
1abb243d
ILT
384 {
385 lang_output_section_statement_type *os;
31ddb156 386
1abb243d
ILT
387 os = (lang_output_section_statement_lookup
388 (h->u.def.section->output_section->name));
389
390 /* FIXME: Is this correct if this section is being
391 linked with -R? */
392 result = new_rel ((h->u.def.value
393 + h->u.def.section->output_offset),
394 os);
395 }
2fa0b342 396 }
1abb243d
ILT
397 else if (allocation_done == lang_final_phase_enum)
398 einfo ("%F%S: undefined symbol `%s' referenced in expression\n",
399 tree->name.name);
ac004870 400 }
ac004870 401 break;
2fa0b342 402
ac004870 403 case ADDR:
2fa0b342 404
ac004870
SC
405 if (allocation_done != lang_first_phase_enum) {
406 lang_output_section_statement_type *os =
407 lang_output_section_find(tree->name.name);
408 check(os,tree->name.name,"ADDR");
409 result = new_rel((bfd_vma)0, os);
410 }
411 else {
412 result = invalid();
413 }
414 break;
415 case SIZEOF:
416 if(allocation_done != lang_first_phase_enum) {
417 lang_output_section_statement_type *os =
418 lang_output_section_find(tree->name.name);
419 check(os,tree->name.name,"SIZEOF");
c611e285 420 result = new_abs((bfd_vma)(os->bfd_section->_raw_size));
ac004870
SC
421 }
422 else {
423 result = invalid();
424 }
425 break;
2fa0b342 426
ac004870
SC
427 default:
428 FAIL();
429 break;
430 }
2fa0b342
DHW
431
432 return result;
433}
c611e285 434etree_value_type
8bf66be8
DM
435exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
436 etree_type *tree;
437 lang_output_section_statement_type *current_section;
438 lang_phase_type allocation_done;
439 bfd_vma dot;
440 bfd_vma *dotp;
2fa0b342
DHW
441{
442 etree_value_type result;
443
444 if (tree == (etree_type *)NULL) {
8bf66be8
DM
445 result.valid = false;
446 }
2fa0b342 447 else {
8bf66be8
DM
448 switch (tree->type.node_class)
449 {
450 case etree_value:
451 result = new_rel(tree->value.value, current_section);
452 break;
31ddb156
ILT
453 case etree_rel:
454 if (allocation_done != lang_final_phase_enum)
455 result.valid = false;
456 else
457 result = new_rel ((tree->rel.value
458 + tree->rel.section->output_section->vma
459 + tree->rel.section->output_offset),
460 current_section);
461 break;
8bf66be8
DM
462 case etree_unary:
463 result = exp_fold_tree(tree->unary.child,
464 current_section,
465 allocation_done, dot, dotp);
466 if (result.valid == true)
c611e285 467 {
8bf66be8 468 switch(tree->type.node_code)
d4c02e29 469 {
8bf66be8
DM
470 case ALIGN_K:
471 if (allocation_done != lang_first_phase_enum) {
472 result = new_rel_from_section(ALIGN_N(dot,
473 result.value) ,
474 current_section);
475
476 }
477 else {
478 result.valid = false;
479 }
480 break;
481 case ABSOLUTE:
e3e69b13 482 if (allocation_done != lang_first_phase_enum && result.valid)
8bf66be8 483 {
e3e69b13 484 result.value += result.section->bfd_section->vma;
8bf66be8 485 result.section = abs_output_section;
8bf66be8 486 }
8bf66be8 487 else
e3e69b13
ILT
488 {
489 result.valid = false;
490 }
8bf66be8
DM
491 break;
492 case '~':
493 make_abs(&result);
494 result.value = ~result.value;
495 break;
496 case '!':
497 make_abs(&result);
498 result.value = !result.value;
499 break;
500 case '-':
501 make_abs(&result);
502 result.value = -result.value;
503 break;
504 case NEXT:
505 if (allocation_done ==lang_allocating_phase_enum) {
c611e285 506 make_abs(&result);
8bf66be8 507 result.value = ALIGN_N(dot, result.value);
c611e285 508 }
8bf66be8
DM
509 else {
510 /* Return next place aligned to value */
511 result.valid = false;
512 }
513 break;
514 default:
515 FAIL();
c611e285 516 }
8bf66be8 517 }
2fa0b342 518
8bf66be8
DM
519 break;
520 case etree_trinary:
2fa0b342 521
8bf66be8
DM
522 result = exp_fold_tree(tree->trinary.cond,
523 current_section,
524 allocation_done, dot, dotp);
525 if (result.valid) {
526 result = exp_fold_tree(result.value ?
527 tree->trinary.lhs:tree->trinary.rhs,
c611e285
SC
528 current_section,
529 allocation_done, dot, dotp);
8bf66be8 530 }
d4c02e29 531
8bf66be8
DM
532 break;
533 case etree_binary:
534 result = fold_binary(tree, current_section, allocation_done,
535 dot, dotp);
536 break;
537 case etree_assign:
31ddb156 538 case etree_provide:
8bf66be8
DM
539 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
540 /* Assignment to dot can only be done during allocation */
31ddb156
ILT
541 if (tree->type.node_class == etree_provide)
542 einfo ("%F%S can not PROVIDE assignment to location counter\n");
e3e69b13
ILT
543 if (allocation_done == lang_allocating_phase_enum
544 || (allocation_done == lang_final_phase_enum
545 && current_section == abs_output_section)) {
8bf66be8
DM
546 result = exp_fold_tree(tree->assign.src,
547 current_section,
548 lang_allocating_phase_enum, dot, dotp);
549 if (result.valid == false) {
550 einfo("%F%S invalid assignment to location counter\n");
551 }
552 else {
553 if (current_section ==
554 (lang_output_section_statement_type *)NULL) {
555 einfo("%F%S assignment to location counter invalid outside of SECTION\n");
556 }
557 else {
558 bfd_vma nextdot =result.value +
559 current_section->bfd_section->vma;
e3e69b13 560 if (nextdot < dot && current_section != abs_output_section) {
8bf66be8
DM
561 einfo("%F%S cannot move location counter backwards (from %V to %V)\n", dot, nextdot);
562 }
563 else {
564 *dotp = nextdot;
2fa0b342 565 }
8bf66be8 566 }
2fa0b342 567 }
8bf66be8
DM
568 }
569 }
31ddb156 570 else
8bf66be8 571 {
31ddb156
ILT
572 result = exp_fold_tree (tree->assign.src,
573 current_section, allocation_done,
574 dot, dotp);
575 if (result.valid)
576 {
577 struct bfd_link_hash_entry *h;
578
579 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
580 (tree->type.node_class == etree_assign
581 ? true : false),
582 false, false);
583 if (h == (struct bfd_link_hash_entry *) NULL)
584 {
585 if (tree->type.node_class == etree_assign)
586 einfo ("%P%F:%s: hash creation failed\n",
587 tree->assign.dst);
588 }
589 else if (tree->type.node_class == etree_provide
590 && h->type != bfd_link_hash_undefined
591 && h->type != bfd_link_hash_common)
592 {
593 /* Do nothing. The symbol was defined by some
594 object. */
595 }
596 else
597 {
598 /* FIXME: Should we worry if the symbol is already
599 defined? */
600 h->type = bfd_link_hash_defined;
601 h->u.def.value = result.value;
602 h->u.def.section = result.section->bfd_section;
603 }
604 }
605 }
8bf66be8
DM
606 break;
607 case etree_name:
608 result = fold_name(tree, current_section, allocation_done, dot);
609 break;
610 default:
fcf276c4 611 einfo("%F%S need more of these %d\n",tree->type.node_class );
2fa0b342 612
c611e285 613 }
8bf66be8 614 }
2fa0b342
DHW
615
616 return result;
617}
618
619
31ddb156 620static etree_value_type
8bf66be8
DM
621exp_fold_tree_no_dot (tree, current_section, allocation_done)
622 etree_type *tree;
623 lang_output_section_statement_type *current_section;
624 lang_phase_type allocation_done;
2fa0b342
DHW
625{
626return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
627 0, (bfd_vma *)NULL);
628}
629
630etree_type *
8bf66be8
DM
631exp_binop (code, lhs, rhs)
632 int code;
633 etree_type *lhs;
634 etree_type *rhs;
2fa0b342
DHW
635{
636 etree_type value, *new;
637 etree_value_type r;
638
639 value.type.node_code = code;
640 value.binary.lhs = lhs;
641 value.binary.rhs = rhs;
642 value.type.node_class = etree_binary;
76971f0d
SC
643 r = exp_fold_tree_no_dot(&value,
644 abs_output_section,
2fa0b342
DHW
645 lang_first_phase_enum );
646 if (r.valid)
647 {
648 return exp_intop(r.value);
649 }
e3e69b13 650 new = (etree_type *) stat_alloc (sizeof (new->binary));
2fa0b342
DHW
651 memcpy((char *)new, (char *)&value, sizeof(new->binary));
652 return new;
653}
654
655etree_type *
8bf66be8
DM
656exp_trinop (code, cond, lhs, rhs)
657 int code;
658 etree_type *cond;
659 etree_type *lhs;
660 etree_type *rhs;
2fa0b342
DHW
661{
662 etree_type value, *new;
663 etree_value_type r;
664 value.type.node_code = code;
665 value.trinary.lhs = lhs;
666 value.trinary.cond = cond;
667 value.trinary.rhs = rhs;
668 value.type.node_class = etree_trinary;
669 r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type
670 *)NULL,lang_first_phase_enum);
671 if (r.valid) {
672 return exp_intop(r.value);
673 }
e3e69b13 674 new = (etree_type *) stat_alloc (sizeof (new->trinary));
2fa0b342
DHW
675 memcpy((char *)new,(char *) &value, sizeof(new->trinary));
676 return new;
677}
678
679
680etree_type *
8bf66be8
DM
681exp_unop (code, child)
682 int code;
683 etree_type *child;
2fa0b342
DHW
684{
685 etree_type value, *new;
686
687 etree_value_type r;
688 value.unary.type.node_code = code;
689 value.unary.child = child;
690 value.unary.type.node_class = etree_unary;
8bf66be8 691 r = exp_fold_tree_no_dot(&value,abs_output_section,
c611e285
SC
692 lang_first_phase_enum);
693 if (r.valid) {
2fa0b342
DHW
694 return exp_intop(r.value);
695 }
e3e69b13 696 new = (etree_type *) stat_alloc (sizeof (new->unary));
2fa0b342
DHW
697 memcpy((char *)new, (char *)&value, sizeof(new->unary));
698 return new;
699}
700
701
702etree_type *
8bf66be8
DM
703exp_nameop (code, name)
704 int code;
705 CONST char *name;
2fa0b342 706{
2fa0b342 707 etree_type value, *new;
2fa0b342
DHW
708 etree_value_type r;
709 value.name.type.node_code = code;
710 value.name.name = name;
711 value.name.type.node_class = etree_name;
712
713
76971f0d
SC
714 r = exp_fold_tree_no_dot(&value,
715 (lang_output_section_statement_type *)NULL,
716 lang_first_phase_enum);
2fa0b342
DHW
717 if (r.valid) {
718 return exp_intop(r.value);
719 }
e3e69b13 720 new = (etree_type *) stat_alloc (sizeof (new->name));
2fa0b342
DHW
721 memcpy((char *)new, (char *)&value, sizeof(new->name));
722 return new;
723
724}
725
726
727
728
729etree_type *
8bf66be8
DM
730exp_assop (code, dst, src)
731 int code;
732 CONST char *dst;
733 etree_type *src;
2fa0b342
DHW
734{
735 etree_type value, *new;
736
737 value.assign.type.node_code = code;
738
739
740 value.assign.src = src;
741 value.assign.dst = dst;
742 value.assign.type.node_class = etree_assign;
743
744#if 0
745 if (exp_fold_tree_no_dot(&value, &result)) {
746 return exp_intop(result);
747 }
748#endif
e3e69b13 749 new = (etree_type*) stat_alloc (sizeof (new->assign));
2fa0b342
DHW
750 memcpy((char *)new, (char *)&value, sizeof(new->assign));
751 return new;
752}
753
31ddb156
ILT
754/* Handle PROVIDE. */
755
756etree_type *
757exp_provide (dst, src)
758 const char *dst;
759 etree_type *src;
760{
761 etree_type *n;
762
763 n = (etree_type *) stat_alloc (sizeof (n->assign));
764 n->assign.type.node_code = '=';
765 n->assign.type.node_class = etree_provide;
766 n->assign.src = src;
767 n->assign.dst = dst;
768 return n;
769}
770
2fa0b342 771void
8bf66be8
DM
772exp_print_tree (tree)
773 etree_type *tree;
2fa0b342
DHW
774{
775 switch (tree->type.node_class) {
776 case etree_value:
c611e285 777 print_address(tree->value.value);
2fa0b342 778 return;
31ddb156
ILT
779 case etree_rel:
780 if (tree->rel.section->owner != NULL)
781 fprintf (config.map_file, "%s:",
782 bfd_get_filename (tree->rel.section->owner));
783 fprintf (config.map_file, "%s+", tree->rel.section->name);
784 print_address (tree->rel.value);
785 return;
2fa0b342
DHW
786 case etree_assign:
787#if 0
788 if (tree->assign.dst->sdefs != (asymbol *)NULL){
2e2bf962 789 fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
2fa0b342
DHW
790 tree->assign.dst->sdefs->value);
791 }
792 else {
2e2bf962 793 fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
2fa0b342
DHW
794 }
795#endif
2e2bf962
SC
796 fprintf(config.map_file,"%s ",tree->assign.dst);
797 exp_print_token(tree->type.node_code);
798 exp_print_tree(tree->assign.src);
2fa0b342 799 break;
31ddb156
ILT
800 case etree_provide:
801 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
802 exp_print_tree (tree->assign.src);
803 fprintf (config.map_file, ")");
804 break;
2fa0b342 805 case etree_binary:
bfbdc80f 806 fprintf(config.map_file,"(");
2e2bf962
SC
807 exp_print_tree(tree->binary.lhs);
808 exp_print_token(tree->type.node_code);
809 exp_print_tree(tree->binary.rhs);
bfbdc80f 810 fprintf(config.map_file,")");
2fa0b342
DHW
811 break;
812 case etree_trinary:
2e2bf962
SC
813 exp_print_tree(tree->trinary.cond);
814 fprintf(config.map_file,"?");
815 exp_print_tree(tree->trinary.lhs);
816 fprintf(config.map_file,":");
817 exp_print_tree(tree->trinary.rhs);
2fa0b342
DHW
818 break;
819 case etree_unary:
2e2bf962 820 exp_print_token(tree->unary.type.node_code);
bfbdc80f
SC
821 if (tree->unary.child)
822 {
823
2e2bf962
SC
824 fprintf(config.map_file,"(");
825 exp_print_tree(tree->unary.child);
826 fprintf(config.map_file,")");
bfbdc80f
SC
827 }
828
2fa0b342
DHW
829 break;
830 case etree_undef:
2e2bf962 831 fprintf(config.map_file,"????????");
2fa0b342
DHW
832 break;
833 case etree_name:
834 if (tree->type.node_code == NAME) {
2e2bf962 835 fprintf(config.map_file,"%s", tree->name.name);
2fa0b342
DHW
836 }
837 else {
2e2bf962 838 exp_print_token(tree->type.node_code);
bfbdc80f 839 if (tree->name.name)
2e2bf962 840 fprintf(config.map_file,"(%s)", tree->name.name);
2fa0b342
DHW
841 }
842 break;
843 default:
844 FAIL();
845 break;
846 }
847}
848
849
850
851
852bfd_vma
8bf66be8
DM
853exp_get_vma (tree, def, name, allocation_done)
854 etree_type *tree;
855 bfd_vma def;
856 char *name;
857 lang_phase_type allocation_done;
2fa0b342
DHW
858{
859 etree_value_type r;
860
861 if (tree != (etree_type *)NULL) {
862 r = exp_fold_tree_no_dot(tree,
bfbdc80f 863 abs_output_section,
2fa0b342
DHW
864 allocation_done);
865 if (r.valid == false && name) {
fcf276c4 866 einfo("%F%S nonconstant expression for %s\n",name);
2fa0b342
DHW
867 }
868 return r.value;
869 }
870 else {
871 return def;
872 }
873}
874
875int
8bf66be8
DM
876exp_get_value_int (tree,def,name, allocation_done)
877 etree_type *tree;
878 int def;
879 char *name;
880 lang_phase_type allocation_done;
2fa0b342
DHW
881{
882 return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
883}
65c552e3 884
1abb243d 885
e3e69b13 886bfd_vma
1abb243d
ILT
887exp_get_abs_int (tree, def, name, allocation_done)
888 etree_type *tree;
889 int def;
890 char *name;
891 lang_phase_type allocation_done;
892{
893 etree_value_type res;
894 res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
895
896 if (res.valid)
897 {
898 res.value += res.section->bfd_section->vma;
899 }
900 else {
901 einfo ("%F%S non constant expression for %s\n",name);
902 }
903 return res.value;
904}
This page took 0.214941 seconds and 4 git commands to generate.