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.
This commit is contained in:
Alan Modra 2017-04-19 01:26:57 +09:30
parent 951787ed6d
commit 954b63d4c8
13 changed files with 226 additions and 79 deletions

View File

@ -1,3 +1,21 @@
2017-04-19 Alan Modra <amodra@gmail.com>
* 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.
2017-04-17 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21389

View File

@ -2609,7 +2609,7 @@ ppc_elf_modify_segment_map (bfd *abfd,
amt += (m->count - j - 1) * sizeof (asection *);
n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (n == NULL)
return FALSE;
return FALSE;
n->p_type = PT_LOAD;
n->count = m->count - j;
@ -5947,6 +5947,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
@ -6036,6 +6037,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
else
eh->elf.got.offset = (bfd_vma) -1;
/* 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;
@ -6050,13 +6053,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
changes. */
else if (bfd_link_pic (info))
{
/* Discard relocs on undefined symbols that must be local. */
if (h->root.type == bfd_link_hash_undefined
&& ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
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;
/* Relocs that use pc_count are those that appear on a call insn,
or certain REL relocs (see must_be_dyn_reloc) that can be
generated via assembly. We want calls to protected symbols to
resolve directly to the function rather than going via the plt.
If people want function pointer comparisons to work as expected
then they should avoid writing weird assembly. */
if (SYMBOL_CALLS_LOCAL (info, h))
else if (SYMBOL_CALLS_LOCAL (info, h))
{
struct elf_dyn_relocs **pp;
@ -6084,24 +6099,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
}
}
/* Discard relocs on undefined symbols that must be local. */
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefined
&& (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
|| ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
eh->dyn_relocs = NULL;
/* 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 undefined weak symbols are output as a dynamic
symbol in PIEs. */
else if (!ensure_undefweak_dynamic (info, h))
if (!ensure_undefweak_dynamic (info, h))
return FALSE;
}
}
@ -8859,10 +8861,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
if ((bfd_link_pic (info)
&& !(h != NULL
&& ((h->root.type == bfd_link_hash_undefined
&& (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
|| ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
&& ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|| (h->root.type == bfd_link_hash_undefweak
&& ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)))
&& (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|| info->dynamic_undefined_weak == 0))))
&& (must_be_dyn_reloc (info, r_type)
|| !SYMBOL_CALLS_LOCAL (info, h)))
|| (ELIMINATE_COPY_RELOCS
@ -10979,7 +10981,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
#define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections
#define elf_backend_fake_sections ppc_elf_fake_sections
#define elf_backend_additional_program_headers ppc_elf_additional_program_headers
#define elf_backend_modify_segment_map ppc_elf_modify_segment_map
#define elf_backend_modify_segment_map ppc_elf_modify_segment_map
#define elf_backend_grok_prstatus ppc_elf_grok_prstatus
#define elf_backend_grok_psinfo ppc_elf_grok_psinfo
#define elf_backend_write_core_note ppc_elf_write_core_note
@ -11049,7 +11051,7 @@ ppc_elf_vxworks_link_hash_table_create (bfd *abfd)
if (ret)
{
struct ppc_elf_link_hash_table *htab
= (struct ppc_elf_link_hash_table *)ret;
= (struct ppc_elf_link_hash_table *)ret;
htab->is_vxworks = 1;
htab->plt_type = PLT_VXWORKS;
htab->plt_entry_size = VXWORKS_PLT_ENTRY_SIZE;

View File

@ -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)

View File

@ -2803,6 +2803,24 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
if (! _bfd_elf_fix_symbol_flags (h, eif))
return FALSE;
if (h->root.type == bfd_link_hash_undefweak)
{
if (eif->info->dynamic_undefined_weak == 0)
_bfd_elf_link_hash_hide_symbol (eif->info, h, TRUE);
else if (eif->info->dynamic_undefined_weak > 0
&& h->ref_regular
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
&& !bfd_hide_sym_by_version (eif->info->version_info,
h->root.root.string))
{
if (!bfd_elf_link_record_dynamic_symbol (eif->info, h))
{
eif->failed = TRUE;
return FALSE;
}
}
}
/* If this symbol does not require a PLT entry, and it is not
defined by a dynamic object, or is not referenced by a regular
object, ignore it. We do have to handle a weak defined symbol,

View File

@ -1,3 +1,8 @@
2017-04-19 Alan Modra <amodra@gmail.com>
* bfdlink.h (struct bfd_link_info <dynamic_undefined_weak>):
Revise comment.
2017-04-11 Alan Modra <amodra@gmail.com>
* opcode/ppc.h (PPC_OPCODE_ALTIVEC2): Delete.

View File

@ -584,8 +584,9 @@ struct bfd_link_info
backend to decide. */
int extern_protected_data;
/* > 0 to treat undefined weak symbol in the executable as dynamic,
requiring dynamic relocation. */
/* 1 to make undefined weak symbols dynamic when building a dynamic
object. 0 to resolve undefined weak symbols to zero. -1 to let
the backend decide. */
int dynamic_undefined_weak;
/* Non-zero if auto-import thunks for DATA items in pei386 DLLs

View File

@ -1,3 +1,17 @@
2017-04-19 Alan Modra <amodra@gmail.com>
* 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.
2017-04-17 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21389

View File

@ -1157,23 +1157,27 @@ eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \
eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppclinux.c: $(srcdir)/emulparams/elf32lppclinux.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
@ -1253,31 +1257,37 @@ eelf32or1k_linux.c: $(srcdir)/emulparams/elf32or1k_linux.sh \
eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcvxworks.c: $(srcdir)/emulparams/elf32ppcvxworks.sh \
$(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emulparams/vxworks.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(srcdir)/emultempl/vxworks.em \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
@ -1976,8 +1986,9 @@ eelf64hppa.c: $(srcdir)/emulparams/elf64hppa.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elf64hppa.sc ${GEN_DEPENDS}
eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \
$(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
ldemul-list.h \
$(srcdir)/emulparams/elf64ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
@ -2000,11 +2011,13 @@ eelf64mmix.c: $(srcdir)/emulparams/elf64mmix.sh \
$(ELF_DEPS) $(srcdir)/emultempl/mmix-elfnmmo.em \
$(srcdir)/emultempl/mmixelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
ldemul-list.h \
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64ppc_fbsd.c: $(srcdir)/emulparams/elf64ppc_fbsd.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}

View File

@ -2721,23 +2721,27 @@ eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \
eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppclinux.c: $(srcdir)/emulparams/elf32lppclinux.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
@ -2817,31 +2821,37 @@ eelf32or1k_linux.c: $(srcdir)/emulparams/elf32or1k_linux.sh \
eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
$(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf32ppcvxworks.c: $(srcdir)/emulparams/elf32ppcvxworks.sh \
$(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emulparams/vxworks.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc32elf.em ldemul-list.h \
$(srcdir)/emultempl/vxworks.em \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
@ -3540,8 +3550,9 @@ eelf64hppa.c: $(srcdir)/emulparams/elf64hppa.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elf64hppa.sc ${GEN_DEPENDS}
eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \
$(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
ldemul-list.h \
$(srcdir)/emulparams/elf64ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
@ -3564,11 +3575,13 @@ eelf64mmix.c: $(srcdir)/emulparams/elf64mmix.sh \
$(ELF_DEPS) $(srcdir)/emultempl/mmix-elfnmmo.em \
$(srcdir)/emultempl/mmixelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
ldemul-list.h \
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
eelf64ppc_fbsd.c: $(srcdir)/emulparams/elf64ppc_fbsd.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emultempl/ppc64elf.em ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}

View File

@ -1,12 +1,15 @@
PARSE_AND_LIST_OPTIONS_NODYNAMIC_UNDEFINED_WEAK='
PARSE_AND_LIST_OPTIONS_DYNAMIC_UNDEFINED_WEAK='
fprintf (file, _("\
-z nodynamic-undefined-weak Do not treat undefined weak symbol as dynamic\n"));
-z dynamic-undefined-weak Make undefined weak symbols dynamic\n\
-z nodynamic-undefined-weak Do not make undefined weak symbols dynamic\n"));
'
PARSE_AND_LIST_ARGS_CASE_Z_NODYNAMIC_UNDEFINED_WEAK='
PARSE_AND_LIST_ARGS_CASE_Z_DYNAMIC_UNDEFINED_WEAK='
else if (strcmp (optarg, "dynamic-undefined-weak") == 0)
link_info.dynamic_undefined_weak = TRUE;
else if (strcmp (optarg, "nodynamic-undefined-weak") == 0)
link_info.dynamic_undefined_weak = FALSE;
'
PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_NODYNAMIC_UNDEFINED_WEAK"
PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_NODYNAMIC_UNDEFINED_WEAK"
PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_DYNAMIC_UNDEFINED_WEAK"
PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_DYNAMIC_UNDEFINED_WEAK"

View File

@ -1,5 +1,7 @@
# The PLT-agnostic parts of a generic 32-bit ELF PowerPC target. Included by:
# elf32ppc.sh elf32ppcvxworks.sh elf64ppc.sh
. ${srcdir}/emulparams/dynamic_undefined_weak.sh
TEMPLATE_NAME=elf32
GENERATE_SHLIB_SCRIPT=yes
GENERATE_PIE_SCRIPT=yes

View File

@ -1231,11 +1231,18 @@ generated by compiler. Updates on protected data symbols by another
module aren't visible to the resulting shared library. Supported for
i386 and x86-64.
@item dynamic-undefined-weak
Make undefined weak symbols dynamic when building a dynamic object,
if they are referenced from a regular object file and not forced local
by symbol visibility or versioning. Not all targets support this
option.
@item nodynamic-undefined-weak
Don't treat undefined weak symbols as dynamic when building executable.
This option overrides linker backend default. It can be used to avoid
dynamic relocations against undefined weak symbols in executable.
Supported for i386 and x86-64.
Do not make undefined weak symbols dynamic when building a dynamic
object. Not all targets support this option. If neither
@option{-z nodynamic-undefined-weak} nor @option{-z dynamic-undefined-weak}
are given, a target may default to either option being in force, or
make some other selection of undefined weak symbols dynamic.
@item noreloc-overflow
Disable relocation overflow check. This can be used to disable

View File

@ -53,6 +53,52 @@ if { ![is_elf_format] && ![is_pecoff_format] } then {
}
}
proc undef_weak_so { testname opts passval } {
global ld
global nm
if {![ld_link $ld tmpdir/weak-fundef.so \
"$opts tmpdir/weak-fundef.o"]} then {
fail $testname
} elseif {![is_remote host] && [which $nm] == 0} then {
unresolved $testname
} else {
set exec_output [run_host_cmd "$nm" "-D tmpdir/weak-fundef.so"]
set exec_output [prune_warnings $exec_output]
set output_regexp ".*w undef_weak_fun.*"
if {[regexp $output_regexp $exec_output] == $passval} then {
pass $testname
} else {
fail $testname
}
return 1
}
return 0
}
proc undef_weak_exe { testname opts passval } {
global ld
global nm
if {![ld_link $ld tmpdir/weak-fundef \
"$opts tmpdir/weak-fundef.o tmpdir/weak-fundef.so"]} then {
fail $testname
} elseif {![is_remote host] && [which $nm] == 0} then {
unresolved $testname
} else {
set exec_output [run_host_cmd "$nm" "-D tmpdir/weak-fundef"]
set exec_output [prune_warnings $exec_output]
set output_regexp ".*w undef_weak_fun.*"
if {[regexp $output_regexp $exec_output] == $passval} then {
pass $testname
} else {
fail $testname
}
}
}
# When linking a shared lib, weak undefined symbols should become dynamic.
set testname "weak undefined function symbols in shared lib"
@ -71,39 +117,40 @@ if { $asflags == "" || ![is_elf_format] || ![check_shared_lib_support]} then {
} elseif {![ld_assemble $as "$asflags $srcdir/$subdir/weak-fundef.s" \
tmpdir/weak-fundef.o]} then {
fail $testname
} elseif {![ld_link $ld tmpdir/weak-fundef.so \
"--shared tmpdir/weak-fundef.o"]} then {
fail $testname
} elseif {![is_remote host] && [which $nm] == 0} then {
unresolved $testname
} else {
set exec_output [run_host_cmd "$nm" "-D tmpdir/weak-fundef.so"]
set exec_output [prune_warnings $exec_output]
verbose -log $exec_output
set output_regexp ".*w undef_weak_fun.*"
if {[regexp $output_regexp $exec_output]} then {
pass $testname
} else {
fail $testname
}
} elseif { [undef_weak_so $testname "--shared" 1] } then {
# When linking a dynamic executable, weak undefined symbols become dynamic.
set testname "weak undefined function symbols in dynamic exe"
undef_weak_exe $testname "--no-as-needed" 1
if {![ld_link $ld tmpdir/weak-fundef \
"--no-as-needed tmpdir/weak-fundef.o tmpdir/weak-fundef.so"]} then {
fail $testname
} else {
set exec_output [run_host_cmd "$nm" "-D tmpdir/weak-fundef"]
set exec_output [prune_warnings $exec_output]
verbose -log $exec_output
# Find -z options supported by the default emulation
set emul [get_target_emul]
set cmd [list "$ld --help 2>&1 | sed -e '1,/^$emul:/d;/^\[^ \]*:/,\$d'"]
set status [remote_exec host [concat sh -c $cmd]]
if { [lindex $status 0] != 0 } {
verbose -log "$cmd exited with status [lindex $status 0]"
}
set emulopt [lindex $status 1]
if {[regexp $output_regexp $exec_output]} then {
pass $testname
} else {
fail $testname
}
if { [string first "dynamic-undefined-weak" $emulopt] >= 0 } {
# -z dynamic-undefined-weak is supported. Let's see if it works.
set testname "weak undefined functions in shared lib, no dyn undef weak"
undef_weak_so $testname "--shared -z nodynamic-undefined-weak" 0
set testname "weak undefined functions in shared lib, dyn undef weak"
undef_weak_so $testname "--shared -z dynamic-undefined-weak" 1
set testname "weak undefined functions in dynamic exe, no dyn undef weak"
undef_weak_exe $testname "-z nodynamic-undefined-weak" 0
set testname "weak undefined functions in dynamic exe, dyn undef weak"
undef_weak_exe $testname "-z dynamic-undefined-weak" 1
set testname "weak undefined functions in pie, no dyn undef weak"
undef_weak_exe $testname "-pie -z nodynamic-undefined-weak" 0
set testname "weak undefined functions in pie, dyn undef weak"
undef_weak_exe $testname "-pie -z dynamic-undefined-weak" 1
}
}