ld: Unify STT_GNU_IFUNC handling
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 28 May 2018 15:15:06 +0000 (08:15 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 28 May 2018 15:15:21 +0000 (08:15 -0700)
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.

18 files changed:
bfd/ChangeLog
bfd/elf-s390-common.c
bfd/elf32-arc.c
bfd/elf32-arm.c
bfd/elf32-m68k.c
bfd/elf32-ppc.c
bfd/elf32-s390.c
bfd/elf32-sparc.c
bfd/elf64-ppc.c
bfd/elf64-s390.c
bfd/elf64-sparc.c
bfd/elflink.c
bfd/elfxx-aarch64.c
bfd/elfxx-aarch64.h
ld/ChangeLog
ld/testsuite/ld-ifunc/ifunc-26.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-26.s [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc.exp

index 0419bec612fab193a6fa1c303a7f7d2b3a0e8bcf..f190b9f3be042725e5d47fc58a7598cdf8f8afeb 100644 (file)
@@ -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
index 21195f2aa5c02aa76a6311c02018f89b6160770b..b37cb254577a2904d20b1b43d96c9ffe4a7cd7f3 100644 (file)
@@ -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
index 33fff585e404b6e47178201195782a4516125443..a48ef0ca15fb1effb0d0aea0538515bfc817c98d 100644 (file)
@@ -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
index 5a3b58ff0dc63cbe84940cf4a9232f83e6bef92e..dbfd838fbe09eaceb905fcaa6b7416fc5c83cbad 100644 (file)
@@ -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;
 
index 8680504cee6b2ccaa7ad6e034fba078296643c0b..70532c29ea7ba814c26d53129ca6746fda2fcc82 100644 (file)
@@ -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
index 462c8af3119042332c1a0b5dd20fd4e70b049b8c..3482baca2051dbb98f42de21d5369655133a2661 100644 (file)
@@ -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;
 }
 \f
index b3603bd865b46481cac81328b8710d893d3b0a75..99ceb76d3d1fab42a4ff05fc5fd4eb3a7844504c 100644 (file)
@@ -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
index 1a18e1ea0f54973c7bbf51795f01e91d2ddeb4f6..4378b6177c5cf9dd98428d09e7c77aacc3ca757e 100644 (file)
@@ -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"
index 7f7a8f777ed9c1157bd771360e05ed86e3d4c5af..f543cb02887237c9ba18305cdf893bbc408c930d 100644 (file)
@@ -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)
     {
index bfa02340cadabaa41e54fc50cb2b464326c0dd72..612557fa74ff300307200a51c1ff940d5947151c 100644 (file)
@@ -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
index b4c04755ce325b3e14bf55aea55a4f5cd80b955e..8c45d3257e43511658a89b2f3ef8de70d72639f2 100644 (file)
@@ -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;
index 05664b4e89bb4f546a120a26e0479ddea2dfd265..9dfd3e957f358b55e33c73e9eec451268ec40beb 100644 (file)
@@ -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
index 45a732db2bc745a36dd48396dd6b4d9f46a6ee30..af37f828d54199ecbd38ee718932d5f147c7d00c 100644 (file)
@@ -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
index 977faf3a4f8fc3bc9d6ee1700480e9f606caa4f0..301af73e3ecf2800d0dd8a3558ad35f03867f6d7 100644 (file)
@@ -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
index 0d6bf36c0db0dc313ec46753df0653afc0e3790b..c49ce46dd59dcd732c156939b0eb6ab7bf52417a 100644 (file)
@@ -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.
diff --git a/ld/testsuite/ld-ifunc/ifunc-26.d b/ld/testsuite/ld-ifunc/ifunc-26.d
new file mode 100644 (file)
index 0000000..3b1e9f1
--- /dev/null
@@ -0,0 +1,7 @@
+#ld: -shared
+#readelf: -h
+
+ELF Header:
+#...
+  OS/ABI:                            UNIX - GNU
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-26.s b/ld/testsuite/ld-ifunc/ifunc-26.s
new file mode 100644 (file)
index 0000000..2b18d9b
--- /dev/null
@@ -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
index 9f4aa73e7a749dd3e2f0116b567908ec3705eb80..dd3abd475ae2c328212f5cc424a5c9e4f8b9e276 100644 (file)
@@ -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