Rev 5199 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5199 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* This module handles expression trees. |
1 | /* This module handles expression trees. |
2 | Copyright 1991-2013 Free Software Foundation, Inc. |
2 | Copyright (C) 1991-2015 Free Software Foundation, Inc. |
3 | Written by Steve Chamberlain of Cygnus Support |
3 | Written by Steve Chamberlain of Cygnus Support |
Line 4... | Line 4... | ||
4 | 4 | ||
Line 5... | Line 5... | ||
5 | This file is part of the GNU Binutils. |
5 | This file is part of the GNU Binutils. |
Line 46... | Line 46... | ||
46 | 46 | ||
Line 47... | Line 47... | ||
47 | segment_type *segments; |
47 | segment_type *segments; |
Line -... | Line 48... | ||
- | 48 | ||
- | 49 | struct ldexp_control expld; |
|
- | 50 | ||
- | 51 | /* This structure records symbols for which we need to keep track of |
|
- | 52 | definedness for use in the DEFINED () test. It is also used in |
|
- | 53 | making absolute symbols section relative late in the link. */ |
|
- | 54 | ||
- | 55 | struct definedness_hash_entry |
|
- | 56 | { |
|
- | 57 | struct bfd_hash_entry root; |
|
- | 58 | ||
- | 59 | /* If this symbol was assigned from "dot" outside of an output |
|
- | 60 | section statement, the section we'd like it relative to. */ |
|
- | 61 | asection *final_sec; |
|
- | 62 | ||
- | 63 | /* Symbol was defined by an object file. */ |
|
- | 64 | unsigned int by_object : 1; |
|
- | 65 | ||
- | 66 | /* Symbols was defined by a script. */ |
|
- | 67 | unsigned int by_script : 1; |
|
- | 68 | ||
- | 69 | /* Low bit of iteration count. Symbols with matching iteration have |
|
- | 70 | been defined in this pass over the script. */ |
|
- | 71 | unsigned int iteration : 1; |
|
- | 72 | }; |
|
48 | 73 | ||
49 | struct ldexp_control expld; |
74 | static struct bfd_hash_table definedness_table; |
Line 50... | Line 75... | ||
50 | 75 | ||
51 | /* Print the string representation of the given token. Surround it |
76 | /* Print the string representation of the given token. Surround it |
Line 159... | Line 184... | ||
159 | make_abs (void) |
184 | make_abs (void) |
160 | { |
185 | { |
161 | if (expld.result.section != NULL) |
186 | if (expld.result.section != NULL) |
162 | expld.result.value += expld.result.section->vma; |
187 | expld.result.value += expld.result.section->vma; |
163 | expld.result.section = bfd_abs_section_ptr; |
188 | expld.result.section = bfd_abs_section_ptr; |
- | 189 | expld.rel_from_abs = FALSE; |
|
164 | } |
190 | } |
Line 165... | Line 191... | ||
165 | 191 | ||
166 | static void |
192 | static void |
167 | new_abs (bfd_vma value) |
193 | new_abs (bfd_vma value) |
Line 234... | Line 260... | ||
234 | static void |
260 | static void |
235 | new_rel_from_abs (bfd_vma value) |
261 | new_rel_from_abs (bfd_vma value) |
236 | { |
262 | { |
237 | asection *s = expld.section; |
263 | asection *s = expld.section; |
Line 238... | Line -... | ||
238 | - | ||
239 | if (s == bfd_abs_section_ptr && expld.phase == lang_final_phase_enum) |
264 | |
240 | s = section_for_dot (); |
265 | expld.rel_from_abs = TRUE; |
241 | expld.result.valid_p = TRUE; |
266 | expld.result.valid_p = TRUE; |
242 | expld.result.value = value - s->vma; |
267 | expld.result.value = value - s->vma; |
243 | expld.result.str = NULL; |
268 | expld.result.str = NULL; |
244 | expld.result.section = s; |
269 | expld.result.section = s; |
Line -... | Line 270... | ||
- | 270 | } |
|
- | 271 | ||
- | 272 | /* New-function for the definedness hash table. */ |
|
- | 273 | ||
- | 274 | static struct bfd_hash_entry * |
|
- | 275 | definedness_newfunc (struct bfd_hash_entry *entry, |
|
- | 276 | struct bfd_hash_table *table ATTRIBUTE_UNUSED, |
|
- | 277 | const char *name ATTRIBUTE_UNUSED) |
|
- | 278 | { |
|
- | 279 | struct definedness_hash_entry *ret = (struct definedness_hash_entry *) entry; |
|
- | 280 | ||
- | 281 | if (ret == NULL) |
|
- | 282 | ret = (struct definedness_hash_entry *) |
|
- | 283 | bfd_hash_allocate (table, sizeof (struct definedness_hash_entry)); |
|
- | 284 | ||
- | 285 | if (ret == NULL) |
|
- | 286 | einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name); |
|
- | 287 | ||
- | 288 | ret->by_object = 0; |
|
- | 289 | ret->by_script = 0; |
|
- | 290 | ret->iteration = 0; |
|
- | 291 | return &ret->root; |
|
- | 292 | } |
|
- | 293 | ||
- | 294 | /* Called during processing of linker script script expressions. |
|
- | 295 | For symbols assigned in a linker script, return a struct describing |
|
- | 296 | where the symbol is defined relative to the current expression, |
|
- | 297 | otherwise return NULL. */ |
|
- | 298 | ||
- | 299 | static struct definedness_hash_entry * |
|
- | 300 | symbol_defined (const char *name) |
|
- | 301 | { |
|
- | 302 | return ((struct definedness_hash_entry *) |
|
- | 303 | bfd_hash_lookup (&definedness_table, name, FALSE, FALSE)); |
|
- | 304 | } |
|
- | 305 | ||
- | 306 | /* Update the definedness state of NAME. Return FALSE if script symbol |
|
- | 307 | is multiply defining a strong symbol in an object. */ |
|
- | 308 | ||
- | 309 | static bfd_boolean |
|
- | 310 | update_definedness (const char *name, struct bfd_link_hash_entry *h) |
|
- | 311 | { |
|
- | 312 | bfd_boolean ret; |
|
- | 313 | struct definedness_hash_entry *defentry |
|
- | 314 | = (struct definedness_hash_entry *) |
|
- | 315 | bfd_hash_lookup (&definedness_table, name, TRUE, FALSE); |
|
- | 316 | ||
- | 317 | if (defentry == NULL) |
|
- | 318 | einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name); |
|
- | 319 | ||
- | 320 | /* If the symbol was already defined, and not by a script, then it |
|
- | 321 | must be defined by an object file or by the linker target code. */ |
|
- | 322 | ret = TRUE; |
|
- | 323 | if (!defentry->by_script |
|
- | 324 | && (h->type == bfd_link_hash_defined |
|
- | 325 | || h->type == bfd_link_hash_defweak |
|
- | 326 | || h->type == bfd_link_hash_common)) |
|
- | 327 | { |
|
- | 328 | defentry->by_object = 1; |
|
- | 329 | if (h->type == bfd_link_hash_defined |
|
- | 330 | && h->u.def.section->output_section != NULL |
|
- | 331 | && !h->linker_def) |
|
- | 332 | ret = FALSE; |
|
- | 333 | } |
|
- | 334 | ||
- | 335 | defentry->by_script = 1; |
|
- | 336 | defentry->iteration = lang_statement_iteration; |
|
- | 337 | defentry->final_sec = bfd_abs_section_ptr; |
|
- | 338 | if (expld.phase == lang_final_phase_enum |
|
- | 339 | && expld.rel_from_abs |
|
- | 340 | && expld.result.section == bfd_abs_section_ptr) |
|
- | 341 | defentry->final_sec = section_for_dot (); |
|
- | 342 | return ret; |
|
245 | } |
343 | } |
246 | 344 | ||
247 | static void |
345 | static void |
248 | fold_unary (etree_type *tree) |
346 | fold_unary (etree_type *tree) |
249 | { |
347 | { |
Line 492... | Line 590... | ||
492 | /* OK. */ |
590 | /* OK. */ |
493 | } |
591 | } |
494 | else if (expld.dataseg.phase == exp_dataseg_none) |
592 | else if (expld.dataseg.phase == exp_dataseg_none) |
495 | { |
593 | { |
496 | expld.dataseg.phase = exp_dataseg_align_seen; |
594 | expld.dataseg.phase = exp_dataseg_align_seen; |
497 | expld.dataseg.min_base = expld.dot; |
- | |
498 | expld.dataseg.base = expld.result.value; |
595 | expld.dataseg.base = expld.result.value; |
499 | expld.dataseg.pagesize = commonpage; |
596 | expld.dataseg.pagesize = commonpage; |
500 | expld.dataseg.maxpagesize = maxpage; |
597 | expld.dataseg.maxpagesize = maxpage; |
501 | expld.dataseg.relro_end = 0; |
598 | expld.dataseg.relro_end = 0; |
502 | } |
599 | } |
Line 505... | Line 602... | ||
505 | } |
602 | } |
506 | } |
603 | } |
507 | break; |
604 | break; |
Line 508... | Line 605... | ||
508 | 605 | ||
- | 606 | case DATA_SEGMENT_RELRO_END: |
|
- | 607 | /* Operands swapped! DATA_SEGMENT_RELRO_END(offset,exp) |
|
509 | case DATA_SEGMENT_RELRO_END: |
608 | has offset in expld.result and exp in lhs. */ |
- | 609 | expld.dataseg.relro = exp_dataseg_relro_end; |
|
510 | expld.dataseg.relro = exp_dataseg_relro_end; |
610 | expld.dataseg.relro_offset = expld.result.value; |
511 | if (expld.phase == lang_first_phase_enum |
611 | if (expld.phase == lang_first_phase_enum |
512 | || expld.section != bfd_abs_section_ptr) |
612 | || expld.section != bfd_abs_section_ptr) |
513 | expld.result.valid_p = FALSE; |
613 | expld.result.valid_p = FALSE; |
514 | else if (expld.dataseg.phase == exp_dataseg_align_seen |
614 | else if (expld.dataseg.phase == exp_dataseg_align_seen |
Line 573... | Line 673... | ||
573 | new_number (hdr_size); |
673 | new_number (hdr_size); |
574 | } |
674 | } |
575 | break; |
675 | break; |
Line 576... | Line 676... | ||
576 | 676 | ||
577 | case DEFINED: |
677 | case DEFINED: |
578 | if (expld.phase == lang_first_phase_enum) |
- | |
579 | lang_track_definedness (tree->name.name); |
- | |
580 | else |
678 | if (expld.phase != lang_first_phase_enum) |
581 | { |
679 | { |
582 | struct bfd_link_hash_entry *h; |
- | |
583 | int def_iteration |
680 | struct bfd_link_hash_entry *h; |
Line 584... | Line 681... | ||
584 | = lang_symbol_definition_iteration (tree->name.name); |
681 | struct definedness_hash_entry *def; |
585 | 682 | ||
586 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
683 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
587 | &link_info, |
684 | &link_info, |
588 | tree->name.name, |
685 | tree->name.name, |
589 | FALSE, FALSE, TRUE); |
686 | FALSE, FALSE, TRUE); |
590 | new_number (h != NULL |
687 | new_number (h != NULL |
591 | && (h->type == bfd_link_hash_defined |
688 | && (h->type == bfd_link_hash_defined |
592 | || h->type == bfd_link_hash_defweak |
689 | || h->type == bfd_link_hash_defweak |
593 | || h->type == bfd_link_hash_common) |
690 | || h->type == bfd_link_hash_common) |
- | 691 | && ((def = symbol_defined (tree->name.name)) == NULL |
|
594 | && (def_iteration == lang_statement_iteration |
692 | || def->by_object |
595 | || def_iteration == -1)); |
693 | || def->iteration == (lang_statement_iteration & 1))); |
Line 596... | Line 694... | ||
596 | } |
694 | } |
597 | break; |
695 | break; |
598 | 696 | ||
- | 697 | case NAME: |
|
- | 698 | if (expld.assign_name != NULL |
|
- | 699 | && strcmp (expld.assign_name, tree->name.name) == 0) |
|
- | 700 | { |
|
- | 701 | /* Self-assignment is only allowed for absolute symbols |
|
- | 702 | defined in a linker script. */ |
|
- | 703 | struct bfd_link_hash_entry *h; |
|
- | 704 | struct definedness_hash_entry *def; |
|
- | 705 | ||
- | 706 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
|
- | 707 | &link_info, |
|
- | 708 | tree->name.name, |
|
- | 709 | FALSE, FALSE, TRUE); |
|
- | 710 | if (!(h != NULL |
|
- | 711 | && (h->type == bfd_link_hash_defined |
|
- | 712 | || h->type == bfd_link_hash_defweak) |
|
599 | case NAME: |
713 | && h->u.def.section == bfd_abs_section_ptr |
- | 714 | && (def = symbol_defined (tree->name.name)) != NULL |
|
600 | if (expld.assign_name != NULL |
715 | && def->iteration == (lang_statement_iteration & 1))) |
601 | && strcmp (expld.assign_name, tree->name.name) == 0) |
716 | expld.assign_name = NULL; |
602 | expld.assign_name = NULL; |
717 | } |
603 | if (expld.phase == lang_first_phase_enum) |
718 | if (expld.phase == lang_first_phase_enum) |
604 | ; |
719 | ; |
Line 730... | Line 845... | ||
730 | } |
845 | } |
731 | break; |
846 | break; |
Line 732... | Line 847... | ||
732 | 847 | ||
733 | case LENGTH: |
848 | case LENGTH: |
- | 849 | { |
|
- | 850 | if (expld.phase != lang_first_phase_enum) |
|
734 | { |
851 | { |
Line 735... | Line 852... | ||
735 | lang_memory_region_type *mem; |
852 | lang_memory_region_type *mem; |
736 | 853 | ||
737 | mem = lang_memory_region_lookup (tree->name.name, FALSE); |
854 | mem = lang_memory_region_lookup (tree->name.name, FALSE); |
738 | if (mem != NULL) |
855 | if (mem != NULL) |
739 | new_number (mem->length); |
856 | new_number (mem->length); |
740 | else |
857 | else |
741 | einfo (_("%F%S: undefined MEMORY region `%s'" |
858 | einfo (_("%F%S: undefined MEMORY region `%s'" |
742 | " referenced in expression\n"), |
859 | " referenced in expression\n"), |
- | 860 | tree, tree->name.name); |
|
743 | tree, tree->name.name); |
861 | } |
Line 744... | Line 862... | ||
744 | } |
862 | } |
745 | break; |
863 | break; |
746 | 864 | ||
Line 773... | Line 891... | ||
773 | FAIL (); |
891 | FAIL (); |
774 | break; |
892 | break; |
775 | } |
893 | } |
776 | } |
894 | } |
Line -... | Line 895... | ||
- | 895 | ||
- | 896 | /* Return true if TREE is '.'. */ |
|
- | 897 | ||
- | 898 | static bfd_boolean |
|
- | 899 | is_dot (const etree_type *tree) |
|
- | 900 | { |
|
- | 901 | return (tree->type.node_class == etree_name |
|
- | 902 | && tree->type.node_code == NAME |
|
- | 903 | && tree->name.name[0] == '.' |
|
- | 904 | && tree->name.name[1] == 0); |
|
- | 905 | } |
|
- | 906 | ||
- | 907 | /* Return true if TREE is a constant equal to VAL. */ |
|
- | 908 | ||
- | 909 | static bfd_boolean |
|
- | 910 | is_value (const etree_type *tree, bfd_vma val) |
|
- | 911 | { |
|
- | 912 | return (tree->type.node_class == etree_value |
|
- | 913 | && tree->value.value == val); |
|
- | 914 | } |
|
- | 915 | ||
- | 916 | /* Return true if TREE is an absolute symbol equal to VAL defined in |
|
- | 917 | a linker script. */ |
|
- | 918 | ||
- | 919 | static bfd_boolean |
|
- | 920 | is_sym_value (const etree_type *tree, bfd_vma val) |
|
- | 921 | { |
|
- | 922 | struct bfd_link_hash_entry *h; |
|
- | 923 | struct definedness_hash_entry *def; |
|
- | 924 | ||
- | 925 | return (tree->type.node_class == etree_name |
|
- | 926 | && tree->type.node_code == NAME |
|
- | 927 | && (def = symbol_defined (tree->name.name)) != NULL |
|
- | 928 | && def->by_script |
|
- | 929 | && def->iteration == (lang_statement_iteration & 1) |
|
- | 930 | && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
|
- | 931 | &link_info, |
|
- | 932 | tree->name.name, |
|
- | 933 | FALSE, FALSE, TRUE)) != NULL |
|
- | 934 | && h->type == bfd_link_hash_defined |
|
- | 935 | && h->u.def.section == bfd_abs_section_ptr |
|
- | 936 | && h->u.def.value == val); |
|
- | 937 | } |
|
- | 938 | ||
- | 939 | /* Return true if TREE is ". != 0". */ |
|
- | 940 | ||
- | 941 | static bfd_boolean |
|
- | 942 | is_dot_ne_0 (const etree_type *tree) |
|
- | 943 | { |
|
- | 944 | return (tree->type.node_class == etree_binary |
|
- | 945 | && tree->type.node_code == NE |
|
- | 946 | && is_dot (tree->binary.lhs) |
|
- | 947 | && is_value (tree->binary.rhs, 0)); |
|
- | 948 | } |
|
- | 949 | ||
- | 950 | /* Return true if TREE is ". = . + 0" or ". = . + sym" where sym is an |
|
- | 951 | absolute constant with value 0 defined in a linker script. */ |
|
- | 952 | ||
- | 953 | static bfd_boolean |
|
- | 954 | is_dot_plus_0 (const etree_type *tree) |
|
- | 955 | { |
|
- | 956 | return (tree->type.node_class == etree_binary |
|
- | 957 | && tree->type.node_code == '+' |
|
- | 958 | && is_dot (tree->binary.lhs) |
|
- | 959 | && (is_value (tree->binary.rhs, 0) |
|
- | 960 | || is_sym_value (tree->binary.rhs, 0))); |
|
- | 961 | } |
|
- | 962 | ||
- | 963 | /* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)". */ |
|
- | 964 | ||
- | 965 | static bfd_boolean |
|
- | 966 | is_align_conditional (const etree_type *tree) |
|
- | 967 | { |
|
- | 968 | if (tree->type.node_class == etree_unary |
|
- | 969 | && tree->type.node_code == ALIGN_K) |
|
- | 970 | { |
|
- | 971 | tree = tree->unary.child; |
|
- | 972 | return (tree->type.node_class == etree_trinary |
|
- | 973 | && is_dot_ne_0 (tree->trinary.cond) |
|
- | 974 | && is_value (tree->trinary.rhs, 1)); |
|
- | 975 | } |
|
- | 976 | return FALSE; |
|
- | 977 | } |
|
- | 978 | ||
- | 979 | /* Subroutine of exp_fold_tree_1 for copying a symbol type. */ |
|
- | 980 | ||
- | 981 | static void |
|
- | 982 | try_copy_symbol_type (struct bfd_link_hash_entry * h, etree_type *src) |
|
- | 983 | { |
|
- | 984 | if (src->type.node_class == etree_name) |
|
- | 985 | { |
|
- | 986 | struct bfd_link_hash_entry *hsrc; |
|
- | 987 | ||
- | 988 | hsrc = bfd_link_hash_lookup (link_info.hash, src->name.name, |
|
- | 989 | FALSE, FALSE, TRUE); |
|
- | 990 | if (hsrc) |
|
- | 991 | bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, |
|
- | 992 | hsrc); |
|
- | 993 | } |
|
- | 994 | } |
|
777 | 995 | ||
778 | static void |
996 | static void |
779 | exp_fold_tree_1 (etree_type *tree) |
997 | exp_fold_tree_1 (etree_type *tree) |
780 | { |
998 | { |
781 | if (tree == NULL) |
999 | if (tree == NULL) |
Line 837... | Line 1055... | ||
837 | /* Notify the folder that this is an assignment to dot. */ |
1055 | /* Notify the folder that this is an assignment to dot. */ |
838 | expld.assigning_to_dot = TRUE; |
1056 | expld.assigning_to_dot = TRUE; |
839 | exp_fold_tree_1 (tree->assign.src); |
1057 | exp_fold_tree_1 (tree->assign.src); |
840 | expld.assigning_to_dot = FALSE; |
1058 | expld.assigning_to_dot = FALSE; |
Line -... | Line 1059... | ||
- | 1059 | ||
- | 1060 | /* If we are assigning to dot inside an output section |
|
- | 1061 | arrange to keep the section, except for certain |
|
- | 1062 | expressions that evaluate to zero. We ignore . = 0, |
|
- | 1063 | . = . + 0, and . = ALIGN (. != 0 ? expr : 1). |
|
- | 1064 | We can't ignore all expressions that evaluate to zero |
|
- | 1065 | because an otherwise empty section might have padding |
|
- | 1066 | added by an alignment expression that changes with |
|
- | 1067 | relaxation. Such a section might have zero size |
|
- | 1068 | before relaxation and so be stripped incorrectly. */ |
|
- | 1069 | if (expld.phase == lang_mark_phase_enum |
|
- | 1070 | && expld.section != bfd_abs_section_ptr |
|
- | 1071 | && !(expld.result.valid_p |
|
- | 1072 | && expld.result.value == 0 |
|
- | 1073 | && (is_value (tree->assign.src, 0) |
|
- | 1074 | || is_sym_value (tree->assign.src, 0) |
|
- | 1075 | || is_dot_plus_0 (tree->assign.src) |
|
- | 1076 | || is_align_conditional (tree->assign.src)))) |
|
- | 1077 | expld.section->flags |= SEC_KEEP; |
|
841 | 1078 | ||
842 | if (!expld.result.valid_p) |
1079 | if (!expld.result.valid_p) |
843 | { |
1080 | { |
844 | if (expld.phase != lang_mark_phase_enum) |
1081 | if (expld.phase != lang_mark_phase_enum) |
845 | einfo (_("%F%S invalid assignment to" |
1082 | einfo (_("%F%S invalid assignment to" |
Line 885... | Line 1122... | ||
885 | if (tree->type.node_class == etree_provide) |
1122 | if (tree->type.node_class == etree_provide) |
886 | { |
1123 | { |
887 | h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, |
1124 | h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, |
888 | FALSE, FALSE, TRUE); |
1125 | FALSE, FALSE, TRUE); |
889 | if (h == NULL |
1126 | if (h == NULL |
890 | || (h->type != bfd_link_hash_new |
1127 | || !(h->type == bfd_link_hash_new |
891 | && h->type != bfd_link_hash_undefined |
1128 | || h->type == bfd_link_hash_undefined |
892 | && h->type != bfd_link_hash_common)) |
1129 | || h->type == bfd_link_hash_undefweak |
- | 1130 | || h->linker_def)) |
|
893 | { |
1131 | { |
894 | /* Do nothing. The symbol was never referenced, or was |
1132 | /* Do nothing. The symbol was never referenced, or |
895 | defined by some object. */ |
1133 | was defined in some object file. Note that |
- | 1134 | undefweak symbols are defined by PROVIDE. This |
|
- | 1135 | is to support glibc use of __rela_iplt_start and |
|
- | 1136 | similar weak references. */ |
|
896 | break; |
1137 | break; |
897 | } |
1138 | } |
898 | } |
1139 | } |
Line 899... | Line 1140... | ||
899 | 1140 | ||
Line 922... | Line 1163... | ||
922 | if (h == NULL) |
1163 | if (h == NULL) |
923 | einfo (_("%P%F:%s: hash creation failed\n"), |
1164 | einfo (_("%P%F:%s: hash creation failed\n"), |
924 | tree->assign.dst); |
1165 | tree->assign.dst); |
925 | } |
1166 | } |
Line 926... | Line -... | ||
926 | - | ||
927 | /* FIXME: Should we worry if the symbol is already |
- | |
928 | defined? */ |
- | |
929 | lang_update_definedness (tree->assign.dst, h); |
- | |
930 | h->type = bfd_link_hash_defined; |
- | |
931 | h->u.def.value = expld.result.value; |
1167 | |
932 | if (expld.result.section == NULL) |
1168 | if (expld.result.section == NULL) |
- | 1169 | expld.result.section = expld.section; |
|
- | 1170 | if (!update_definedness (tree->assign.dst, h) && 0) |
|
- | 1171 | { |
|
- | 1172 | /* Symbol was already defined. For now this error |
|
- | 1173 | is disabled because it causes failures in the ld |
|
- | 1174 | testsuite: ld-elf/var1, ld-scripts/defined5, and |
|
- | 1175 | ld-scripts/pr14962. Some of these no doubt |
|
- | 1176 | reflect scripts used in the wild. */ |
|
- | 1177 | (*link_info.callbacks->multiple_definition) |
|
- | 1178 | (&link_info, h, link_info.output_bfd, |
|
- | 1179 | expld.result.section, expld.result.value); |
|
- | 1180 | } |
|
- | 1181 | h->type = bfd_link_hash_defined; |
|
933 | expld.result.section = expld.section; |
1182 | h->u.def.value = expld.result.value; |
- | 1183 | h->u.def.section = expld.result.section; |
|
934 | h->u.def.section = expld.result.section; |
1184 | h->linker_def = 0; |
935 | if (tree->type.node_class == etree_provide) |
1185 | if (tree->type.node_class == etree_provide) |
Line 936... | Line 1186... | ||
936 | tree->type.node_class = etree_provided; |
1186 | tree->type.node_class = etree_provided; |
937 | 1187 | ||
938 | /* Copy the symbol type if this is a simple assignment of |
1188 | /* Copy the symbol type if this is a simple assignment of |
939 | one symbol to another. This could be more general |
1189 | one symbol to another. Also, handle the case of a foldable |
- | 1190 | ternary conditional with names on either side. */ |
|
- | 1191 | if (tree->assign.src->type.node_class == etree_name) |
|
940 | (e.g. a ?: operator with NAMEs in each branch). */ |
1192 | try_copy_symbol_type (h, tree->assign.src); |
- | 1193 | else if (tree->assign.src->type.node_class == etree_trinary) |
|
- | 1194 | { |
|
- | 1195 | exp_fold_tree_1 (tree->assign.src->trinary.cond); |
|
941 | if (tree->assign.src->type.node_class == etree_name) |
1196 | if (expld.result.valid_p) |
- | 1197 | { |
|
- | 1198 | if (expld.result.value |
|
- | 1199 | && tree->assign.src->trinary.lhs->type.node_class |
|
942 | { |
1200 | == etree_name) |
943 | struct bfd_link_hash_entry *hsrc; |
1201 | try_copy_symbol_type (h, tree->assign.src->trinary.lhs); |
944 | 1202 | ||
945 | hsrc = bfd_link_hash_lookup (link_info.hash, |
1203 | if (!expld.result.value |
946 | tree->assign.src->name.name, |
- | |
947 | FALSE, FALSE, TRUE); |
1204 | && tree->assign.src->trinary.rhs->type.node_class |
948 | if (hsrc) |
1205 | == etree_name) |
949 | bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, |
1206 | try_copy_symbol_type (h, tree->assign.src->trinary.rhs); |
950 | hsrc); |
1207 | } |
951 | } |
1208 | } |
952 | } |
1209 | } |
953 | else if (expld.phase == lang_final_phase_enum) |
1210 | else if (expld.phase == lang_final_phase_enum) |
Line 974... | Line 1231... | ||
974 | } |
1231 | } |
Line 975... | Line 1232... | ||
975 | 1232 | ||
976 | void |
1233 | void |
977 | exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) |
1234 | exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) |
- | 1235 | { |
|
978 | { |
1236 | expld.rel_from_abs = FALSE; |
979 | expld.dot = *dotp; |
1237 | expld.dot = *dotp; |
980 | expld.dotp = dotp; |
1238 | expld.dotp = dotp; |
981 | expld.section = current_section; |
1239 | expld.section = current_section; |
982 | exp_fold_tree_1 (tree); |
1240 | exp_fold_tree_1 (tree); |
Line 983... | Line 1241... | ||
983 | } |
1241 | } |
984 | 1242 | ||
985 | void |
1243 | void |
- | 1244 | exp_fold_tree_no_dot (etree_type *tree) |
|
986 | exp_fold_tree_no_dot (etree_type *tree) |
1245 | { |
987 | { |
1246 | expld.rel_from_abs = FALSE; |
988 | expld.dot = 0; |
1247 | expld.dot = 0; |
989 | expld.dotp = NULL; |
1248 | expld.dotp = NULL; |
990 | expld.section = bfd_abs_section_ptr; |
1249 | expld.section = bfd_abs_section_ptr; |
Line 1353... | Line 1612... | ||
1353 | return value; |
1612 | return value; |
Line 1354... | Line 1613... | ||
1354 | 1613 | ||
1355 | value = (value + align - 1) / align; |
1614 | value = (value + align - 1) / align; |
1356 | return value * align; |
1615 | return value * align; |
- | 1616 | } |
|
- | 1617 | ||
- | 1618 | void |
|
- | 1619 | ldexp_init (void) |
|
- | 1620 | { |
|
- | 1621 | /* The value "13" is ad-hoc, somewhat related to the expected number of |
|
- | 1622 | assignments in a linker script. */ |
|
- | 1623 | if (!bfd_hash_table_init_n (&definedness_table, |
|
- | 1624 | definedness_newfunc, |
|
- | 1625 | sizeof (struct definedness_hash_entry), |
|
- | 1626 | 13)) |
|
- | 1627 | einfo (_("%P%F: can not create hash table: %E\n")); |
|
- | 1628 | } |
|
- | 1629 | ||
- | 1630 | /* Convert absolute symbols defined by a script from "dot" (also |
|
- | 1631 | SEGMENT_START or ORIGIN) outside of an output section statement, |
|
- | 1632 | to section relative. */ |
|
- | 1633 | ||
- | 1634 | static bfd_boolean |
|
- | 1635 | set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) |
|
- | 1636 | { |
|
- | 1637 | struct definedness_hash_entry *def = (struct definedness_hash_entry *) bh; |
|
- | 1638 | if (def->final_sec != bfd_abs_section_ptr) |
|
- | 1639 | { |
|
- | 1640 | struct bfd_link_hash_entry *h; |
|
- | 1641 | h = bfd_link_hash_lookup (link_info.hash, bh->string, |
|
- | 1642 | FALSE, FALSE, TRUE); |
|
- | 1643 | if (h != NULL |
|
- | 1644 | && h->type == bfd_link_hash_defined |
|
- | 1645 | && h->u.def.section == bfd_abs_section_ptr) |
|
- | 1646 | { |
|
- | 1647 | h->u.def.value -= def->final_sec->vma; |
|
- | 1648 | h->u.def.section = def->final_sec; |
|
- | 1649 | } |
|
- | 1650 | } |
|
- | 1651 | return TRUE; |
|
- | 1652 | } |
|
- | 1653 | ||
- | 1654 | void |
|
- | 1655 | ldexp_finalize_syms (void) |
|
- | 1656 | { |
|
- | 1657 | bfd_hash_traverse (&definedness_table, set_sym_sections, NULL); |
|
- | 1658 | } |
|
- | 1659 | ||
- | 1660 | void |
|
- | 1661 | ldexp_finish (void) |
|
- | 1662 | { |
|
- | 1663 | bfd_hash_table_free (&definedness_table); |