aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-11-27 13:40:43 +1030
committerAlan Modra <amodra@gmail.com>2017-11-28 22:57:00 +1030
commit165f707ac88916aedecc96fa518be8879704d6da (patch)
tree8ca3d6cbc5f8a0a0154ff5686e71a964a932966d /bfd
parentcd5b2babea487b0a71a14b593af98330efd8d73e (diff)
downloadgdb-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/ChangeLog9
-rw-r--r--bfd/elflink.c7
-rw-r--r--bfd/linker.c9
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: