source: branches/libc-0.6/src/binutils/ld/ldexp.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 28.7 KB
Line 
1/* This module handles expression trees.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002
4 Free Software Foundation, Inc.
5 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
6
7This file is part of GLD, the Gnu Linker.
8
9GLD is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GLD is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GLD; see the file COPYING. If not, write to the Free
21Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2202111-1307, USA. */
23
24/* This module is in charge of working out the contents of expressions.
25
26 It has to keep track of the relative/absness of a symbol etc. This
27 is done by keeping all values in a struct (an etree_value_type)
28 which contains a value, a section to which it is relative and a
29 valid bit. */
30
31#include "bfd.h"
32#include "sysdep.h"
33#include "bfdlink.h"
34
35#include "ld.h"
36#include "ldmain.h"
37#include "ldmisc.h"
38#include "ldexp.h"
39#include <ldgram.h>
40#include "ldlang.h"
41#include "libiberty.h"
42#include "safe-ctype.h"
43
44static void exp_print_token
45 PARAMS ((token_code_type code, int infix_p));
46static void make_abs
47 PARAMS ((etree_value_type *ptr));
48static etree_value_type new_abs
49 PARAMS ((bfd_vma value));
50static void check
51 PARAMS ((lang_output_section_statement_type *os, const char *name,
52 const char *op));
53static etree_value_type new_rel
54 PARAMS ((bfd_vma, char *, lang_output_section_statement_type *section));
55static etree_value_type new_rel_from_section
56 PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
57static etree_value_type fold_unary
58 PARAMS ((etree_type *tree,
59 lang_output_section_statement_type *current_section,
60 lang_phase_type allocation_done,
61 bfd_vma dot, bfd_vma *dotp));
62static etree_value_type fold_binary
63 PARAMS ((etree_type *tree,
64 lang_output_section_statement_type *current_section,
65 lang_phase_type allocation_done,
66 bfd_vma dot, bfd_vma *dotp));
67static etree_value_type fold_trinary
68 PARAMS ((etree_type *tree,
69 lang_output_section_statement_type *current_section,
70 lang_phase_type allocation_done,
71 bfd_vma dot, bfd_vma *dotp));
72static etree_value_type fold_name
73 PARAMS ((etree_type *tree,
74 lang_output_section_statement_type *current_section,
75 lang_phase_type allocation_done,
76 bfd_vma dot));
77static etree_value_type exp_fold_tree_no_dot
78 PARAMS ((etree_type *tree,
79 lang_output_section_statement_type *current_section,
80 lang_phase_type allocation_done));
81
82struct exp_data_seg exp_data_seg;
83
84/* Print the string representation of the given token. Surround it
85 with spaces if INFIX_P is TRUE. */
86
87static void
88exp_print_token (code, infix_p)
89 token_code_type code;
90 int infix_p;
91{
92 static const struct
93 {
94 token_code_type code;
95 char * name;
96 }
97 table[] =
98 {
99 { INT, "int" },
100 { NAME, "NAME" },
101 { PLUSEQ, "+=" },
102 { MINUSEQ, "-=" },
103 { MULTEQ, "*=" },
104 { DIVEQ, "/=" },
105 { LSHIFTEQ, "<<=" },
106 { RSHIFTEQ, ">>=" },
107 { ANDEQ, "&=" },
108 { OREQ, "|=" },
109 { OROR, "||" },
110 { ANDAND, "&&" },
111 { EQ, "==" },
112 { NE, "!=" },
113 { LE, "<=" },
114 { GE, ">=" },
115 { LSHIFT, "<<" },
116 { RSHIFT, ">>" },
117 { ALIGN_K, "ALIGN" },
118 { BLOCK, "BLOCK" },
119 { QUAD, "QUAD" },
120 { SQUAD, "SQUAD" },
121 { LONG, "LONG" },
122 { SHORT, "SHORT" },
123 { BYTE, "BYTE" },
124 { SECTIONS, "SECTIONS" },
125 { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
126 { MEMORY, "MEMORY" },
127 { DEFINED, "DEFINED" },
128 { TARGET_K, "TARGET" },
129 { SEARCH_DIR, "SEARCH_DIR" },
130 { MAP, "MAP" },
131 { ENTRY, "ENTRY" },
132 { NEXT, "NEXT" },
133 { SIZEOF, "SIZEOF" },
134 { ADDR, "ADDR" },
135 { LOADADDR, "LOADADDR" },
136 { MAX_K, "MAX_K" },
137 { REL, "relocateable" },
138 { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
139 { DATA_SEGMENT_END, "DATA_SEGMENT_END" }
140 };
141 unsigned int idx;
142
143 for (idx = 0; idx < ARRAY_SIZE (table); idx++)
144 if (table[idx].code == code)
145 break;
146
147 if (infix_p)
148 fputc (' ', config.map_file);
149
150 if (idx < ARRAY_SIZE (table))
151 fputs (table[idx].name, config.map_file);
152 else if (code < 127)
153 fputc (code, config.map_file);
154 else
155 fprintf (config.map_file, "<code %d>", code);
156
157 if (infix_p)
158 fputc (' ', config.map_file);
159}
160
161static void
162make_abs (ptr)
163 etree_value_type *ptr;
164{
165 asection *s = ptr->section->bfd_section;
166 ptr->value += s->vma;
167 ptr->section = abs_output_section;
168}
169
170static etree_value_type
171new_abs (value)
172 bfd_vma value;
173{
174 etree_value_type new;
175 new.valid_p = TRUE;
176 new.section = abs_output_section;
177 new.value = value;
178 return new;
179}
180
181static void
182check (os, name, op)
183 lang_output_section_statement_type *os;
184 const char *name;
185 const char *op;
186{
187 if (os == NULL)
188 einfo (_("%F%P: %s uses undefined section %s\n"), op, name);
189 if (! os->processed)
190 einfo (_("%F%P: %s forward reference of section %s\n"), op, name);
191}
192
193etree_type *
194exp_intop (value)
195 bfd_vma value;
196{
197 etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
198 new->type.node_code = INT;
199 new->value.value = value;
200 new->value.str = NULL;
201 new->type.node_class = etree_value;
202 return new;
203}
204
205etree_type *
206exp_bigintop (value, str)
207 bfd_vma value;
208 char *str;
209{
210 etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
211 new->type.node_code = INT;
212 new->value.value = value;
213 new->value.str = str;
214 new->type.node_class = etree_value;
215 return new;
216}
217
218/* Build an expression representing an unnamed relocateable value. */
219
220etree_type *
221exp_relop (section, value)
222 asection *section;
223 bfd_vma value;
224{
225 etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
226 new->type.node_code = REL;
227 new->type.node_class = etree_rel;
228 new->rel.section = section;
229 new->rel.value = value;
230 return new;
231}
232
233static etree_value_type
234new_rel (value, str, section)
235 bfd_vma value;
236 char *str;
237 lang_output_section_statement_type *section;
238{
239 etree_value_type new;
240 new.valid_p = TRUE;
241 new.value = value;
242 new.str = str;
243 new.section = section;
244 return new;
245}
246
247static etree_value_type
248new_rel_from_section (value, section)
249 bfd_vma value;
250 lang_output_section_statement_type *section;
251{
252 etree_value_type new;
253 new.valid_p = TRUE;
254 new.value = value;
255 new.str = NULL;
256 new.section = section;
257
258 new.value -= section->bfd_section->vma;
259
260 return new;
261}
262
263static etree_value_type
264fold_unary (tree, current_section, allocation_done, dot, dotp)
265 etree_type *tree;
266 lang_output_section_statement_type *current_section;
267 lang_phase_type allocation_done;
268 bfd_vma dot;
269 bfd_vma *dotp;
270{
271 etree_value_type result;
272
273 result = exp_fold_tree (tree->unary.child,
274 current_section,
275 allocation_done, dot, dotp);
276 if (result.valid_p)
277 {
278 switch (tree->type.node_code)
279 {
280 case ALIGN_K:
281 if (allocation_done != lang_first_phase_enum)
282 result = new_rel_from_section (align_n (dot, result.value),
283 current_section);
284 else
285 result.valid_p = FALSE;
286 break;
287
288 case ABSOLUTE:
289 if (allocation_done != lang_first_phase_enum)
290 {
291 result.value += result.section->bfd_section->vma;
292 result.section = abs_output_section;
293 }
294 else
295 result.valid_p = FALSE;
296 break;
297
298 case '~':
299 make_abs (&result);
300 result.value = ~result.value;
301 break;
302
303 case '!':
304 make_abs (&result);
305 result.value = !result.value;
306 break;
307
308 case '-':
309 make_abs (&result);
310 result.value = -result.value;
311 break;
312
313 case NEXT:
314 /* Return next place aligned to value. */
315 if (allocation_done == lang_allocating_phase_enum)
316 {
317 make_abs (&result);
318 result.value = align_n (dot, result.value);
319 }
320 else
321 result.valid_p = FALSE;
322 break;
323
324 case DATA_SEGMENT_END:
325 if (allocation_done != lang_first_phase_enum
326 && current_section == abs_output_section
327 && (exp_data_seg.phase == exp_dataseg_align_seen
328 || exp_data_seg.phase == exp_dataseg_adjust
329 || allocation_done != lang_allocating_phase_enum))
330 {
331 if (exp_data_seg.phase == exp_dataseg_align_seen)
332 {
333 exp_data_seg.phase = exp_dataseg_end_seen;
334 exp_data_seg.end = result.value;
335 }
336 }
337 else
338 result.valid_p = FALSE;
339 break;
340
341 default:
342 FAIL ();
343 break;
344 }
345 }
346
347 return result;
348}
349
350static etree_value_type
351fold_binary (tree, current_section, allocation_done, dot, dotp)
352 etree_type *tree;
353 lang_output_section_statement_type *current_section;
354 lang_phase_type allocation_done;
355 bfd_vma dot;
356 bfd_vma *dotp;
357{
358 etree_value_type result;
359
360 result = exp_fold_tree (tree->binary.lhs, current_section,
361 allocation_done, dot, dotp);
362 if (result.valid_p)
363 {
364 etree_value_type other;
365
366 other = exp_fold_tree (tree->binary.rhs,
367 current_section,
368 allocation_done, dot, dotp);
369 if (other.valid_p)
370 {
371 /* If the values are from different sections, or this is an
372 absolute expression, make both the source arguments
373 absolute. However, adding or subtracting an absolute
374 value from a relative value is meaningful, and is an
375 exception. */
376 if (current_section != abs_output_section
377 && (other.section == abs_output_section
378 || (result.section == abs_output_section
379 && tree->type.node_code == '+'))
380 && (tree->type.node_code == '+'
381 || tree->type.node_code == '-'))
382 {
383 if (other.section != abs_output_section)
384 {
385 /* Keep the section of the other term. */
386 if (tree->type.node_code == '+')
387 other.value = result.value + other.value;
388 else
389 other.value = result.value - other.value;
390 return other;
391 }
392 }
393 else if (result.section != other.section
394 || current_section == abs_output_section)
395 {
396 make_abs (&result);
397 make_abs (&other);
398 }
399
400 switch (tree->type.node_code)
401 {
402 case '%':
403 if (other.value == 0)
404 einfo (_("%F%S %% by zero\n"));
405 result.value = ((bfd_signed_vma) result.value
406 % (bfd_signed_vma) other.value);
407 break;
408
409 case '/':
410 if (other.value == 0)
411 einfo (_("%F%S / by zero\n"));
412 result.value = ((bfd_signed_vma) result.value
413 / (bfd_signed_vma) other.value);
414 break;
415
416#define BOP(x,y) case x : result.value = result.value y other.value; break;
417 BOP ('+', +);
418 BOP ('*', *);
419 BOP ('-', -);
420 BOP (LSHIFT, <<);
421 BOP (RSHIFT, >>);
422 BOP (EQ, ==);
423 BOP (NE, !=);
424 BOP ('<', <);
425 BOP ('>', >);
426 BOP (LE, <=);
427 BOP (GE, >=);
428 BOP ('&', &);
429 BOP ('^', ^);
430 BOP ('|', |);
431 BOP (ANDAND, &&);
432 BOP (OROR, ||);
433
434 case MAX_K:
435 if (result.value < other.value)
436 result = other;
437 break;
438
439 case MIN_K:
440 if (result.value > other.value)
441 result = other;
442 break;
443
444 case DATA_SEGMENT_ALIGN:
445 if (allocation_done != lang_first_phase_enum
446 && current_section == abs_output_section
447 && (exp_data_seg.phase == exp_dataseg_none
448 || exp_data_seg.phase == exp_dataseg_adjust
449 || allocation_done != lang_allocating_phase_enum))
450 {
451 bfd_vma maxpage = result.value;
452
453 result.value = align_n (dot, maxpage);
454 if (exp_data_seg.phase != exp_dataseg_adjust)
455 {
456 result.value += dot & (maxpage - 1);
457 if (allocation_done == lang_allocating_phase_enum)
458 {
459 exp_data_seg.phase = exp_dataseg_align_seen;
460 exp_data_seg.base = result.value;
461 exp_data_seg.pagesize = other.value;
462 }
463 }
464 else if (other.value < maxpage)
465 result.value += (dot + other.value - 1)
466 & (maxpage - other.value);
467 }
468 else
469 result.valid_p = FALSE;
470 break;
471
472 default:
473 FAIL ();
474 }
475 }
476 else
477 {
478 result.valid_p = FALSE;
479 }
480 }
481
482 return result;
483}
484
485static etree_value_type
486fold_trinary (tree, current_section, allocation_done, dot, dotp)
487 etree_type *tree;
488 lang_output_section_statement_type *current_section;
489 lang_phase_type allocation_done;
490 bfd_vma dot;
491 bfd_vma *dotp;
492{
493 etree_value_type result;
494
495 result = exp_fold_tree (tree->trinary.cond, current_section,
496 allocation_done, dot, dotp);
497 if (result.valid_p)
498 result = exp_fold_tree ((result.value
499 ? tree->trinary.lhs
500 : tree->trinary.rhs),
501 current_section,
502 allocation_done, dot, dotp);
503
504 return result;
505}
506
507etree_value_type
508invalid ()
509{
510 etree_value_type new;
511 new.valid_p = FALSE;
512 return new;
513}
514
515static etree_value_type
516fold_name (tree, current_section, allocation_done, dot)
517 etree_type *tree;
518 lang_output_section_statement_type *current_section;
519 lang_phase_type allocation_done;
520 bfd_vma dot;
521{
522 etree_value_type result;
523
524 switch (tree->type.node_code)
525 {
526 case SIZEOF_HEADERS:
527 if (allocation_done != lang_first_phase_enum)
528 {
529 result = new_abs ((bfd_vma)
530 bfd_sizeof_headers (output_bfd,
531 link_info.relocateable));
532 }
533 else
534 {
535 result.valid_p = FALSE;
536 }
537 break;
538 case DEFINED:
539 if (allocation_done == lang_first_phase_enum)
540 result.valid_p = FALSE;
541 else
542 {
543 struct bfd_link_hash_entry *h;
544
545 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
546 tree->name.name,
547 FALSE, FALSE, TRUE);
548 result.value = (h != (struct bfd_link_hash_entry *) NULL
549 && (h->type == bfd_link_hash_defined
550 || h->type == bfd_link_hash_defweak
551 || h->type == bfd_link_hash_common));
552 result.section = 0;
553 result.valid_p = TRUE;
554 }
555 break;
556 case NAME:
557 result.valid_p = FALSE;
558 if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
559 {
560 if (allocation_done != lang_first_phase_enum)
561 result = new_rel_from_section (dot, current_section);
562 else
563 result = invalid ();
564 }
565 else if (allocation_done != lang_first_phase_enum)
566 {
567 struct bfd_link_hash_entry *h;
568
569 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
570 tree->name.name,
571 FALSE, FALSE, TRUE);
572 if (h != NULL
573 && (h->type == bfd_link_hash_defined
574 || h->type == bfd_link_hash_defweak))
575 {
576 if (bfd_is_abs_section (h->u.def.section))
577 result = new_abs (h->u.def.value);
578 else if (allocation_done == lang_final_phase_enum
579 || allocation_done == lang_allocating_phase_enum)
580 {
581 asection *output_section;
582
583 output_section = h->u.def.section->output_section;
584 if (output_section == NULL)
585 einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
586 tree->name.name);
587 else
588 {
589 lang_output_section_statement_type *os;
590
591 os = (lang_output_section_statement_lookup
592 (bfd_get_section_name (output_bfd,
593 output_section)));
594
595 /* FIXME: Is this correct if this section is
596 being linked with -R? */
597 result = new_rel ((h->u.def.value
598 + h->u.def.section->output_offset),
599 NULL,
600 os);
601 }
602 }
603 }
604 else if (allocation_done == lang_final_phase_enum)
605 einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
606 tree->name.name);
607 }
608 break;
609
610 case ADDR:
611 if (allocation_done != lang_first_phase_enum)
612 {
613 lang_output_section_statement_type *os;
614
615 os = lang_output_section_find (tree->name.name);
616 check (os, tree->name.name, "ADDR");
617 result = new_rel (0, NULL, os);
618 }
619 else
620 result = invalid ();
621 break;
622
623 case LOADADDR:
624 if (allocation_done != lang_first_phase_enum)
625 {
626 lang_output_section_statement_type *os;
627
628 os = lang_output_section_find (tree->name.name);
629 check (os, tree->name.name, "LOADADDR");
630 if (os->load_base == NULL)
631 result = new_rel (0, NULL, os);
632 else
633 result = exp_fold_tree_no_dot (os->load_base,
634 abs_output_section,
635 allocation_done);
636 }
637 else
638 result = invalid ();
639 break;
640
641 case SIZEOF:
642 if (allocation_done != lang_first_phase_enum)
643 {
644 int opb = bfd_octets_per_byte (output_bfd);
645 lang_output_section_statement_type *os;
646
647 os = lang_output_section_find (tree->name.name);
648 check (os, tree->name.name, "SIZEOF");
649 result = new_abs (os->bfd_section->_raw_size / opb);
650 }
651 else
652 result = invalid ();
653 break;
654
655 default:
656 FAIL ();
657 break;
658 }
659
660 return result;
661}
662
663etree_value_type
664exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
665 etree_type *tree;
666 lang_output_section_statement_type *current_section;
667 lang_phase_type allocation_done;
668 bfd_vma dot;
669 bfd_vma *dotp;
670{
671 etree_value_type result;
672
673 if (tree == NULL)
674 {
675 result.valid_p = FALSE;
676 return result;
677 }
678
679 switch (tree->type.node_class)
680 {
681 case etree_value:
682 result = new_rel (tree->value.value, tree->value.str, current_section);
683 break;
684
685 case etree_rel:
686 if (allocation_done != lang_final_phase_enum)
687 result.valid_p = FALSE;
688 else
689 result = new_rel ((tree->rel.value
690 + tree->rel.section->output_section->vma
691 + tree->rel.section->output_offset),
692 NULL,
693 current_section);
694 break;
695
696 case etree_assert:
697 result = exp_fold_tree (tree->assert_s.child,
698 current_section,
699 allocation_done, dot, dotp);
700 if (result.valid_p)
701 {
702 if (! result.value)
703 einfo ("%F%P: %s\n", tree->assert_s.message);
704 return result;
705 }
706 break;
707
708 case etree_unary:
709 result = fold_unary (tree, current_section, allocation_done,
710 dot, dotp);
711 break;
712
713 case etree_binary:
714 result = fold_binary (tree, current_section, allocation_done,
715 dot, dotp);
716 break;
717
718 case etree_trinary:
719 result = fold_trinary (tree, current_section, allocation_done,
720 dot, dotp);
721 break;
722
723 case etree_assign:
724 case etree_provide:
725 case etree_provided:
726 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
727 {
728 /* Assignment to dot can only be done during allocation. */
729 if (tree->type.node_class != etree_assign)
730 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
731 if (allocation_done == lang_allocating_phase_enum
732 || (allocation_done == lang_final_phase_enum
733 && current_section == abs_output_section))
734 {
735 result = exp_fold_tree (tree->assign.src,
736 current_section,
737 allocation_done, dot,
738 dotp);
739 if (! result.valid_p)
740 einfo (_("%F%S invalid assignment to location counter\n"));
741 else
742 {
743 if (current_section == NULL)
744 einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
745 else
746 {
747 bfd_vma nextdot;
748
749 nextdot = (result.value
750 + current_section->bfd_section->vma);
751 if (nextdot < dot
752 && current_section != abs_output_section)
753 einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
754 dot, nextdot);
755 else
756 *dotp = nextdot;
757 }
758 }
759 }
760 }
761 else
762 {
763 result = exp_fold_tree (tree->assign.src,
764 current_section, allocation_done,
765 dot, dotp);
766 if (result.valid_p)
767 {
768 bfd_boolean create;
769 struct bfd_link_hash_entry *h;
770
771 if (tree->type.node_class == etree_assign)
772 create = TRUE;
773 else
774 create = FALSE;
775 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
776 create, FALSE, FALSE);
777 if (h == (struct bfd_link_hash_entry *) NULL)
778 {
779 if (tree->type.node_class == etree_assign)
780 einfo (_("%P%F:%s: hash creation failed\n"),
781 tree->assign.dst);
782 }
783 else if (tree->type.node_class == etree_provide
784 && h->type != bfd_link_hash_undefined
785 && h->type != bfd_link_hash_common)
786 {
787 /* Do nothing. The symbol was defined by some
788 object. */
789 }
790 else
791 {
792 /* FIXME: Should we worry if the symbol is already
793 defined? */
794 h->type = bfd_link_hash_defined;
795 h->u.def.value = result.value;
796 h->u.def.section = result.section->bfd_section;
797 if (tree->type.node_class == etree_provide)
798 tree->type.node_class = etree_provided;
799 }
800 }
801 }
802 break;
803
804 case etree_name:
805 result = fold_name (tree, current_section, allocation_done, dot);
806 break;
807
808 default:
809 FAIL ();
810 break;
811 }
812
813 return result;
814}
815
816static etree_value_type
817exp_fold_tree_no_dot (tree, current_section, allocation_done)
818 etree_type *tree;
819 lang_output_section_statement_type *current_section;
820 lang_phase_type allocation_done;
821{
822 return exp_fold_tree (tree, current_section, allocation_done,
823 (bfd_vma) 0, (bfd_vma *) NULL);
824}
825
826etree_type *
827exp_binop (code, lhs, rhs)
828 int code;
829 etree_type *lhs;
830 etree_type *rhs;
831{
832 etree_type value, *new;
833 etree_value_type r;
834
835 value.type.node_code = code;
836 value.binary.lhs = lhs;
837 value.binary.rhs = rhs;
838 value.type.node_class = etree_binary;
839 r = exp_fold_tree_no_dot (&value,
840 abs_output_section,
841 lang_first_phase_enum);
842 if (r.valid_p)
843 {
844 return exp_intop (r.value);
845 }
846 new = (etree_type *) stat_alloc (sizeof (new->binary));
847 memcpy ((char *) new, (char *) &value, sizeof (new->binary));
848 return new;
849}
850
851etree_type *
852exp_trinop (code, cond, lhs, rhs)
853 int code;
854 etree_type *cond;
855 etree_type *lhs;
856 etree_type *rhs;
857{
858 etree_type value, *new;
859 etree_value_type r;
860 value.type.node_code = code;
861 value.trinary.lhs = lhs;
862 value.trinary.cond = cond;
863 value.trinary.rhs = rhs;
864 value.type.node_class = etree_trinary;
865 r = exp_fold_tree_no_dot (&value,
866 (lang_output_section_statement_type *) NULL,
867 lang_first_phase_enum);
868 if (r.valid_p)
869 return exp_intop (r.value);
870
871 new = (etree_type *) stat_alloc (sizeof (new->trinary));
872 memcpy ((char *) new, (char *) &value, sizeof (new->trinary));
873 return new;
874}
875
876etree_type *
877exp_unop (code, child)
878 int code;
879 etree_type *child;
880{
881 etree_type value, *new;
882
883 etree_value_type r;
884 value.unary.type.node_code = code;
885 value.unary.child = child;
886 value.unary.type.node_class = etree_unary;
887 r = exp_fold_tree_no_dot (&value, abs_output_section,
888 lang_first_phase_enum);
889 if (r.valid_p)
890 return exp_intop (r.value);
891
892 new = (etree_type *) stat_alloc (sizeof (new->unary));
893 memcpy ((char *) new, (char *) &value, sizeof (new->unary));
894 return new;
895}
896
897etree_type *
898exp_nameop (code, name)
899 int code;
900 const char *name;
901{
902 etree_type value, *new;
903 etree_value_type r;
904 value.name.type.node_code = code;
905 value.name.name = name;
906 value.name.type.node_class = etree_name;
907
908 r = exp_fold_tree_no_dot (&value,
909 (lang_output_section_statement_type *) NULL,
910 lang_first_phase_enum);
911 if (r.valid_p)
912 return exp_intop (r.value);
913
914 new = (etree_type *) stat_alloc (sizeof (new->name));
915 memcpy ((char *) new, (char *) &value, sizeof (new->name));
916 return new;
917
918}
919
920etree_type *
921exp_assop (code, dst, src)
922 int code;
923 const char *dst;
924 etree_type *src;
925{
926 etree_type value, *new;
927
928 value.assign.type.node_code = code;
929
930 value.assign.src = src;
931 value.assign.dst = dst;
932 value.assign.type.node_class = etree_assign;
933
934#if 0
935 if (exp_fold_tree_no_dot (&value, &result))
936 return exp_intop (result);
937#endif
938 new = (etree_type *) stat_alloc (sizeof (new->assign));
939 memcpy ((char *) new, (char *) &value, sizeof (new->assign));
940 return new;
941}
942
943/* Handle PROVIDE. */
944
945etree_type *
946exp_provide (dst, src)
947 const char *dst;
948 etree_type *src;
949{
950 etree_type *n;
951
952 n = (etree_type *) stat_alloc (sizeof (n->assign));
953 n->assign.type.node_code = '=';
954 n->assign.type.node_class = etree_provide;
955 n->assign.src = src;
956 n->assign.dst = dst;
957 return n;
958}
959
960/* Handle ASSERT. */
961
962etree_type *
963exp_assert (exp, message)
964 etree_type *exp;
965 const char *message;
966{
967 etree_type *n;
968
969 n = (etree_type *) stat_alloc (sizeof (n->assert_s));
970 n->assert_s.type.node_code = '!';
971 n->assert_s.type.node_class = etree_assert;
972 n->assert_s.child = exp;
973 n->assert_s.message = message;
974 return n;
975}
976
977void
978exp_print_tree (tree)
979 etree_type *tree;
980{
981 if (config.map_file == NULL)
982 config.map_file = stderr;
983
984 if (tree == NULL)
985 {
986 minfo ("NULL TREE\n");
987 return;
988 }
989
990 switch (tree->type.node_class)
991 {
992 case etree_value:
993 minfo ("0x%v", tree->value.value);
994 return;
995 case etree_rel:
996 if (tree->rel.section->owner != NULL)
997 minfo ("%B:", tree->rel.section->owner);
998 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
999 return;
1000 case etree_assign:
1001#if 0
1002 if (tree->assign.dst->sdefs != (asymbol *) NULL)
1003 fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name,
1004 tree->assign.dst->sdefs->value);
1005 else
1006 fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name);
1007#endif
1008 fprintf (config.map_file, "%s", tree->assign.dst);
1009 exp_print_token (tree->type.node_code, TRUE);
1010 exp_print_tree (tree->assign.src);
1011 break;
1012 case etree_provide:
1013 case etree_provided:
1014 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
1015 exp_print_tree (tree->assign.src);
1016 fprintf (config.map_file, ")");
1017 break;
1018 case etree_binary:
1019 fprintf (config.map_file, "(");
1020 exp_print_tree (tree->binary.lhs);
1021 exp_print_token (tree->type.node_code, TRUE);
1022 exp_print_tree (tree->binary.rhs);
1023 fprintf (config.map_file, ")");
1024 break;
1025 case etree_trinary:
1026 exp_print_tree (tree->trinary.cond);
1027 fprintf (config.map_file, "?");
1028 exp_print_tree (tree->trinary.lhs);
1029 fprintf (config.map_file, ":");
1030 exp_print_tree (tree->trinary.rhs);
1031 break;
1032 case etree_unary:
1033 exp_print_token (tree->unary.type.node_code, FALSE);
1034 if (tree->unary.child)
1035 {
1036 fprintf (config.map_file, " (");
1037 exp_print_tree (tree->unary.child);
1038 fprintf (config.map_file, ")");
1039 }
1040 break;
1041
1042 case etree_assert:
1043 fprintf (config.map_file, "ASSERT (");
1044 exp_print_tree (tree->assert_s.child);
1045 fprintf (config.map_file, ", %s)", tree->assert_s.message);
1046 break;
1047
1048 case etree_undef:
1049 fprintf (config.map_file, "????????");
1050 break;
1051 case etree_name:
1052 if (tree->type.node_code == NAME)
1053 {
1054 fprintf (config.map_file, "%s", tree->name.name);
1055 }
1056 else
1057 {
1058 exp_print_token (tree->type.node_code, FALSE);
1059 if (tree->name.name)
1060 fprintf (config.map_file, " (%s)", tree->name.name);
1061 }
1062 break;
1063 default:
1064 FAIL ();
1065 break;
1066 }
1067}
1068
1069bfd_vma
1070exp_get_vma (tree, def, name, allocation_done)
1071 etree_type *tree;
1072 bfd_vma def;
1073 char *name;
1074 lang_phase_type allocation_done;
1075{
1076 etree_value_type r;
1077
1078 if (tree != NULL)
1079 {
1080 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
1081 if (! r.valid_p && name != NULL)
1082 einfo (_("%F%S nonconstant expression for %s\n"), name);
1083 return r.value;
1084 }
1085 else
1086 return def;
1087}
1088
1089int
1090exp_get_value_int (tree, def, name, allocation_done)
1091 etree_type *tree;
1092 int def;
1093 char *name;
1094 lang_phase_type allocation_done;
1095{
1096 return (int) exp_get_vma (tree, (bfd_vma) def, name, allocation_done);
1097}
1098
1099fill_type *
1100exp_get_fill (tree, def, name, allocation_done)
1101 etree_type *tree;
1102 fill_type *def;
1103 char *name;
1104 lang_phase_type allocation_done;
1105{
1106 fill_type *fill;
1107 etree_value_type r;
1108 size_t len;
1109 unsigned int val;
1110
1111 if (tree == NULL)
1112 return def;
1113
1114 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
1115 if (! r.valid_p && name != NULL)
1116 einfo (_("%F%S nonconstant expression for %s\n"), name);
1117
1118 if (r.str != NULL && (len = strlen (r.str)) != 0)
1119 {
1120 unsigned char *dst;
1121 unsigned char *s;
1122 fill = (fill_type *) xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
1123 fill->size = (len + 1) / 2;
1124 dst = fill->data;
1125 s = r.str;
1126 val = 0;
1127 do
1128 {
1129 unsigned int digit;
1130
1131 digit = *s++ - '0';
1132 if (digit > 9)
1133 digit = (digit - 'A' + '0' + 10) & 0xf;
1134 val <<= 4;
1135 val += digit;
1136 --len;
1137 if ((len & 1) == 0)
1138 {
1139 *dst++ = val;
1140 val = 0;
1141 }
1142 }
1143 while (len != 0);
1144 }
1145 else
1146 {
1147 fill = (fill_type *) xmalloc (4 + sizeof (*fill) - 1);
1148 val = r.value;
1149 fill->data[0] = (val >> 24) & 0xff;
1150 fill->data[1] = (val >> 16) & 0xff;
1151 fill->data[2] = (val >> 8) & 0xff;
1152 fill->data[3] = (val >> 0) & 0xff;
1153 fill->size = 4;
1154 }
1155 return fill;
1156}
1157
1158bfd_vma
1159exp_get_abs_int (tree, def, name, allocation_done)
1160 etree_type *tree;
1161 int def ATTRIBUTE_UNUSED;
1162 char *name;
1163 lang_phase_type allocation_done;
1164{
1165 etree_value_type res;
1166 res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
1167
1168 if (res.valid_p)
1169 res.value += res.section->bfd_section->vma;
1170 else
1171 einfo (_("%F%S non constant expression for %s\n"), name);
1172
1173 return res.value;
1174}
1175
1176bfd_vma align_n (value, align)
1177 bfd_vma value;
1178 bfd_vma align;
1179{
1180 if (align <= 1)
1181 return value;
1182
1183 value = (value + align - 1) / align;
1184 return value * align;
1185}
Note: See TracBrowser for help on using the repository browser.