diff options
author | Alan Modra <amodra@gmail.com> | 2017-11-27 13:40:43 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-11-28 22:57:00 +1030 |
commit | 165f707ac88916aedecc96fa518be8879704d6da (patch) | |
tree | 8ca3d6cbc5f8a0a0154ff5686e71a964a932966d /bfd | |
parent | cd5b2babea487b0a71a14b593af98330efd8d73e (diff) | |
download | gdb-165f707ac88916aedecc96fa518be8879704d6da.zip gdb-165f707ac88916aedecc96fa518be8879704d6da.tar.gz gdb-165f707ac88916aedecc96fa518be8879704d6da.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elflink.c | 7 | ||||
-rw-r--r-- | bfd/linker.c | 9 |
3 files changed, 23 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index dc3aa2f..c9c2407 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,14 @@ 2017-11-28 Alan Modra <amodra@gmail.com> + 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. + +2017-11-28 Alan Modra <amodra@gmail.com> + * elf64-mmix.c (bfd_elf64_bfd_copy_link_hash_symbol_type): Define. 2017-11-28 H.J. Lu <hongjiu.lu@intel.com> diff --git a/bfd/elflink.c b/bfd/elflink.c index ddd088c..fed7caa 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1471,10 +1471,15 @@ _bfd_elf_merge_symbol (bfd *abfd, treated as strong if the new symbol is from a dynamic library. This reflects the way glibc's ld.so works. + Also allow a weak symbol to override a linker script symbol + defined by an early pass over the script. This is done so the + linker knows the symbol is defined in an object file, for the + DEFINED script function. + Do this before setting *type_change_ok or *size_change_ok so that we warn properly when dynamic library symbols are overridden. */ - if (newdef && !newdyn && olddyn) + if (newdef && !newdyn && (olddyn || h->root.ldscript_def)) newweak = FALSE; if (olddef && newdyn) oldweak = FALSE; diff --git a/bfd/linker.c b/bfd/linker.c index a96c6ed..9c19df4 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1443,9 +1443,14 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, do { enum link_action action; + int prev; + prev = h->type; + /* Treat symbols defined by early linker script pass as undefined. */ + if (h->ldscript_def) + prev = bfd_link_hash_undefined; cycle = FALSE; - action = link_action[(int) row][(int) h->type]; + action = link_action[(int) row][prev]; switch (action) { case FAIL: @@ -1489,6 +1494,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, h->u.def.section = section; h->u.def.value = value; h->linker_def = 0; + h->ldscript_def = 0; /* If we have been asked to, we act like collect2 and identify all functions that might be global @@ -1588,6 +1594,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, else h->u.c.p->section = section; h->linker_def = 0; + h->ldscript_def = 0; break; case REF: |