1 /* This module handles expression trees.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
5 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
7 This file is part of GLD, the Gnu Linker.
9 GLD is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GLD is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GLD; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24 /* This module is in charge of working out the contents of expressions.
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
41 #include "libiberty.h"
42 #include "safe-ctype.h"
44 static etree_value_type exp_fold_tree_1
45 (etree_type *, lang_output_section_statement_type *,
46 lang_phase_type, bfd_vma, bfd_vma *, bfd_boolean);
47 static etree_value_type exp_fold_tree_no_dot
48 (etree_type *, lang_output_section_statement_type *, lang_phase_type,
50 static bfd_vma align_n
53 struct exp_data_seg exp_data_seg;
55 segment_type *segments;
57 /* Principally used for diagnostics. */
58 static bfd_boolean assigning_to_dot = FALSE;
60 /* Print the string representation of the given token. Surround it
61 with spaces if INFIX_P is TRUE. */
64 exp_print_token (token_code_type code, int infix_p)
98 { SECTIONS, "SECTIONS" },
99 { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
100 { MEMORY, "MEMORY" },
101 { DEFINED, "DEFINED" },
102 { TARGET_K, "TARGET" },
103 { SEARCH_DIR, "SEARCH_DIR" },
107 { SIZEOF, "SIZEOF" },
109 { LOADADDR, "LOADADDR" },
111 { REL, "relocatable" },
112 { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
113 { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
114 { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
115 { ORIGIN, "ORIGIN" },
116 { LENGTH, "LENGTH" },
117 { SEGMENT_START, "SEGMENT_START" }
121 for (idx = 0; idx < ARRAY_SIZE (table); idx++)
122 if (table[idx].code == code)
126 fputc (' ', config.map_file);
128 if (idx < ARRAY_SIZE (table))
129 fputs (table[idx].name, config.map_file);
131 fputc (code, config.map_file);
133 fprintf (config.map_file, "<code %d>", code);
136 fputc (' ', config.map_file);
140 make_abs (etree_value_type *ptr)
142 asection *s = ptr->section->bfd_section;
143 ptr->value += s->vma;
144 ptr->section = abs_output_section;
147 static etree_value_type
148 new_abs (bfd_vma value)
150 etree_value_type new;
152 new.section = abs_output_section;
159 exp_intop (bfd_vma value)
161 etree_type *new = stat_alloc (sizeof (new->value));
162 new->type.node_code = INT;
163 new->value.value = value;
164 new->value.str = NULL;
165 new->type.node_class = etree_value;
170 exp_bigintop (bfd_vma value, char *str)
172 etree_type *new = stat_alloc (sizeof (new->value));
173 new->type.node_code = INT;
174 new->value.value = value;
175 new->value.str = str;
176 new->type.node_class = etree_value;
180 /* Build an expression representing an unnamed relocatable value. */
183 exp_relop (asection *section, bfd_vma value)
185 etree_type *new = stat_alloc (sizeof (new->rel));
186 new->type.node_code = REL;
187 new->type.node_class = etree_rel;
188 new->rel.section = section;
189 new->rel.value = value;
193 static etree_value_type
194 new_rel (bfd_vma value,
196 lang_output_section_statement_type *section)
198 etree_value_type new;
202 new.section = section;
206 static etree_value_type
207 new_rel_from_section (bfd_vma value,
208 lang_output_section_statement_type *section)
210 etree_value_type new;
214 new.section = section;
216 new.value -= section->bfd_section->vma;
221 static etree_value_type
222 fold_unary (etree_type *tree,
223 lang_output_section_statement_type *current_section,
224 lang_phase_type allocation_done,
227 bfd_boolean mark_used)
229 etree_value_type result;
231 result = exp_fold_tree_1 (tree->unary.child,
233 allocation_done, dot, dotp, mark_used);
236 switch (tree->type.node_code)
239 if (allocation_done != lang_first_phase_enum)
240 result = new_rel_from_section (align_n (dot, result.value),
243 result.valid_p = FALSE;
247 if (allocation_done != lang_first_phase_enum)
249 result.value += result.section->bfd_section->vma;
250 result.section = abs_output_section;
253 result.valid_p = FALSE;
258 result.value = ~result.value;
263 result.value = !result.value;
268 result.value = -result.value;
272 /* Return next place aligned to value. */
273 if (allocation_done == lang_allocating_phase_enum)
276 result.value = align_n (dot, result.value);
279 result.valid_p = FALSE;
282 case DATA_SEGMENT_END:
283 if (allocation_done != lang_first_phase_enum
284 && current_section == abs_output_section
285 && (exp_data_seg.phase == exp_dataseg_align_seen
286 || exp_data_seg.phase == exp_dataseg_relro_seen
287 || exp_data_seg.phase == exp_dataseg_adjust
288 || exp_data_seg.phase == exp_dataseg_relro_adjust
289 || allocation_done != lang_allocating_phase_enum))
291 if (exp_data_seg.phase == exp_dataseg_align_seen
292 || exp_data_seg.phase == exp_dataseg_relro_seen)
294 exp_data_seg.phase = exp_dataseg_end_seen;
295 exp_data_seg.end = result.value;
299 result.valid_p = FALSE;
311 static etree_value_type
312 fold_binary (etree_type *tree,
313 lang_output_section_statement_type *current_section,
314 lang_phase_type allocation_done,
317 bfd_boolean mark_used)
319 etree_value_type result;
321 result = exp_fold_tree_1 (tree->binary.lhs, current_section,
322 allocation_done, dot, dotp, mark_used);
324 /* The SEGMENT_START operator is special because its first
325 operand is a string, not the name of a symbol. */
326 if (result.valid_p && tree->type.node_code == SEGMENT_START)
328 const char *segment_name;
330 /* Check to see if the user has overridden the default
332 segment_name = tree->binary.rhs->name.name;
333 for (seg = segments; seg; seg = seg->next)
334 if (strcmp (seg->name, segment_name) == 0)
337 result.value = seg->value;
339 result.section = NULL;
343 else if (result.valid_p)
345 etree_value_type other;
347 other = exp_fold_tree_1 (tree->binary.rhs,
350 dot, dotp, mark_used);
353 /* If the values are from different sections, or this is an
354 absolute expression, make both the source arguments
355 absolute. However, adding or subtracting an absolute
356 value from a relative value is meaningful, and is an
358 if (current_section != abs_output_section
359 && (other.section == abs_output_section
360 || (result.section == abs_output_section
361 && tree->type.node_code == '+'))
362 && (tree->type.node_code == '+'
363 || tree->type.node_code == '-'))
365 if (other.section != abs_output_section)
367 /* Keep the section of the other term. */
368 if (tree->type.node_code == '+')
369 other.value = result.value + other.value;
371 other.value = result.value - other.value;
375 else if (result.section != other.section
376 || current_section == abs_output_section)
382 switch (tree->type.node_code)
385 if (other.value == 0)
386 einfo (_("%F%S %% by zero\n"));
387 result.value = ((bfd_signed_vma) result.value
388 % (bfd_signed_vma) other.value);
392 if (other.value == 0)
393 einfo (_("%F%S / by zero\n"));
394 result.value = ((bfd_signed_vma) result.value
395 / (bfd_signed_vma) other.value);
398 #define BOP(x,y) case x : result.value = result.value y other.value; break;
417 if (result.value < other.value)
422 if (result.value > other.value)
427 result.value = align_n (result.value, other.value);
430 case DATA_SEGMENT_ALIGN:
431 if (allocation_done != lang_first_phase_enum
432 && current_section == abs_output_section
433 && (exp_data_seg.phase == exp_dataseg_none
434 || exp_data_seg.phase == exp_dataseg_adjust
435 || exp_data_seg.phase == exp_dataseg_relro_adjust
436 || allocation_done != lang_allocating_phase_enum))
438 bfd_vma maxpage = result.value;
440 result.value = align_n (dot, maxpage);
441 if (exp_data_seg.phase == exp_dataseg_relro_adjust)
442 result.value = exp_data_seg.base;
443 else if (exp_data_seg.phase != exp_dataseg_adjust)
445 result.value += dot & (maxpage - 1);
446 if (allocation_done == lang_allocating_phase_enum)
448 exp_data_seg.phase = exp_dataseg_align_seen;
449 exp_data_seg.min_base = align_n (dot, maxpage);
450 exp_data_seg.base = result.value;
451 exp_data_seg.pagesize = other.value;
452 exp_data_seg.maxpagesize = maxpage;
453 exp_data_seg.relro_end = 0;
456 else if (other.value < maxpage)
457 result.value += (dot + other.value - 1)
458 & (maxpage - other.value);
461 result.valid_p = FALSE;
464 case DATA_SEGMENT_RELRO_END:
465 if (allocation_done != lang_first_phase_enum
466 && (exp_data_seg.phase == exp_dataseg_align_seen
467 || exp_data_seg.phase == exp_dataseg_adjust
468 || exp_data_seg.phase == exp_dataseg_relro_adjust
469 || allocation_done != lang_allocating_phase_enum))
471 if (exp_data_seg.phase == exp_dataseg_align_seen
472 || exp_data_seg.phase == exp_dataseg_relro_adjust)
473 exp_data_seg.relro_end
474 = result.value + other.value;
475 if (exp_data_seg.phase == exp_dataseg_relro_adjust
476 && (exp_data_seg.relro_end
477 & (exp_data_seg.pagesize - 1)))
479 exp_data_seg.relro_end += exp_data_seg.pagesize - 1;
480 exp_data_seg.relro_end &= ~(exp_data_seg.pagesize - 1);
481 result.value = exp_data_seg.relro_end - other.value;
483 if (exp_data_seg.phase == exp_dataseg_align_seen)
484 exp_data_seg.phase = exp_dataseg_relro_seen;
487 result.valid_p = FALSE;
496 result.valid_p = FALSE;
503 static etree_value_type
504 fold_trinary (etree_type *tree,
505 lang_output_section_statement_type *current_section,
506 lang_phase_type allocation_done,
509 bfd_boolean mark_used)
511 etree_value_type result;
513 result = exp_fold_tree_1 (tree->trinary.cond, current_section,
514 allocation_done, dot, dotp, mark_used);
516 result = exp_fold_tree_1 ((result.value
518 : tree->trinary.rhs),
521 dot, dotp, mark_used);
526 static etree_value_type
527 fold_name (etree_type *tree,
528 lang_output_section_statement_type *current_section,
529 lang_phase_type allocation_done,
531 bfd_boolean mark_used)
533 etree_value_type result;
535 result.valid_p = FALSE;
537 switch (tree->type.node_code)
540 if (allocation_done != lang_first_phase_enum)
541 result = new_abs (bfd_sizeof_headers (output_bfd,
542 link_info.relocatable));
545 if (allocation_done == lang_first_phase_enum)
546 lang_track_definedness (tree->name.name);
549 struct bfd_link_hash_entry *h;
551 = lang_symbol_definition_iteration (tree->name.name);
553 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
556 result.value = (h != NULL
557 && (h->type == bfd_link_hash_defined
558 || h->type == bfd_link_hash_defweak
559 || h->type == bfd_link_hash_common)
560 && (def_iteration == lang_statement_iteration
561 || def_iteration == -1));
562 result.section = abs_output_section;
563 result.valid_p = TRUE;
567 if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
569 if (allocation_done != lang_first_phase_enum)
570 result = new_rel_from_section (dot, current_section);
572 else if (allocation_done != lang_first_phase_enum)
574 struct bfd_link_hash_entry *h;
576 h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
580 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
581 else if (h->type == bfd_link_hash_defined
582 || h->type == bfd_link_hash_defweak)
584 if (bfd_is_abs_section (h->u.def.section))
585 result = new_abs (h->u.def.value);
586 else if (allocation_done == lang_final_phase_enum
587 || allocation_done == lang_allocating_phase_enum)
589 asection *output_section;
591 output_section = h->u.def.section->output_section;
592 if (output_section == NULL)
593 einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
597 lang_output_section_statement_type *os;
599 os = (lang_output_section_statement_lookup
600 (bfd_get_section_name (output_bfd,
603 /* FIXME: Is this correct if this section is
604 being linked with -R? */
605 result = new_rel ((h->u.def.value
606 + h->u.def.section->output_offset),
609 os->bfd_section->flags |= SEC_KEEP;
613 else if (allocation_done == lang_final_phase_enum
615 einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
617 else if (h->type == bfd_link_hash_new)
619 h->type = bfd_link_hash_undefined;
620 h->u.undef.abfd = NULL;
621 if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
622 bfd_link_add_undef (link_info.hash, h);
628 if (allocation_done != lang_first_phase_enum)
630 lang_output_section_statement_type *os;
632 os = lang_output_section_find (tree->name.name);
635 os->bfd_section->flags |= SEC_KEEP;
636 if (os->processed > 0)
637 result = new_rel (0, NULL, os);
643 if (allocation_done != lang_first_phase_enum)
645 lang_output_section_statement_type *os;
647 os = lang_output_section_find (tree->name.name);
650 os->bfd_section->flags |= SEC_KEEP;
651 if (os->processed != 0)
653 if (os->load_base == NULL)
654 result = new_rel (0, NULL, os);
656 result = exp_fold_tree_no_dot (os->load_base,
666 if (allocation_done != lang_first_phase_enum)
668 int opb = bfd_octets_per_byte (output_bfd);
669 lang_output_section_statement_type *os;
671 os = lang_output_section_find (tree->name.name);
674 os->bfd_section->flags |= SEC_KEEP;
675 if (os->processed > 0)
676 result = new_abs (os->bfd_section->size / opb);
683 lang_memory_region_type *mem;
685 mem = lang_memory_region_lookup (tree->name.name, FALSE);
687 result = new_abs (mem->length);
689 einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
696 lang_memory_region_type *mem;
698 mem = lang_memory_region_lookup (tree->name.name, FALSE);
700 result = new_abs (mem->origin);
702 einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
715 static etree_value_type
716 exp_fold_tree_1 (etree_type *tree,
717 lang_output_section_statement_type *current_section,
718 lang_phase_type allocation_done,
721 bfd_boolean mark_used)
723 etree_value_type result;
727 memset (&result, 0, sizeof (result));
731 switch (tree->type.node_class)
734 result = new_rel (tree->value.value, tree->value.str, current_section);
738 if (allocation_done != lang_final_phase_enum)
739 memset (&result, 0, sizeof (result));
741 result = new_rel ((tree->rel.value
742 + tree->rel.section->output_section->vma
743 + tree->rel.section->output_offset),
749 result = exp_fold_tree_1 (tree->assert_s.child,
751 allocation_done, dot, dotp,
756 /* We don't care if assert fails or not when we are just
757 marking if a section is used or not. */
759 else if (!result.value)
760 einfo ("%X%P: %s\n", tree->assert_s.message);
765 result = fold_unary (tree, current_section, allocation_done,
766 dot, dotp, mark_used);
770 result = fold_binary (tree, current_section, allocation_done,
771 dot, dotp, mark_used);
775 result = fold_trinary (tree, current_section, allocation_done,
776 dot, dotp, mark_used);
782 if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
784 /* Assignment to dot can only be done during allocation. */
785 if (tree->type.node_class != etree_assign)
786 einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
787 if (allocation_done == lang_allocating_phase_enum
788 || (allocation_done == lang_final_phase_enum
789 && current_section == abs_output_section))
791 /* Notify the folder that this is an assignment to dot. */
792 assigning_to_dot = TRUE;
793 result = exp_fold_tree_1 (tree->assign.src,
796 dot, dotp, mark_used);
797 assigning_to_dot = FALSE;
799 if (! result.valid_p)
800 einfo (_("%F%S invalid assignment to location counter\n"));
803 if (current_section == NULL)
804 einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
809 nextdot = (result.value
810 + current_section->bfd_section->vma);
812 && current_section != abs_output_section)
813 einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
821 memset (&result, 0, sizeof (result));
825 result = exp_fold_tree_1 (tree->assign.src,
826 current_section, allocation_done,
827 dot, dotp, mark_used);
831 struct bfd_link_hash_entry *h;
833 if (tree->type.node_class == etree_assign)
837 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
838 create, FALSE, TRUE);
842 einfo (_("%P%F:%s: hash creation failed\n"),
845 else if (tree->type.node_class == etree_provide
846 && h->type != bfd_link_hash_new
847 && h->type != bfd_link_hash_undefined
848 && h->type != bfd_link_hash_common)
850 /* Do nothing. The symbol was defined by some
855 /* FIXME: Should we worry if the symbol is already
857 lang_update_definedness (tree->assign.dst, h);
858 h->type = bfd_link_hash_defined;
859 h->u.def.value = result.value;
860 h->u.def.section = result.section->bfd_section;
861 if (tree->type.node_class == etree_provide)
862 tree->type.node_class = etree_provided;
869 result = fold_name (tree, current_section, allocation_done, dot,
875 memset (&result, 0, sizeof (result));
883 exp_fold_tree (etree_type *tree,
884 lang_output_section_statement_type *current_section,
885 lang_phase_type allocation_done,
889 return exp_fold_tree_1 (tree, current_section, allocation_done,
893 static etree_value_type
894 exp_fold_tree_no_dot (etree_type *tree,
895 lang_output_section_statement_type *current_section,
896 lang_phase_type allocation_done,
897 bfd_boolean mark_used)
899 return exp_fold_tree_1 (tree, current_section, allocation_done, 0,
904 exp_binop (int code, etree_type *lhs, etree_type *rhs)
906 etree_type value, *new;
909 value.type.node_code = code;
910 value.binary.lhs = lhs;
911 value.binary.rhs = rhs;
912 value.type.node_class = etree_binary;
913 r = exp_fold_tree_no_dot (&value,
915 lang_first_phase_enum, FALSE);
918 return exp_intop (r.value);
920 new = stat_alloc (sizeof (new->binary));
921 memcpy (new, &value, sizeof (new->binary));
926 exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
928 etree_type value, *new;
930 value.type.node_code = code;
931 value.trinary.lhs = lhs;
932 value.trinary.cond = cond;
933 value.trinary.rhs = rhs;
934 value.type.node_class = etree_trinary;
935 r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE);
937 return exp_intop (r.value);
939 new = stat_alloc (sizeof (new->trinary));
940 memcpy (new, &value, sizeof (new->trinary));
945 exp_unop (int code, etree_type *child)
947 etree_type value, *new;
950 value.unary.type.node_code = code;
951 value.unary.child = child;
952 value.unary.type.node_class = etree_unary;
953 r = exp_fold_tree_no_dot (&value, abs_output_section,
954 lang_first_phase_enum, FALSE);
956 return exp_intop (r.value);
958 new = stat_alloc (sizeof (new->unary));
959 memcpy (new, &value, sizeof (new->unary));
964 exp_nameop (int code, const char *name)
966 etree_type value, *new;
968 value.name.type.node_code = code;
969 value.name.name = name;
970 value.name.type.node_class = etree_name;
972 r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE);
974 return exp_intop (r.value);
976 new = stat_alloc (sizeof (new->name));
977 memcpy (new, &value, sizeof (new->name));
983 exp_assop (int code, const char *dst, etree_type *src)
985 etree_type value, *new;
987 value.assign.type.node_code = code;
989 value.assign.src = src;
990 value.assign.dst = dst;
991 value.assign.type.node_class = etree_assign;
993 new = stat_alloc (sizeof (new->assign));
994 memcpy (new, &value, sizeof (new->assign));
998 /* Handle PROVIDE. */
1001 exp_provide (const char *dst, etree_type *src)
1005 n = stat_alloc (sizeof (n->assign));
1006 n->assign.type.node_code = '=';
1007 n->assign.type.node_class = etree_provide;
1008 n->assign.src = src;
1009 n->assign.dst = dst;
1013 /* Handle ASSERT. */
1016 exp_assert (etree_type *exp, const char *message)
1020 n = stat_alloc (sizeof (n->assert_s));
1021 n->assert_s.type.node_code = '!';
1022 n->assert_s.type.node_class = etree_assert;
1023 n->assert_s.child = exp;
1024 n->assert_s.message = message;
1029 exp_print_tree (etree_type *tree)
1031 if (config.map_file == NULL)
1032 config.map_file = stderr;
1036 minfo ("NULL TREE\n");
1040 switch (tree->type.node_class)
1043 minfo ("0x%v", tree->value.value);
1046 if (tree->rel.section->owner != NULL)
1047 minfo ("%B:", tree->rel.section->owner);
1048 minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
1051 fprintf (config.map_file, "%s", tree->assign.dst);
1052 exp_print_token (tree->type.node_code, TRUE);
1053 exp_print_tree (tree->assign.src);
1056 case etree_provided:
1057 fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
1058 exp_print_tree (tree->assign.src);
1059 fprintf (config.map_file, ")");
1062 fprintf (config.map_file, "(");
1063 exp_print_tree (tree->binary.lhs);
1064 exp_print_token (tree->type.node_code, TRUE);
1065 exp_print_tree (tree->binary.rhs);
1066 fprintf (config.map_file, ")");
1069 exp_print_tree (tree->trinary.cond);
1070 fprintf (config.map_file, "?");
1071 exp_print_tree (tree->trinary.lhs);
1072 fprintf (config.map_file, ":");
1073 exp_print_tree (tree->trinary.rhs);
1076 exp_print_token (tree->unary.type.node_code, FALSE);
1077 if (tree->unary.child)
1079 fprintf (config.map_file, " (");
1080 exp_print_tree (tree->unary.child);
1081 fprintf (config.map_file, ")");
1086 fprintf (config.map_file, "ASSERT (");
1087 exp_print_tree (tree->assert_s.child);
1088 fprintf (config.map_file, ", %s)", tree->assert_s.message);
1092 fprintf (config.map_file, "????????");
1095 if (tree->type.node_code == NAME)
1097 fprintf (config.map_file, "%s", tree->name.name);
1101 exp_print_token (tree->type.node_code, FALSE);
1102 if (tree->name.name)
1103 fprintf (config.map_file, " (%s)", tree->name.name);
1113 exp_get_vma (etree_type *tree,
1116 lang_phase_type allocation_done)
1122 r = exp_fold_tree_no_dot (tree, abs_output_section,
1123 allocation_done, FALSE);
1124 if (! r.valid_p && name != NULL)
1125 einfo (_("%F%S nonconstant expression for %s\n"), name);
1133 exp_get_value_int (etree_type *tree,
1136 lang_phase_type allocation_done)
1138 return exp_get_vma (tree, def, name, allocation_done);
1142 exp_get_fill (etree_type *tree,
1145 lang_phase_type allocation_done)
1155 r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done,
1157 if (! r.valid_p && name != NULL)
1158 einfo (_("%F%S nonconstant expression for %s\n"), name);
1160 if (r.str != NULL && (len = strlen (r.str)) != 0)
1164 fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
1165 fill->size = (len + 1) / 2;
1167 s = (unsigned char *) r.str;
1175 digit = (digit - 'A' + '0' + 10) & 0xf;
1189 fill = xmalloc (4 + sizeof (*fill) - 1);
1191 fill->data[0] = (val >> 24) & 0xff;
1192 fill->data[1] = (val >> 16) & 0xff;
1193 fill->data[2] = (val >> 8) & 0xff;
1194 fill->data[3] = (val >> 0) & 0xff;
1201 exp_get_abs_int (etree_type *tree,
1202 int def ATTRIBUTE_UNUSED,
1204 lang_phase_type allocation_done)
1206 etree_value_type res;
1207 res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done,
1211 res.value += res.section->bfd_section->vma;
1213 einfo (_("%F%S non constant expression for %s\n"), name);
1219 align_n (bfd_vma value, bfd_vma align)
1224 value = (value + align - 1) / align;
1225 return value * align;
1229 exp_mark_used_section
1231 lang_output_section_statement_type *current_section)
1233 switch (tree->type.node_class)
1255 case etree_provided:
1256 if (tree->assign.dst[0] != '.' || tree->assign.dst[1] != 0)
1258 etree_value_type result;
1261 result = exp_fold_tree_1 (tree->assign.src,
1263 lang_allocating_phase_enum,
1268 struct bfd_link_hash_entry *h;
1270 if (tree->type.node_class == etree_assign)
1274 h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
1275 create, FALSE, TRUE);
1279 einfo (_("%P%F:%s: hash creation failed\n"),
1282 else if (tree->type.node_class == etree_provide
1283 && h->type != bfd_link_hash_new
1284 && h->type != bfd_link_hash_undefined
1285 && h->type != bfd_link_hash_common)
1287 /* Do nothing. The symbol was defined by some
1292 /* FIXME: Should we worry if the symbol is already
1294 lang_update_definedness (tree->assign.dst, h);
1295 h->type = bfd_link_hash_defined;
1296 h->u.def.value = result.value;
1297 h->u.def.section = result.section->bfd_section;
1298 if (tree->type.node_class == etree_provide)
1299 tree->type.node_class = etree_provided;
1306 fold_name (tree, current_section, lang_allocating_phase_enum, 0,