GNU Binutils with patches for OS216
Revision | 165f707ac88916aedecc96fa518be8879704d6da (tree) |
---|---|
Time | 2017-11-28 21:27:00 |
Author | Alan Modra <amodra@gmai...> |
Commiter | Alan Modra |
PR22471, undefined reference to linker-defined symbols
This patch processes linker script assignment statements before ld
opens DT_NEEDED libraries, in order to define symbols like bss_start
that might also be defined by a library, falsely triggering an error
about "DSO missing from command line".
The initial value won't be correct when assigning a symbol from dot,
and I make no attempt to handle all expressions. For example, an
assignment like "_start_foo = ADDR (.foo)" isn't valid until sections
are laid out, so won't define _start_foo early. What's here should be
enough for most common scripts, and hopefully won't perturb fragile
scripts.
bfd/
PR 22471
* elflink.c (_bfd_elf_merge_symbol): Allow weak symbols to override
early passes over linker script symbols.
* linker.c (_bfd_generic_link_add_one_symbol): Allow symbols to
override early passes over linker script symbols. Clear ldscript_def
on symbol definitions.
ld/
PR 22471
* ldexp.c (struct definedness_hash_entry): Delete "by_script". Make
"iteration" an 8-bit field, and update mask in all uses.
(definedness_newfunc): Don't init "by_script".
(update_definedness): Test ldscript_def rather than by_script.
(is_sym_value): Likewise.
(fold_name <DEFINED>): Return a result for first phase. Test
ldscript_def.
(fold_name <NAME>): Return a result for first phase.
* ldlang.c (open_input_bfds): Process all assignments, not just
defsym.
(lang_process): Increment lang_statement_iteration before
open_input_bfds.
* testsuite/ld-mips-elf/tlsdyn-o32-1.d: Adjust for larger .dynsym.
* testsuite/ld-mips-elf/tlsdyn-o32-1.got: Likewise.
* testsuite/ld-mips-elf/tlsdyn-o32-2.d: Likewise.
* testsuite/ld-mips-elf/tlsdyn-o32-2.got: Likewise.
* testsuite/ld-mips-elf/tlsdyn-o32-3.d: Likewise.
* testsuite/ld-mips-elf/tlsdyn-o32-3.got: Likewise.
@@ -1,5 +1,14 @@ | ||
1 | 1 | 2017-11-28 Alan Modra <amodra@gmail.com> |
2 | 2 | |
3 | + PR 22471 | |
4 | + * elflink.c (_bfd_elf_merge_symbol): Allow weak symbols to override | |
5 | + early passes over linker script symbols. | |
6 | + * linker.c (_bfd_generic_link_add_one_symbol): Allow symbols to | |
7 | + override early passes over linker script symbols. Clear ldscript_def | |
8 | + on symbol definitions. | |
9 | + | |
10 | +2017-11-28 Alan Modra <amodra@gmail.com> | |
11 | + | |
3 | 12 | * elf64-mmix.c (bfd_elf64_bfd_copy_link_hash_symbol_type): Define. |
4 | 13 | |
5 | 14 | 2017-11-28 H.J. Lu <hongjiu.lu@intel.com> |
@@ -1471,10 +1471,15 @@ _bfd_elf_merge_symbol (bfd *abfd, | ||
1471 | 1471 | treated as strong if the new symbol is from a dynamic library. |
1472 | 1472 | This reflects the way glibc's ld.so works. |
1473 | 1473 | |
1474 | + Also allow a weak symbol to override a linker script symbol | |
1475 | + defined by an early pass over the script. This is done so the | |
1476 | + linker knows the symbol is defined in an object file, for the | |
1477 | + DEFINED script function. | |
1478 | + | |
1474 | 1479 | Do this before setting *type_change_ok or *size_change_ok so that |
1475 | 1480 | we warn properly when dynamic library symbols are overridden. */ |
1476 | 1481 | |
1477 | - if (newdef && !newdyn && olddyn) | |
1482 | + if (newdef && !newdyn && (olddyn || h->root.ldscript_def)) | |
1478 | 1483 | newweak = FALSE; |
1479 | 1484 | if (olddef && newdyn) |
1480 | 1485 | oldweak = FALSE; |
@@ -1443,9 +1443,14 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, | ||
1443 | 1443 | do |
1444 | 1444 | { |
1445 | 1445 | enum link_action action; |
1446 | + int prev; | |
1446 | 1447 | |
1448 | + prev = h->type; | |
1449 | + /* Treat symbols defined by early linker script pass as undefined. */ | |
1450 | + if (h->ldscript_def) | |
1451 | + prev = bfd_link_hash_undefined; | |
1447 | 1452 | cycle = FALSE; |
1448 | - action = link_action[(int) row][(int) h->type]; | |
1453 | + action = link_action[(int) row][prev]; | |
1449 | 1454 | switch (action) |
1450 | 1455 | { |
1451 | 1456 | case FAIL: |
@@ -1489,6 +1494,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, | ||
1489 | 1494 | h->u.def.section = section; |
1490 | 1495 | h->u.def.value = value; |
1491 | 1496 | h->linker_def = 0; |
1497 | + h->ldscript_def = 0; | |
1492 | 1498 | |
1493 | 1499 | /* If we have been asked to, we act like collect2 and |
1494 | 1500 | identify all functions that might be global |
@@ -1588,6 +1594,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, | ||
1588 | 1594 | else |
1589 | 1595 | h->u.c.p->section = section; |
1590 | 1596 | h->linker_def = 0; |
1597 | + h->ldscript_def = 0; | |
1591 | 1598 | break; |
1592 | 1599 | |
1593 | 1600 | case REF: |
@@ -1,5 +1,27 @@ | ||
1 | 1 | 2017-11-28 Alan Modra <amodra@gmail.com> |
2 | 2 | |
3 | + PR 22471 | |
4 | + * ldexp.c (struct definedness_hash_entry): Delete "by_script". Make | |
5 | + "iteration" an 8-bit field, and update mask in all uses. | |
6 | + (definedness_newfunc): Don't init "by_script". | |
7 | + (update_definedness): Test ldscript_def rather than by_script. | |
8 | + (is_sym_value): Likewise. | |
9 | + (fold_name <DEFINED>): Return a result for first phase. Test | |
10 | + ldscript_def. | |
11 | + (fold_name <NAME>): Return a result for first phase. | |
12 | + * ldlang.c (open_input_bfds): Process all assignments, not just | |
13 | + defsym. | |
14 | + (lang_process): Increment lang_statement_iteration before | |
15 | + open_input_bfds. | |
16 | + * testsuite/ld-mips-elf/tlsdyn-o32-1.d: Adjust for larger .dynsym. | |
17 | + * testsuite/ld-mips-elf/tlsdyn-o32-1.got: Likewise. | |
18 | + * testsuite/ld-mips-elf/tlsdyn-o32-2.d: Likewise. | |
19 | + * testsuite/ld-mips-elf/tlsdyn-o32-2.got: Likewise. | |
20 | + * testsuite/ld-mips-elf/tlsdyn-o32-3.d: Likewise. | |
21 | + * testsuite/ld-mips-elf/tlsdyn-o32-3.got: Likewise. | |
22 | + | |
23 | +2017-11-28 Alan Modra <amodra@gmail.com> | |
24 | + | |
3 | 25 | * ldexp.h (struct ldexp_control): Add "assign_src". |
4 | 26 | * ldexp.c (fold_trinary): Save and restore assign_src around |
5 | 27 | condition evaluation. |
@@ -60,15 +60,12 @@ struct definedness_hash_entry | ||
60 | 60 | section statement, the section we'd like it relative to. */ |
61 | 61 | asection *final_sec; |
62 | 62 | |
63 | + /* Low bits of iteration count. Symbols with matching iteration have | |
64 | + been defined in this pass over the script. */ | |
65 | + unsigned int iteration : 8; | |
66 | + | |
63 | 67 | /* Symbol was defined by an object file. */ |
64 | 68 | 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 | 69 | }; |
73 | 70 | |
74 | 71 | static struct bfd_hash_table definedness_table; |
@@ -286,7 +283,6 @@ definedness_newfunc (struct bfd_hash_entry *entry, | ||
286 | 283 | einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name); |
287 | 284 | |
288 | 285 | ret->by_object = 0; |
289 | - ret->by_script = 0; | |
290 | 286 | ret->iteration = 0; |
291 | 287 | return &ret->root; |
292 | 288 | } |
@@ -320,7 +316,7 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h) | ||
320 | 316 | /* If the symbol was already defined, and not by a script, then it |
321 | 317 | must be defined by an object file or by the linker target code. */ |
322 | 318 | ret = TRUE; |
323 | - if (!defentry->by_script | |
319 | + if (!h->ldscript_def | |
324 | 320 | && (h->type == bfd_link_hash_defined |
325 | 321 | || h->type == bfd_link_hash_defweak |
326 | 322 | || h->type == bfd_link_hash_common)) |
@@ -332,7 +328,6 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h) | ||
332 | 328 | ret = FALSE; |
333 | 329 | } |
334 | 330 | |
335 | - defentry->by_script = 1; | |
336 | 331 | defentry->iteration = lang_statement_iteration; |
337 | 332 | defentry->final_sec = bfd_abs_section_ptr; |
338 | 333 | if (expld.phase == lang_final_phase_enum |
@@ -686,6 +681,9 @@ fold_trinary (etree_type *tree) | ||
686 | 681 | static void |
687 | 682 | fold_name (etree_type *tree) |
688 | 683 | { |
684 | + struct bfd_link_hash_entry *h; | |
685 | + struct definedness_hash_entry *def; | |
686 | + | |
689 | 687 | memset (&expld.result, 0, sizeof (expld.result)); |
690 | 688 | |
691 | 689 | switch (tree->type.node_code) |
@@ -703,23 +701,18 @@ fold_name (etree_type *tree) | ||
703 | 701 | break; |
704 | 702 | |
705 | 703 | case DEFINED: |
706 | - if (expld.phase != lang_first_phase_enum) | |
707 | - { | |
708 | - struct bfd_link_hash_entry *h; | |
709 | - struct definedness_hash_entry *def; | |
710 | - | |
711 | - h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, | |
712 | - &link_info, | |
713 | - tree->name.name, | |
714 | - FALSE, FALSE, TRUE); | |
715 | - new_number (h != NULL | |
716 | - && (h->type == bfd_link_hash_defined | |
717 | - || h->type == bfd_link_hash_defweak | |
718 | - || h->type == bfd_link_hash_common) | |
719 | - && ((def = symbol_defined (tree->name.name)) == NULL | |
720 | - || def->by_object | |
721 | - || def->iteration == (lang_statement_iteration & 1))); | |
722 | - } | |
704 | + h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, | |
705 | + &link_info, | |
706 | + tree->name.name, | |
707 | + FALSE, FALSE, TRUE); | |
708 | + new_number (h != NULL | |
709 | + && (h->type == bfd_link_hash_defined | |
710 | + || h->type == bfd_link_hash_defweak | |
711 | + || h->type == bfd_link_hash_common) | |
712 | + && (!h->ldscript_def | |
713 | + || (def = symbol_defined (tree->name.name)) == NULL | |
714 | + || def->by_object | |
715 | + || def->iteration == (lang_statement_iteration & 255))); | |
723 | 716 | break; |
724 | 717 | |
725 | 718 | case NAME: |
@@ -728,9 +721,6 @@ fold_name (etree_type *tree) | ||
728 | 721 | { |
729 | 722 | /* Self-assignment is only allowed for absolute symbols |
730 | 723 | defined in a linker script. */ |
731 | - struct bfd_link_hash_entry *h; | |
732 | - struct definedness_hash_entry *def; | |
733 | - | |
734 | 724 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
735 | 725 | &link_info, |
736 | 726 | tree->name.name, |
@@ -740,17 +730,13 @@ fold_name (etree_type *tree) | ||
740 | 730 | || h->type == bfd_link_hash_defweak) |
741 | 731 | && h->u.def.section == bfd_abs_section_ptr |
742 | 732 | && (def = symbol_defined (tree->name.name)) != NULL |
743 | - && def->iteration == (lang_statement_iteration & 1))) | |
733 | + && def->iteration == (lang_statement_iteration & 255))) | |
744 | 734 | expld.assign_name = NULL; |
745 | 735 | } |
746 | - if (expld.phase == lang_first_phase_enum) | |
747 | - ; | |
748 | - else if (tree->name.name[0] == '.' && tree->name.name[1] == 0) | |
736 | + if (tree->name.name[0] == '.' && tree->name.name[1] == 0) | |
749 | 737 | new_rel_from_abs (expld.dot); |
750 | 738 | else |
751 | 739 | { |
752 | - struct bfd_link_hash_entry *h; | |
753 | - | |
754 | 740 | h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
755 | 741 | &link_info, |
756 | 742 | tree->name.name, |
@@ -765,7 +751,7 @@ fold_name (etree_type *tree) | ||
765 | 751 | output_section = h->u.def.section->output_section; |
766 | 752 | if (output_section == NULL) |
767 | 753 | { |
768 | - if (expld.phase == lang_mark_phase_enum) | |
754 | + if (expld.phase <= lang_mark_phase_enum) | |
769 | 755 | new_rel (h->u.def.value, h->u.def.section); |
770 | 756 | else |
771 | 757 | einfo (_("%X%S: unresolvable symbol `%s'" |
@@ -957,12 +943,12 @@ is_sym_value (const etree_type *tree, bfd_vma val) | ||
957 | 943 | return (tree->type.node_class == etree_name |
958 | 944 | && tree->type.node_code == NAME |
959 | 945 | && (def = symbol_defined (tree->name.name)) != NULL |
960 | - && def->by_script | |
961 | - && def->iteration == (lang_statement_iteration & 1) | |
946 | + && def->iteration == (lang_statement_iteration & 255) | |
962 | 947 | && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, |
963 | 948 | &link_info, |
964 | 949 | tree->name.name, |
965 | 950 | FALSE, FALSE, TRUE)) != NULL |
951 | + && h->ldscript_def | |
966 | 952 | && h->type == bfd_link_hash_defined |
967 | 953 | && h->u.def.section == bfd_abs_section_ptr |
968 | 954 | && h->u.def.value == val); |
@@ -3359,9 +3359,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) | ||
3359 | 3359 | #endif |
3360 | 3360 | break; |
3361 | 3361 | case lang_assignment_statement_enum: |
3362 | - if (s->assignment_statement.exp->type.node_class != etree_assert | |
3363 | - && s->assignment_statement.exp->assign.defsym) | |
3364 | - /* This is from a --defsym on the command line. */ | |
3362 | + if (s->assignment_statement.exp->type.node_class != etree_assert) | |
3365 | 3363 | exp_fold_tree_no_dot (s->assignment_statement.exp); |
3366 | 3364 | break; |
3367 | 3365 | default: |
@@ -7167,6 +7165,7 @@ lang_process (void) | ||
7167 | 7165 | |
7168 | 7166 | /* Create a bfd for each input file. */ |
7169 | 7167 | current_target = default_target; |
7168 | + lang_statement_iteration++; | |
7170 | 7169 | open_input_bfds (statement_list.head, OPEN_BFD_NORMAL); |
7171 | 7170 | |
7172 | 7171 | #ifdef ENABLE_PLUGINS |
@@ -7222,6 +7221,7 @@ lang_process (void) | ||
7222 | 7221 | |
7223 | 7222 | /* Rescan archives in case new undefined symbols have appeared. */ |
7224 | 7223 | files = file_chain; |
7224 | + lang_statement_iteration++; | |
7225 | 7225 | open_input_bfds (statement_list.head, OPEN_BFD_RESCAN); |
7226 | 7226 | lang_list_remove_tail (&file_chain, &files); |
7227 | 7227 | while (files.head != NULL) |
@@ -5,7 +5,7 @@ Disassembly of section .text: | ||
5 | 5 | |
6 | 6 | .* <__start>: |
7 | 7 | .*: 3c1c0fc0 lui gp,0xfc0 |
8 | - .*: 279c7c30 addiu gp,gp,31792 | |
8 | + .*: 279c7b80 addiu gp,gp,31616 | |
9 | 9 | .*: 0399e021 addu gp,gp,t9 |
10 | 10 | .*: 27bdfff0 addiu sp,sp,-16 |
11 | 11 | .*: afbe0008 sw s8,8\(sp\) |
@@ -55,7 +55,7 @@ Disassembly of section .text: | ||
55 | 55 | |
56 | 56 | .* <other>: |
57 | 57 | .*: 3c1c0fc0 lui gp,0xfc0 |
58 | - .*: 279c7b70 addiu gp,gp,31600 | |
58 | + .*: 279c7ac0 addiu gp,gp,31424 | |
59 | 59 | .*: 0399e021 addu gp,gp,t9 |
60 | 60 | .*: 27bdfff0 addiu sp,sp,-16 |
61 | 61 | .*: afbe0008 sw s8,8\(sp\) |
@@ -13,6 +13,6 @@ OFFSET TYPE VALUE | ||
13 | 13 | |
14 | 14 | |
15 | 15 | Contents of section .got: |
16 | - 10000020 00000000 80000000 0040048c 00000000 .........@...... | |
16 | + 10000020 00000000 80000000 0040053c 00000000 .........@...... | |
17 | 17 | 10000030 00000000 00000000 00000000 00000000 ................ |
18 | 18 | 10000040 00000000 00000001 00000000 ............ |
@@ -5,7 +5,7 @@ Disassembly of section .text: | ||
5 | 5 | |
6 | 6 | .* <__start>: |
7 | 7 | .*: 3c1c0fc0 lui gp,0xfc0 |
8 | - .*: 279c7c30 addiu gp,gp,31792 | |
8 | + .*: 279c7b80 addiu gp,gp,31616 | |
9 | 9 | .*: 0399e021 addu gp,gp,t9 |
10 | 10 | .*: 27bdfff0 addiu sp,sp,-16 |
11 | 11 | .*: afbe0008 sw s8,8\(sp\) |
@@ -55,7 +55,7 @@ Disassembly of section .text: | ||
55 | 55 | |
56 | 56 | .* <other>: |
57 | 57 | .*: 3c1c0fc0 lui gp,0xfc0 |
58 | - .*: 279c7b70 addiu gp,gp,31600 | |
58 | + .*: 279c7ac0 addiu gp,gp,31424 | |
59 | 59 | .*: 0399e021 addu gp,gp,t9 |
60 | 60 | .*: 27bdfff0 addiu sp,sp,-16 |
61 | 61 | .*: afbe0008 sw s8,8\(sp\) |
@@ -13,6 +13,6 @@ OFFSET TYPE VALUE | ||
13 | 13 | |
14 | 14 | |
15 | 15 | Contents of section .got: |
16 | - 10000020 00000000 80000000 0040048c 00000000 .* | |
16 | + 10000020 00000000 80000000 0040053c 00000000 .* | |
17 | 17 | 10000030 00000000 00000000 00000000 00000000 .* |
18 | 18 | 10000040 00000000 00000001 00000000 .* |
@@ -5,7 +5,7 @@ Disassembly of section .text: | ||
5 | 5 | |
6 | 6 | .* <other>: |
7 | 7 | .*: 3c1c0fc0 lui gp,0xfc0 |
8 | - .*: 279c7c30 addiu gp,gp,31792 | |
8 | + .*: 279c7b80 addiu gp,gp,31616 | |
9 | 9 | .*: 0399e021 addu gp,gp,t9 |
10 | 10 | .*: 27bdfff0 addiu sp,sp,-16 |
11 | 11 | .*: afbe0008 sw s8,8\(sp\) |
@@ -51,7 +51,7 @@ Disassembly of section .text: | ||
51 | 51 | |
52 | 52 | .* <__start>: |
53 | 53 | .*: 3c1c0fc0 lui gp,0xfc0 |
54 | - .*: 279c7b80 addiu gp,gp,31616 | |
54 | + .*: 279c7ad0 addiu gp,gp,31440 | |
55 | 55 | .*: 0399e021 addu gp,gp,t9 |
56 | 56 | .*: 27bdfff0 addiu sp,sp,-16 |
57 | 57 | .*: afbe0008 sw s8,8\(sp\) |
@@ -13,6 +13,6 @@ OFFSET TYPE VALUE | ||
13 | 13 | |
14 | 14 | |
15 | 15 | Contents of section .got: |
16 | - 10000020 00000000 80000000 0040053c 00000000 .* | |
16 | + 10000020 00000000 80000000 004005ec 00000000 .* | |
17 | 17 | 10000030 00000000 00000000 00000000 00000000 .* |
18 | 18 | 10000040 00000000 00000001 00000000 .* |