ld: Unify STT_GNU_IFUNC handling
Take STT_GNU_IFUNC handling scattered across targets and gather it in the generic ELF linker. bfd/ PR ld/23238 * elf-s390-common.c (elf_s390_add_symbol_hook): Removed. * elf32-arc.c (elf_arc_add_symbol_hook): Likewise. (elf_backend_add_symbol_hook): Likewise. * elf32-m68k.c (elf_m68k_add_symbol_hook): Likewise. (elf_backend_add_symbol_hook): Likewise. * elf32-s390.c (elf_backend_add_symbol_hook): Likewise. * elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise. (elf_backend_add_symbol_hook): Likewise. * elf64-s390.c (elf_backend_add_symbol_hook): Likewise. * elfxx-aarch64.c (_bfd_aarch64_elf_add_symbol_hook): Likewise. * elfxx-aarch64.h (_bfd_aarch64_elf_add_symbol_hook): Likewise. (elf_backend_add_symbol_hook): Likewise. * elf32-arm.c (elf32_arm_add_symbol_hook): Remove STT_GNU_IFUNC handling. * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise. * elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise. * elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise. * elflink.c (elf_link_add_object_symbols): Set elf_gnu_symbol_ifunc for STT_GNU_IFUNC symbols. ld/ PR ld/23238 * testsuite/ld-ifunc/ifunc-26.d: New file. * testsuite/ld-ifunc/ifunc-26.s: Likewise. * testsuite/ld-ifunc/ifunc.exp: Run *.d tests without a working compiler.
This commit is contained in:
parent
03fce1c78c
commit
ac98f9e227
@ -1,3 +1,26 @@
|
||||
2018-05-28 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/23238
|
||||
* elf-s390-common.c (elf_s390_add_symbol_hook): Removed.
|
||||
* elf32-arc.c (elf_arc_add_symbol_hook): Likewise.
|
||||
(elf_backend_add_symbol_hook): Likewise.
|
||||
* elf32-m68k.c (elf_m68k_add_symbol_hook): Likewise.
|
||||
(elf_backend_add_symbol_hook): Likewise.
|
||||
* elf32-s390.c (elf_backend_add_symbol_hook): Likewise.
|
||||
* elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
|
||||
(elf_backend_add_symbol_hook): Likewise.
|
||||
* elf64-s390.c (elf_backend_add_symbol_hook): Likewise.
|
||||
* elfxx-aarch64.c (_bfd_aarch64_elf_add_symbol_hook): Likewise.
|
||||
* elfxx-aarch64.h (_bfd_aarch64_elf_add_symbol_hook): Likewise.
|
||||
(elf_backend_add_symbol_hook): Likewise.
|
||||
* elf32-arm.c (elf32_arm_add_symbol_hook): Remove STT_GNU_IFUNC
|
||||
handling.
|
||||
* elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
|
||||
* elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
|
||||
* elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
|
||||
* elflink.c (elf_link_add_object_symbols): Set
|
||||
elf_gnu_symbol_ifunc for STT_GNU_IFUNC symbols.
|
||||
|
||||
2018-05-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/23194
|
||||
|
@ -223,25 +223,6 @@ elf_s390_allocate_local_syminfo (bfd *abfd, Elf_Internal_Shdr *symtab_hdr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Pick ELFOSABI_GNU if IFUNC symbols are used. */
|
||||
|
||||
static bfd_boolean
|
||||
elf_s390_add_symbol_hook (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
Elf_Internal_Sym *sym,
|
||||
const char **namep ATTRIBUTE_UNUSED,
|
||||
flagword *flagsp ATTRIBUTE_UNUSED,
|
||||
asection **secp ATTRIBUTE_UNUSED,
|
||||
bfd_vma *valp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Whether to sort relocs output by ld -r or ld --emit-relocs, by
|
||||
r_offset. Don't do so for code sections. We want to keep ordering
|
||||
of GDCALL / PLT32DBL for TLS optimizations as is. On the other
|
||||
|
@ -2797,26 +2797,6 @@ const struct elf_size_info arc_elf32_size_info =
|
||||
|
||||
#define elf_backend_size_info arc_elf32_size_info
|
||||
|
||||
/* Hook called by the linker routine which adds symbols from an object
|
||||
file. */
|
||||
|
||||
static bfd_boolean
|
||||
elf_arc_add_symbol_hook (bfd * abfd,
|
||||
struct bfd_link_info * info,
|
||||
Elf_Internal_Sym * sym,
|
||||
const char ** namep ATTRIBUTE_UNUSED,
|
||||
flagword * flagsp ATTRIBUTE_UNUSED,
|
||||
asection ** secp ATTRIBUTE_UNUSED,
|
||||
bfd_vma * valp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* GDB expects general purpose registers to be in section .reg. However Linux
|
||||
kernel doesn't create this section and instead writes registers to NOTE
|
||||
section. It is up to the binutils to create a pseudo-section .reg from the
|
||||
@ -2946,7 +2926,6 @@ elf32_arc_section_from_shdr (bfd *abfd,
|
||||
|
||||
#define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
|
||||
#define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
|
||||
#define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
|
||||
|
||||
#define elf_backend_can_gc_sections 1
|
||||
#define elf_backend_want_got_plt 1
|
||||
|
@ -19753,11 +19753,6 @@ elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
|
||||
Elf_Internal_Sym *sym, const char **namep,
|
||||
flagword *flagsp, asection **secp, bfd_vma *valp)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
if (elf32_arm_hash_table (info) == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@ -4589,26 +4589,6 @@ elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Hook called by the linker routine which adds symbols from an object
|
||||
file. */
|
||||
|
||||
static bfd_boolean
|
||||
elf_m68k_add_symbol_hook (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
Elf_Internal_Sym *sym,
|
||||
const char **namep ATTRIBUTE_UNUSED,
|
||||
flagword *flagsp ATTRIBUTE_UNUSED,
|
||||
asection **secp ATTRIBUTE_UNUSED,
|
||||
bfd_vma *valp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define TARGET_BIG_SYM m68k_elf32_vec
|
||||
#define TARGET_BIG_NAME "elf32-m68k"
|
||||
#define ELF_MACHINE_CODE EM_68K
|
||||
@ -4646,7 +4626,6 @@ elf_m68k_add_symbol_hook (bfd *abfd,
|
||||
#define elf_backend_object_p elf32_m68k_object_p
|
||||
#define elf_backend_grok_prstatus elf_m68k_grok_prstatus
|
||||
#define elf_backend_grok_psinfo elf_m68k_grok_psinfo
|
||||
#define elf_backend_add_symbol_hook elf_m68k_add_symbol_hook
|
||||
|
||||
#define elf_backend_can_gc_sections 1
|
||||
#define elf_backend_can_refcount 1
|
||||
|
@ -3792,11 +3792,6 @@ ppc_elf_add_symbol_hook (bfd *abfd,
|
||||
*valp = sym->st_size;
|
||||
}
|
||||
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -4049,7 +4049,6 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
|
||||
#define elf_backend_grok_psinfo elf_s390_grok_psinfo
|
||||
#define elf_backend_write_core_note elf_s390_write_core_note
|
||||
#define elf_backend_plt_sym_val elf_s390_plt_sym_val
|
||||
#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
|
||||
#define elf_backend_sort_relocs_p elf_s390_elf_sort_relocs_p
|
||||
|
||||
#define bfd_elf32_mkobject elf_s390_mkobject
|
||||
|
@ -175,25 +175,6 @@ elf32_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
|
||||
}
|
||||
}
|
||||
|
||||
/* Hook called by the linker routine which adds symbols from an object
|
||||
file. */
|
||||
|
||||
static bfd_boolean
|
||||
elf32_sparc_add_symbol_hook (bfd * abfd,
|
||||
struct bfd_link_info * info,
|
||||
Elf_Internal_Sym * sym,
|
||||
const char ** namep ATTRIBUTE_UNUSED,
|
||||
flagword * flagsp ATTRIBUTE_UNUSED,
|
||||
asection ** secp ATTRIBUTE_UNUSED,
|
||||
bfd_vma * valp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define TARGET_BIG_SYM sparc_elf32_vec
|
||||
#define TARGET_BIG_NAME "elf32-sparc"
|
||||
#define ELF_ARCH bfd_arch_sparc
|
||||
@ -249,8 +230,6 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
|
||||
#define elf_backend_want_dynrelro 1
|
||||
#define elf_backend_rela_normal 1
|
||||
|
||||
#define elf_backend_add_symbol_hook elf32_sparc_add_symbol_hook
|
||||
|
||||
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
|
||||
|
||||
#include "elf32-target.h"
|
||||
|
@ -5034,11 +5034,6 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
|
||||
asection **sec,
|
||||
bfd_vma *value)
|
||||
{
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
|
||||
&& (ibfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
if (*sec != NULL
|
||||
&& strcmp ((*sec)->name, ".opd") == 0)
|
||||
{
|
||||
|
@ -3962,7 +3962,6 @@ const struct elf_size_info s390_elf64_size_info =
|
||||
#define elf_backend_grok_psinfo elf_s390_grok_psinfo
|
||||
#define elf_backend_write_core_note elf_s390_write_core_note
|
||||
#define elf_backend_plt_sym_val elf_s390_plt_sym_val
|
||||
#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
|
||||
#define elf_backend_sort_relocs_p elf_s390_elf_sort_relocs_p
|
||||
#define elf_backend_additional_program_headers elf_s390_additional_program_headers
|
||||
#define elf_backend_modify_segment_map elf_s390_modify_segment_map
|
||||
|
@ -444,11 +444,6 @@ elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
|
||||
{
|
||||
static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
|
||||
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
|
||||
{
|
||||
int reg;
|
||||
|
@ -4680,10 +4680,17 @@ error_free_dyn:
|
||||
(struct bfd_link_hash_entry **) sym_hash)))
|
||||
goto error_free_vers;
|
||||
|
||||
if ((flags & BSF_GNU_UNIQUE)
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_unique;
|
||||
if ((abfd->flags & DYNAMIC) == 0
|
||||
&& (bfd_get_flavour (info->output_bfd)
|
||||
== bfd_target_elf_flavour))
|
||||
{
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols
|
||||
|= elf_gnu_symbol_ifunc;
|
||||
if ((flags & BSF_GNU_UNIQUE))
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols
|
||||
|= elf_gnu_symbol_unique;
|
||||
}
|
||||
|
||||
h = *sym_hash;
|
||||
/* We need to make sure that indirect symbol dynamic flags are
|
||||
|
@ -558,25 +558,6 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type,
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Hook called by the linker routine which adds symbols from an object
|
||||
file. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_aarch64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
|
||||
Elf_Internal_Sym *sym,
|
||||
const char **namep ATTRIBUTE_UNUSED,
|
||||
flagword *flagsp ATTRIBUTE_UNUSED,
|
||||
asection **secp ATTRIBUTE_UNUSED,
|
||||
bfd_vma *valp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
|
||||
&& (abfd->flags & DYNAMIC) == 0
|
||||
&& bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
|
||||
elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Support for core dump NOTE sections. */
|
||||
|
||||
bfd_boolean
|
||||
|
@ -47,11 +47,6 @@ extern bfd_vma
|
||||
_bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type, bfd_vma, bfd_vma,
|
||||
bfd_vma, bfd_boolean);
|
||||
|
||||
extern bfd_boolean
|
||||
_bfd_aarch64_elf_add_symbol_hook (bfd *, struct bfd_link_info *,
|
||||
Elf_Internal_Sym *, const char **,
|
||||
flagword *, asection **, bfd_vma *);
|
||||
|
||||
extern bfd_boolean
|
||||
_bfd_aarch64_elf_grok_prstatus (bfd *, Elf_Internal_Note *);
|
||||
|
||||
@ -61,7 +56,6 @@ _bfd_aarch64_elf_grok_psinfo (bfd *, Elf_Internal_Note *);
|
||||
extern char *
|
||||
_bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
|
||||
|
||||
#define elf_backend_add_symbol_hook _bfd_aarch64_elf_add_symbol_hook
|
||||
#define elf_backend_grok_prstatus _bfd_aarch64_elf_grok_prstatus
|
||||
#define elf_backend_grok_psinfo _bfd_aarch64_elf_grok_psinfo
|
||||
#define elf_backend_write_core_note _bfd_aarch64_elf_write_core_note
|
||||
|
@ -1,3 +1,11 @@
|
||||
2018-05-28 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/23238
|
||||
* testsuite/ld-ifunc/ifunc-26.d: New file.
|
||||
* testsuite/ld-ifunc/ifunc-26.s: Likewise.
|
||||
* testsuite/ld-ifunc/ifunc.exp: Run *.d tests without a
|
||||
working compiler.
|
||||
|
||||
2018-05-28 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* testsuite/ld-ifunc/ifunc-10-i386.d: Skip NaCl targets.
|
||||
|
7
ld/testsuite/ld-ifunc/ifunc-26.d
Normal file
7
ld/testsuite/ld-ifunc/ifunc-26.d
Normal file
@ -0,0 +1,7 @@
|
||||
#ld: -shared
|
||||
#readelf: -h
|
||||
|
||||
ELF Header:
|
||||
#...
|
||||
OS/ABI: UNIX - GNU
|
||||
#pass
|
8
ld/testsuite/ld-ifunc/ifunc-26.s
Normal file
8
ld/testsuite/ld-ifunc/ifunc-26.s
Normal file
@ -0,0 +1,8 @@
|
||||
.text
|
||||
.type resolve_do_it, %function
|
||||
resolve_do_it:
|
||||
.byte 0
|
||||
.size resolve_do_it, .-resolve_do_it
|
||||
.globl do_it
|
||||
.type do_it, %gnu_indirect_function
|
||||
.set do_it,resolve_do_it
|
@ -48,6 +48,13 @@ if ![check_shared_lib_support] {
|
||||
# This test does not need a compiler...
|
||||
run_dump_test "ifuncmod5"
|
||||
|
||||
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||
foreach t $test_list {
|
||||
# We need to strip the ".d", but can leave the dirname.
|
||||
verbose [file rootname $t]
|
||||
run_dump_test [file rootname $t]
|
||||
}
|
||||
|
||||
# We need a working compiler. (Strictly speaking this is
|
||||
# not true, we could use target specific assembler files).
|
||||
if { [which $CC] == 0 } {
|
||||
@ -425,13 +432,6 @@ run_ld_link_exec_tests [list \
|
||||
] \
|
||||
]
|
||||
|
||||
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||
foreach t $test_list {
|
||||
# We need to strip the ".d", but can leave the dirname.
|
||||
verbose [file rootname $t]
|
||||
run_dump_test [file rootname $t]
|
||||
}
|
||||
|
||||
# Run-time tests which require working IFUNC support.
|
||||
if { ![check_ifunc_available] } {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user