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:
parent
951787ed6d
commit
954b63d4c8
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
14
ld/ChangeLog
14
ld/ChangeLog
@ -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
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user