aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-04-19 01:26:57 +0930
committerAlan Modra <amodra@gmail.com>2017-04-19 20:39:52 +0930
commit954b63d4c8645f86e40c7ef6c6d60acd2bf019de (patch)
tree7e351a33b44fe2672265e418e9d3d4f9e38215d1 /bfd/elf64-ppc.c
parent951787ed6d13f8f441d93fc3f6fb870c234774af (diff)
downloadfsf-binutils-gdb-954b63d4c8645f86e40c7ef6c6d60acd2bf019de.zip
fsf-binutils-gdb-954b63d4c8645f86e40c7ef6c6d60acd2bf019de.tar.gz
fsf-binutils-gdb-954b63d4c8645f86e40c7ef6c6d60acd2bf019de.tar.bz2
Implement -z dynamic-undefined-weak
-z nodynamic-undefined-weak is only implemented for x86. (The sparc backend has some support code but doesn't enable the option by including ld/emulparams/dynamic_undefined_weak.sh, and since the support looks like it may be broken I haven't enabled it.) This patch adds the complementary -z dynamic-undefined-weak, extends both options to affect building of shared libraries as well as executables, and adds support for the option on powerpc. include/ * bfdlink.h (struct bfd_link_info <dynamic_undefined_weak>): Revise comment. bfd/ * elflink.c (_bfd_elf_adjust_dynamic_symbol): Hide undefweak or make dynamic for info->dynamic_undefined_weak 0 and 1. * elf32-ppc.c:Formatting. (ensure_undefweak_dynamic): Don't make dynamic when info->dynamic_undefined_weak is zero. (allocate_dynrelocs): Discard undefweak dyn_relocs for info->dynamic_undefined_weak. Discard undef dyn_relocs when not default visibility. Discard undef and undefweak dyn_relocs earlier. (ppc_elf_relocate_section): Adjust to suit. * elf64-ppc.c: Formatting. (ensure_undefweak_dynamic): Don't make dynamic when info->dynamic_undefined_weak is zero. (allocate_dynrelocs): Discard undefweak dyn_relocs for info->dynamic_undefined_weak. Discard them earlier. ld/ * ld.texinfo (dynamic-undefined-weak): Document. (nodynamic-undefined-weak): Document that this option now can be used with shared libs. * emulparams/dynamic_undefined_weak.sh: Support -z dynamic-undefined-weak. * emulparams/elf32ppccommon.sh: Include dynamic_undefined_weak.sh. * testsuite/ld-undefined/weak-undef.exp (undef_weak_so), (undef_weak_exe): New. Use them. Add -z dynamic-undefined-weak and -z nodynamic-undefined-weak tests. * Makefile.am: Update powerpc dependencies. * Makefile.in: Regenerate.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e48d67d..fc69964 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -9695,6 +9695,7 @@ ensure_undefweak_dynamic (struct bfd_link_info *info,
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->dynamic_sections_created
+ && info->dynamic_undefined_weak != 0
&& h->root.type == bfd_link_hash_undefweak
&& h->dynindx == -1
&& !h->forced_local
@@ -9785,10 +9786,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
allocate_got (h, info, gent);
}
+ /* If no dynamic sections we can't have dynamic relocs, except for
+ IFUNCs which are handled even in static executables. */
if (!htab->elf.dynamic_sections_created
&& h->type != STT_GNU_IFUNC)
eh->dyn_relocs = NULL;
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility, or when dynamic_undefined_weak says so. */
+ else if (h->root.type == bfd_link_hash_undefweak
+ && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || info->dynamic_undefined_weak == 0))
+ eh->dyn_relocs = NULL;
+
if (eh->dyn_relocs != NULL)
{
struct elf_dyn_relocs *p, **pp;
@@ -9821,17 +9831,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
}
}
- /* Also discard relocs on undefined weak syms with
- non-default visibility. */
- if (eh->dyn_relocs != NULL
- && h->root.type == bfd_link_hash_undefweak)
+ if (eh->dyn_relocs != NULL)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
- eh->dyn_relocs = NULL;
-
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- else if (!ensure_undefweak_dynamic (info, h))
+ if (!ensure_undefweak_dynamic (info, h))
return FALSE;
}
}
@@ -14320,7 +14324,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
addend = 0;
reloc_dest = DEST_STUB;
- if ((stub_entry->stub_type == ppc_stub_plt_call
+ if ((stub_entry->stub_type == ppc_stub_plt_call
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
&& (ALWAYS_EMIT_R2SAVE
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)