]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Don't generate PLT for IFUNC GOT/pointer reference
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 18 Jun 2016 16:16:52 +0000 (09:16 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 18 Jun 2016 16:17:25 +0000 (09:17 -0700)
If a backend supports it, PLT entry isn't needed when all references
to a STT_GNU_IFUNC symbols are done via GOT or static function pointers.
For GOT entries, We generate dynamic R_*_GLOB_DAT relocations for
preemptable symbols and R_*_IRELATIVE relocations for non-preemptable
symbols to update them with real function address.  For static pointer
pointers, we generate dynamic pointer relocations and store them in:

1. .rel[a].ifunc section in PIC object.
2. .rel[a].got section in dynamic executable.
3. .rel[a].iplt section in static executable.

We don't allocate GOT entry if it isn't used.

bfd/

PR ld/20253
* elf-bfd.h (_bfd_elf_allocate_ifunc_dyn_relocs): Add an
bfd_boolean argument.
* elf-ifunc.c (_bfd_elf_create_ifunc_sections): Replace
"shared object" with "PIC object" in comments.
(_bfd_elf_allocate_ifunc_dyn_relocs): Updated.  Replace
"shared object" with "PIC object" in comments.  Avoid PLT if
requested.  Generate dynamic relocations for non-GOT references.
Make room for the special first entry in PLT and allocate PLT
entry only for PLT and PC-relative references.  Store dynamic
GOT relocations in .rel[a].iplt section for static executables.
If PLT isn't used, always use GOT for symbol value.  Don't
allocate GOT entry if it isn't used.
* elf32-i386.c (elf_i386_check_relocs): Increment PLT reference
count only in the code section.  Allocate dynamic pointer
relocation against STT_GNU_IFUNC symbol in the non-code section.
(elf_i386_adjust_dynamic_symbol): Increment PLT reference count
only for PC-relative references.
(elf_i386_allocate_dynrelocs): Pass TRUE to
_bfd_elf_allocate_ifunc_dyn_relocs.
(elf_i386_relocate_section): Allow R_386_GOT32/R_386_GOT32X
relocations against STT_GNU_IFUNC symbols without PLT.  Generate
dynamic pointer relocation against STT_GNU_IFUNC symbol in
the non-code section and store it in the proper REL section.
Don't allow non-pointer relocation against STT_GNU_IFUNC symbol
without PLT.
(elf_i386_finish_dynamic_symbol): Generate dynamic
R_386_IRELATIVE and R_386_GLOB_DAT GOT relocations against
STT_GNU_IFUNC symbols without PLT.
(elf_i386_finish_dynamic_sections): Don't handle local
STT_GNU_IFUNC symbols here.
(elf_i386_output_arch_local_syms): Handle local STT_GNU_IFUNC
symbols here.
(elf_backend_output_arch_local_syms): New.
* elf32-x86-64.c (elf_i386_check_relocs): Increment PLT reference
count only in the code section.  Allocate dynamic pointer
relocation against STT_GNU_IFUNC symbol in the non-code section.
(elf_x86_64_adjust_dynamic_symbol): Increment PLT reference
count only for PC-relative references.
(elf_x86_64_allocate_dynrelocs): Pass TRUE to
_bfd_elf_allocate_ifunc_dyn_relocs.
(elf_x86_64_relocate_section): Allow R_X86_64_GOTPCREL,
R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX and
R_X86_64_GOTPCREL64 relocations against STT_GNU_IFUNC symbols
without PLT.  Generate dynamic pointer relocation against
STT_GNU_IFUNC symbol in the non-code section and store it in
the proper RELA section.  Don't allow non-pointer relocation
against STT_GNU_IFUNC symbol without PLT.
(elf_x86_64_finish_dynamic_symbol): Generate dynamic
R_X86_64_IRELATIVE and R_X86_64_GLOB_DAT GOT relocations against
STT_GNU_IFUNC symbols without PLT.
(elf_x86_64_finish_dynamic_sections): Don't handle local
STT_GNU_IFUNC symbols here.
(elf_x86_64_output_arch_local_syms): Handle local STT_GNU_IFUNC
symbols here.
(elf_backend_output_arch_local_syms): New.
* elfnn-aarch64.c (elfNN_aarch64_allocate_ifunc_dynrelocs):
Pass FALSE to _bfd_elf_allocate_ifunc_dyn_relocs.

ld/

PR ld/20253
* testsuite/ld-i386/i386.exp: Run PR ld/20253 tests.
* testsuite/ld-i386/no-plt.exp: Likewise.
* testsuite/ld-x86-64/no-plt.exp: Likewise.
* testsuite/ld-i386/pr13302.d: Remove .rel.plt section.
* testsuite/ld-ifunc/ifunc-13-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-13-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-15-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-15-x86-64.d: Likewise.
* testsuite/ld-x86-64/pr13082-5a.d: Likewise.
* testsuite/ld-x86-64/pr13082-5b.d: Likewise.
* testsuite/ld-x86-64/pr13082-6a.d: Likewise.
* testsuite/ld-x86-64/pr13082-6b.d: Likewise.
* testsuite/ld-i386/pr20244-2a.d: Remove .plt section.
* testsuite/ld-ifunc/ifunc-21-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-22-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise.
* testsuite/ld-i386/pr20244-2b.d: Updated.
* testsuite/ld-i386/pr20244-2c.d: Likewise.
* testsuite/ld-ifunc/ifunc-18a-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise.
* testsuite/ld-i386/pr20253-1a.c: New file.
* testsuite/ld-i386/pr20253-1b.S: Likewise.
* testsuite/ld-i386/pr20253-1c.S: Likewise.
* testsuite/ld-i386/pr20253-1d.S: Likewise.
* testsuite/ld-i386/pr20253-2a.c: Likewise.
* testsuite/ld-i386/pr20253-2b.S: Likewise.
* testsuite/ld-i386/pr20253-2c.S: Likewise.
* testsuite/ld-i386/pr20253-2d.S: Likewise.
* testsuite/ld-i386/pr20253-3.d: Likewise.
* testsuite/ld-i386/pr20253-3.s: Likewise.
* testsuite/ld-i386/pr20253-4.s: Likewise.
* testsuite/ld-i386/pr20253-4a.d: Likewise.
* testsuite/ld-i386/pr20253-4b.d: Likewise.
* testsuite/ld-i386/pr20253-4c.d: Likewise.
* testsuite/ld-i386/pr20253-5.d: Likewise.
* testsuite/ld-i386/pr20253-5.s: Likewise.
* testsuite/ld-ifunc/ifunc-23-x86.s: Likewise.
* testsuite/ld-ifunc/ifunc-23a-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-23b-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-23c-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-24-x86.s: Likewise.
* testsuite/ld-ifunc/ifunc-24a-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-24b-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-24c-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-25-x86.s: Likewise.
* testsuite/ld-ifunc/ifunc-25a-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-25b-x86.d: Likewise.
* testsuite/ld-ifunc/ifunc-25c-x86.d: Likewise.
* testsuite/ld-x86-64/pr20253-1.s: Likewise.
* testsuite/ld-x86-64/pr20253-1a.d: Likewise.
* testsuite/ld-x86-64/pr20253-1b.d: Likewise.
* testsuite/ld-x86-64/pr20253-1c.d: Likewise.
* testsuite/ld-x86-64/pr20253-1d.d: Likewise.
* testsuite/ld-x86-64/pr20253-1e.d: Likewise.
* testsuite/ld-x86-64/pr20253-1f.d: Likewise.
* testsuite/ld-x86-64/pr20253-1g.d: Likewise.
* testsuite/ld-x86-64/pr20253-1h.d: Likewise.
* testsuite/ld-x86-64/pr20253-1i.d: Likewise.
* testsuite/ld-x86-64/pr20253-1j.d: Likewise.
* testsuite/ld-x86-64/pr20253-1k.d: Likewise.
* testsuite/ld-x86-64/pr20253-1l.d: Likewise.
* testsuite/ld-x86-64/pr20253-2a.c: Likewise.
* testsuite/ld-x86-64/pr20253-2b.S: Likewise.
* testsuite/ld-x86-64/pr20253-2c.S: Likewise.
* testsuite/ld-x86-64/pr20253-2d.S: Likewise.
* testsuite/ld-x86-64/pr20253-3.d: Likewise.
* testsuite/ld-x86-64/pr20253-3.s: Likewise.
* testsuite/ld-x86-64/pr20253-4.s: Likewise.
* testsuite/ld-x86-64/pr20253-4a.d: Likewise.
* testsuite/ld-x86-64/pr20253-4b.d: Likewise.
* testsuite/ld-x86-64/pr20253-4c.d: Likewise.
* testsuite/ld-x86-64/pr20253-4d.d: Likewise.
* testsuite/ld-x86-64/pr20253-4e.d: Likewise.
* testsuite/ld-x86-64/pr20253-4f.d: Likewise.
* testsuite/ld-x86-64/pr20253-5.s: Likewise.
* testsuite/ld-x86-64/pr20253-5a.d: Likewise.
* testsuite/ld-x86-64/pr20253-5b.d: Likewise.
* testsuite/ld-ifunc/ifunc-18a-i386.d: Remove extra IRELATIVE
relocation.
* testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-18a.s: Fix a typo.
* testsuite/ld-x86-64/x86-64.exp: Run pr20253-1 tests.

89 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf-ifunc.c
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/no-plt.exp
ld/testsuite/ld-i386/pr13302.d
ld/testsuite/ld-i386/pr20244-2a.d
ld/testsuite/ld-i386/pr20244-2b.d
ld/testsuite/ld-i386/pr20244-2c.d
ld/testsuite/ld-i386/pr20253-1a.c [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-1b.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-1c.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-1d.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-2a.c [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-2b.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-2c.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-2d.S [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-3.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-3.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-4.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-4a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-4b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-4c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-5.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20253-5.s [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-13-i386.d
ld/testsuite/ld-ifunc/ifunc-13-x86-64.d
ld/testsuite/ld-ifunc/ifunc-15-i386.d
ld/testsuite/ld-ifunc/ifunc-15-x86-64.d
ld/testsuite/ld-ifunc/ifunc-18a-i386.d
ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d
ld/testsuite/ld-ifunc/ifunc-18a.s
ld/testsuite/ld-ifunc/ifunc-18b-i386.d
ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d
ld/testsuite/ld-ifunc/ifunc-21-i386.d
ld/testsuite/ld-ifunc/ifunc-21-x86-64.d
ld/testsuite/ld-ifunc/ifunc-22-i386.d
ld/testsuite/ld-ifunc/ifunc-22-x86-64.d
ld/testsuite/ld-ifunc/ifunc-23-x86.s [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-23a-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-23b-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-23c-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-24-x86.s [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-24a-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-24b-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-24c-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-25-x86.s [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-25a-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-25b-x86.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-25c-x86.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/no-plt.exp
ld/testsuite/ld-x86-64/pr13082-5a.d
ld/testsuite/ld-x86-64/pr13082-5b.d
ld/testsuite/ld-x86-64/pr13082-6a.d
ld/testsuite/ld-x86-64/pr13082-6b.d
ld/testsuite/ld-x86-64/pr20253-1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1g.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1h.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1i.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1j.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1k.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-1l.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-2a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-2b.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-2c.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-2d.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-3.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-3.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-4f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-5.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-5a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20253-5b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 0e52b9512b510dec920d92d1b8403ce6fa81f55e..2173fc9fca43c5d1ec9c12b18dcb036036b0970a 100644 (file)
@@ -1,3 +1,64 @@
+2016-06-18  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20253
+       * elf-bfd.h (_bfd_elf_allocate_ifunc_dyn_relocs): Add an
+       bfd_boolean argument.
+       * elf-ifunc.c (_bfd_elf_create_ifunc_sections): Replace
+       "shared object" with "PIC object" in comments.
+       (_bfd_elf_allocate_ifunc_dyn_relocs): Updated.  Replace
+       "shared object" with "PIC object" in comments.  Avoid PLT if
+       requested.  Generate dynamic relocations for non-GOT references.
+       Make room for the special first entry in PLT and allocate PLT
+       entry only for PLT and PC-relative references.  Store dynamic
+       GOT relocations in .rel[a].iplt section for static executables.
+       If PLT isn't used, always use GOT for symbol value.  Don't
+       allocate GOT entry if it isn't used.
+       * elf32-i386.c (elf_i386_check_relocs): Increment PLT reference
+       count only in the code section.  Allocate dynamic pointer
+       relocation against STT_GNU_IFUNC symbol in the non-code section.
+       (elf_i386_adjust_dynamic_symbol): Increment PLT reference count
+       only for PC-relative references.
+       (elf_i386_allocate_dynrelocs): Pass TRUE to
+       _bfd_elf_allocate_ifunc_dyn_relocs.
+       (elf_i386_relocate_section): Allow R_386_GOT32/R_386_GOT32X
+       relocations against STT_GNU_IFUNC symbols without PLT.  Generate
+       dynamic pointer relocation against STT_GNU_IFUNC symbol in
+       the non-code section and store it in the proper REL section.
+       Don't allow non-pointer relocation against STT_GNU_IFUNC symbol
+       without PLT.
+       (elf_i386_finish_dynamic_symbol): Generate dynamic
+       R_386_IRELATIVE and R_386_GLOB_DAT GOT relocations against
+       STT_GNU_IFUNC symbols without PLT.
+       (elf_i386_finish_dynamic_sections): Don't handle local
+       STT_GNU_IFUNC symbols here.
+       (elf_i386_output_arch_local_syms): Handle local STT_GNU_IFUNC
+       symbols here.
+       (elf_backend_output_arch_local_syms): New.
+       * elf32-x86-64.c (elf_i386_check_relocs): Increment PLT reference
+       count only in the code section.  Allocate dynamic pointer
+       relocation against STT_GNU_IFUNC symbol in the non-code section.
+       (elf_x86_64_adjust_dynamic_symbol): Increment PLT reference
+       count only for PC-relative references.
+       (elf_x86_64_allocate_dynrelocs): Pass TRUE to
+       _bfd_elf_allocate_ifunc_dyn_relocs.
+       (elf_x86_64_relocate_section): Allow R_X86_64_GOTPCREL,
+       R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX and
+       R_X86_64_GOTPCREL64 relocations against STT_GNU_IFUNC symbols
+       without PLT.  Generate dynamic pointer relocation against
+       STT_GNU_IFUNC symbol in the non-code section and store it in
+       the proper RELA section.  Don't allow non-pointer relocation
+       against STT_GNU_IFUNC symbol without PLT.
+       (elf_x86_64_finish_dynamic_symbol): Generate dynamic
+       R_X86_64_IRELATIVE and R_X86_64_GLOB_DAT GOT relocations against
+       STT_GNU_IFUNC symbols without PLT.
+       (elf_x86_64_finish_dynamic_sections): Don't handle local
+       STT_GNU_IFUNC symbols here.
+       (elf_x86_64_output_arch_local_syms): Handle local STT_GNU_IFUNC
+       symbols here.
+       (elf_backend_output_arch_local_syms): New.
+       * elfnn-aarch64.c (elfNN_aarch64_allocate_ifunc_dynrelocs):
+       Pass FALSE to _bfd_elf_allocate_ifunc_dyn_relocs.
+
 2016-06-17  Thomas Preud'homme  <thomas.preudhomme@arm.com>
            Tony Wang  <tony.wang@arm.com>
 
index 6825530dcebaefea4665f10131a32e24071f2e50..163ef35fadcc41987dd234c56d818be606a10cfe 100644 (file)
@@ -2521,7 +2521,7 @@ extern bfd_boolean _bfd_elf_create_ifunc_sections
 extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
   (struct bfd_link_info *, struct elf_link_hash_entry *,
    struct elf_dyn_relocs **, bfd_boolean *, unsigned int,
-   unsigned int, unsigned int);
+   unsigned int, unsigned int, bfd_boolean);
 extern long _bfd_elf_ifunc_get_synthetic_symtab
   (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *,
    bfd_vma *(*) (bfd *, asymbol **, asection *, asection *));
index 1377fedfd3599a07b92adf475cbfe6eeb1815926..09cbf4a3761ec7097f52dcf65e89a61e454aef23 100644 (file)
@@ -55,7 +55,7 @@ _bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
 
   if (bfd_link_pic (info))
     {
-      /* We need to create .rel[a].ifunc for shared objects.  */
+      /* We need to create .rel[a].ifunc for PIC objects.  */
       const char *rel_sec = (bed->rela_plts_and_copies_p
                             ? ".rela.ifunc" : ".rel.ifunc");
 
@@ -113,7 +113,8 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
                                    bfd_boolean *readonly_dynrelocs_against_ifunc_p,
                                    unsigned int plt_entry_size,
                                    unsigned int plt_header_size,
-                                   unsigned int got_entry_size)
+                                   unsigned int got_entry_size,
+                                   bfd_boolean avoid_plt)
 {
   asection *plt, *gotplt, *relplt;
   struct elf_dyn_relocs *p;
@@ -121,13 +122,17 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
   const struct elf_backend_data *bed;
   struct elf_link_hash_table *htab;
   bfd_boolean readonly_dynrelocs_against_ifunc;
-
-  /* When a shared library references a STT_GNU_IFUNC symbol defined
-     in executable, the address of the resolved function may be used.
-     But in non-shared executable, the address of its .plt slot may
-     be used.  Pointer equality may not work correctly.  PIE should
-     be used if pointer equality is required here.  */
-  if (!bfd_link_pic (info)
+  /* If AVOID_PLT is TRUE, don't use PLT if possible.  */
+  bfd_boolean use_plt = !avoid_plt || h->plt.refcount > 0;
+  bfd_boolean need_dynreloc = !use_plt || bfd_link_pic (info);
+
+  /* When a PIC object references a STT_GNU_IFUNC symbol defined
+     in executable or it isn't referenced via PLT, the address of
+     the resolved function may be used.  But in non-PIC executable,
+     the address of its .plt slot may be used.  Pointer equality may
+     not work correctly.  PIE or non-PLT reference should be used if
+     pointer equality is required here.  */
+  if (!need_dynreloc
       && (h->dynindx != -1
          || info->export_dynamic)
       && h->pointer_equality_needed)
@@ -144,16 +149,30 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
 
   htab = elf_hash_table (info);
 
-  /* When building shared library, we need to handle the case where it is
-     marked with regular reference, but not non-GOT reference since the
-     non-GOT reference bit may not be set here.  */
-  if (bfd_link_pic (info) && !h->non_got_ref && h->ref_regular)
-    for (p = *head; p != NULL; p = p->next)
-      if (p->count)
-       {
-         h->non_got_ref = 1;
-         goto keep;
-       }
+  /* When the symbol is marked with regular reference, if PLT isn't used
+     or we are building a PIC object, we must keep dynamic relocation
+     if there is non-GOT reference and use PLT if there is PC-relative
+     reference.  */
+  if (need_dynreloc && h->ref_regular)
+    {
+      bfd_boolean keep = FALSE;
+      for (p = *head; p != NULL; p = p->next)
+       if (p->count)
+         {
+           h->non_got_ref = 1;
+           /* Need dynamic relocations for non-GOT reference.  */
+           keep = TRUE;
+           if (p->pc_count)
+             {
+               /* Must use PLT for PC-relative reference.  */
+               use_plt = TRUE;
+               need_dynreloc = bfd_link_pic (info);
+               break;
+             }
+         }
+      if (keep)
+       goto keep;
+    }
 
   /* Support garbage collection against STT_GNU_IFUNC symbols.  */
   if (h->plt.refcount <= 0 && h->got.refcount <= 0)
@@ -165,7 +184,7 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
     }
 
   /* Return and discard space for dynamic relocations against it if
-     it is never referenced in a non-shared object.  */
+     it is never referenced.  */
   if (!h->ref_regular)
     {
       if (h->plt.refcount > 0
@@ -192,9 +211,9 @@ keep:
       gotplt = htab->sgotplt;
       relplt = htab->srelplt;
 
-      /* If this is the first .plt entry, make room for the special
-        first entry.  */
-      if (plt->size == 0)
+      /* If this is the first .plt entry and PLT is used, make room for
+        the special first entry.  */
+      if (plt->size == 0 && use_plt)
        plt->size += plt_header_size;
     }
   else
@@ -204,26 +223,31 @@ keep:
       relplt = htab->irelplt;
     }
 
-  /* Don't update value of STT_GNU_IFUNC symbol to PLT.  We need
-     the original value for R_*_IRELATIVE.  */
-  h->plt.offset = plt->size;
+  if (use_plt)
+    {
+      /* Don't update value of STT_GNU_IFUNC symbol to PLT.  We need
+        the original value for R_*_IRELATIVE.  */
+      h->plt.offset = plt->size;
 
-  /* Make room for this entry in the .plt/.iplt section.  */
-  plt->size += plt_entry_size;
+      /* Make room for this entry in the .plt/.iplt section.  */
+      plt->size += plt_entry_size;
 
-  /* We also need to make an entry in the .got.plt/.got.iplt section,
-     which will be placed in the .got section by the linker script.  */
-  gotplt->size += got_entry_size;
+      /* We also need to make an entry in the .got.plt/.got.iplt section,
+        which will be placed in the .got section by the linker script.  */
+      gotplt->size += got_entry_size;
+    }
 
   /* We also need to make an entry in the .rel[a].plt/.rel[a].iplt
-     section.  */
-  relplt->size += sizeof_reloc;
-  relplt->reloc_count++;
+     section for GOTPLT relocation if PLT is used.  */
+  if (use_plt)
+    {
+      relplt->size += sizeof_reloc;
+      relplt->reloc_count++;
+    }
 
   /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
-     there is a non-GOT reference in a shared object.  */
-  if (!bfd_link_pic (info)
-      || !h->non_got_ref)
+     there is a non-GOT reference in a PIC object or PLT isn't used.  */
+  if (!need_dynreloc || !h->non_got_ref)
     *head = NULL;
 
   readonly_dynrelocs_against_ifunc = FALSE;
@@ -245,7 +269,20 @@ keep:
          p = p->next;
        }
       while (p != NULL);
-      htab->irelifunc->size += count * sizeof_reloc;
+
+      /* Dynamic relocations are stored in
+        1. .rel[a].ifunc section in PIC object.
+        2. .rel[a].got section in dynamic executable.
+        3. .rel[a].iplt section in static executable.  */
+      if (bfd_link_pic (info))
+       htab->irelifunc->size += count * sizeof_reloc;
+      else if (htab->splt != NULL)
+       htab->srelgot->size += count * sizeof_reloc;
+      else
+       {
+         relplt->size += count * sizeof_reloc;
+         relplt->reloc_count += count;
+       }
     }
 
   if (readonly_dynrelocs_against_ifunc_p)
@@ -254,34 +291,65 @@ keep:
   /* For STT_GNU_IFUNC symbol, .got.plt has the real function address
      and .got has the PLT entry adddress.  We will load the GOT entry
      with the PLT entry in finish_dynamic_symbol if it is used.  For
-     branch, it uses .got.plt.  For symbol value,
-     1. Use .got.plt in a shared object if it is forced local or not
+     branch, it uses .got.plt.  For symbol value, if PLT is used,
+     1. Use .got.plt in a PIC object if it is forced local or not
      dynamic.
-     2. Use .got.plt in a non-shared object if pointer equality isn't
+     2. Use .got.plt in a non-PIC object if pointer equality isn't
      needed.
      3. Use .got.plt in PIE.
      4. Use .got.plt if .got isn't used.
      5. Otherwise use .got so that it can be shared among different
      objects at run-time.
-     We only need to relocate .got entry in shared object.  */
-  if (h->got.refcount <= 0
-      || (bfd_link_pic (info)
-         && (h->dynindx == -1
-             || h->forced_local))
-      || (!bfd_link_pic (info)
-         && !h->pointer_equality_needed)
-      || bfd_link_pie (info)
-      || htab->sgot == NULL)
+     If PLT isn't used, always use .got for symbol value.
+     We only need to relocate .got entry in PIC object or in dynamic
+     executable without PLT.  */
+  if (use_plt
+      && (h->got.refcount <= 0
+         || (bfd_link_pic (info)
+             && (h->dynindx == -1
+                 || h->forced_local))
+         || (!bfd_link_pic (info)
+             && !h->pointer_equality_needed)
+         || bfd_link_pie (info)
+         || htab->sgot == NULL))
     {
       /* Use .got.plt.  */
       h->got.offset = (bfd_vma) -1;
     }
   else
     {
-      h->got.offset = htab->sgot->size;
-      htab->sgot->size += got_entry_size;
-      if (bfd_link_pic (info))
-       htab->srelgot->size += sizeof_reloc;
+      if (!use_plt)
+       {
+         /* PLT isn't used.  */
+         h->plt.offset = (bfd_vma) -1;
+       }
+      if (h->got.refcount <= 0)
+       {
+         /* GOT isn't need when there are only relocations for static
+            pointers.  */
+         h->got.offset = (bfd_vma) -1;
+       }
+      else
+       {
+         h->got.offset = htab->sgot->size;
+         htab->sgot->size += got_entry_size;
+         /* Need to relocate the GOT entry in a PIC object or PLT isn't
+            used.  Otherwise, the GOT entry will be filled with the PLT
+            entry and dynamic GOT relocation isn't needed.  */
+         if (need_dynreloc)
+           {
+             /* For non-static executable, dynamic GOT relocation is in
+                .rel[a].got section, but for static executable, it is
+                in .rel[a].iplt section.  */
+             if (htab->splt != NULL)
+               htab->srelgot->size += sizeof_reloc;
+             else
+               {
+                 relplt->size += sizeof_reloc;
+                 relplt->reloc_count++;
+               }
+           }
+       }
     }
 
   return TRUE;
index 2b7de3397f9fa7d01d3c1c5d8ff4ebc84600fa01..417957214dbb6257e97fe1510ebd431807a1a256 100644 (file)
@@ -2164,9 +2164,13 @@ do_relocation:
                 adjust_dynamic_symbol.  */
              h->non_got_ref = 1;
 
-             /* We may need a .plt entry if the function this reloc
-                refers to is in a shared lib.  */
-             h->plt.refcount += 1;
+             /* We may need a .plt entry if the symbol is a function
+                defined in a shared lib or is a STT_GNU_IFUNC function
+                referenced from the code or read-only section.  */
+             if (!h->def_regular
+                 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+               h->plt.refcount += 1;
+
              if (r_type == R_386_PC32)
                {
                  /* Since something like ".long foo - ." may be used
@@ -2207,7 +2211,10 @@ do_size:
             If on the other hand, we are creating an executable, we
             may need to keep relocations for symbols satisfied by a
             dynamic library if we manage to avoid copy relocs for the
-            symbol.  */
+            symbol.
+
+            Generate dynamic pointer relocation against STT_GNU_IFUNC
+            symbol in the non-code section.  */
          if ((bfd_link_pic (info)
               && (r_type != R_386_PC32
                   || (h != NULL
@@ -2215,6 +2222,10 @@ do_size:
                              || SYMBOLIC_BIND (info, h))
                           || h->root.type == bfd_link_hash_defweak
                           || !h->def_regular))))
+             || (h != NULL
+                 && h->type == STT_GNU_IFUNC
+                 && r_type == R_386_32
+                 && (sec->flags & SEC_CODE) == 0)
              || (ELIMINATE_COPY_RELOCS
                  && !bfd_link_pic (info)
                  && h != NULL
@@ -2448,12 +2459,17 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
 
          if (pc_count || count)
            {
-             h->needs_plt = 1;
              h->non_got_ref = 1;
-             if (h->plt.refcount <= 0)
-               h->plt.refcount = 1;
-             else
-               h->plt.refcount += 1;
+             if (pc_count)
+               {
+                 /* Increment PLT reference count only for PC-relative
+                    references.  */
+                 h->needs_plt = 1;
+                 if (h->plt.refcount <= 0)
+                   h->plt.refcount = 1;
+                 else
+                   h->plt.refcount += 1;
+               }
            }
        }
 
@@ -2643,7 +2659,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
                                               &htab->readonly_dynrelocs_against_ifunc,
                                               plt_entry_size,
-                                              plt_entry_size, 4);
+                                              plt_entry_size, 4, TRUE);
   /* Don't create the PLT entry if there are only function pointer
      relocations which can be resolved at run-time.  */
   else if (htab->elf.dynamic_sections_created
@@ -3898,8 +3914,6 @@ elf_i386_relocate_section (bfd *output_bfd,
                continue;
              abort ();
            }
-         else if (h->plt.offset == (bfd_vma) -1)
-           abort ();
 
          /* STT_GNU_IFUNC symbol must go through PLT.  */
          if (htab->elf.splt != NULL)
@@ -3913,77 +3927,10 @@ elf_i386_relocate_section (bfd *output_bfd,
              gotplt = htab->elf.igotplt;
            }
 
-         relocation = (plt->output_section->vma
-                       + plt->output_offset + h->plt.offset);
-
          switch (r_type)
            {
            default:
-             if (h->root.root.string)
-               name = h->root.root.string;
-             else
-               name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
-                                        NULL);
-             (*_bfd_error_handler)
-               (_("%B: relocation %s against STT_GNU_IFUNC "
-                  "symbol `%s' isn't handled by %s"), input_bfd,
-                elf_howto_table[r_type].name,
-                name, __FUNCTION__);
-             bfd_set_error (bfd_error_bad_value);
-             return FALSE;
-
-           case R_386_32:
-             /* Generate dynamic relcoation only when there is a
-                non-GOT reference in a shared object.  */
-             if (bfd_link_pic (info) && h->non_got_ref)
-               {
-                 Elf_Internal_Rela outrel;
-                 asection *sreloc;
-                 bfd_vma offset;
-
-                 /* Need a dynamic relocation to get the real function
-                    adddress.  */
-                 offset = _bfd_elf_section_offset (output_bfd,
-                                                   info,
-                                                   input_section,
-                                                   rel->r_offset);
-                 if (offset == (bfd_vma) -1
-                     || offset == (bfd_vma) -2)
-                   abort ();
-
-                 outrel.r_offset = (input_section->output_section->vma
-                                    + input_section->output_offset
-                                    + offset);
-
-                 if (h->dynindx == -1
-                     || h->forced_local
-                     || bfd_link_executable (info))
-                   {
-                     /* This symbol is resolved locally.  */
-                     outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
-                     bfd_put_32 (output_bfd,
-                                 (h->root.u.def.value
-                                  + h->root.u.def.section->output_section->vma
-                                  + h->root.u.def.section->output_offset),
-                                 contents + offset);
-                   }
-                 else
-                   outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-
-                 sreloc = htab->elf.irelifunc;
-                 elf_append_rel (output_bfd, sreloc, &outrel);
-
-                 /* If this reloc is against an external symbol, we
-                    do not want to fiddle with the addend.  Otherwise,
-                    we need to include the symbol value so that it
-                    becomes an addend for the dynamic reloc.  For an
-                    internal symbol, we have updated addend.  */
-                 continue;
-               }
-             /* FALLTHROUGH */
-           case R_386_PC32:
-           case R_386_PLT32:
-             goto do_relocation;
+             break;
 
            case R_386_GOT32:
            case R_386_GOT32X:
@@ -3999,6 +3946,9 @@ elf_i386_relocate_section (bfd *output_bfd,
                     even just remember the offset, as finish_dynamic_symbol
                     would use that as offset into .got.  */
 
+                 if (h->plt.offset == (bfd_vma) -1)
+                   abort ();
+
                  if (htab->elf.splt != NULL)
                    {
                      plt_index = h->plt.offset / plt_entry_size - 1;
@@ -4059,6 +4009,99 @@ elf_i386_relocate_section (bfd *output_bfd,
                }
 
              goto do_relocation;
+           }
+
+         if (h->plt.offset == (bfd_vma) -1)
+           {
+             /* Handle static pointers of STT_GNU_IFUNC symbols.  */
+             if (r_type == R_386_32
+                 && (input_section->flags & SEC_CODE) == 0)
+               goto do_ifunc_pointer;
+             goto bad_ifunc_reloc;
+           }
+
+         relocation = (plt->output_section->vma
+                       + plt->output_offset + h->plt.offset);
+
+         switch (r_type)
+           {
+           default:
+bad_ifunc_reloc:
+             if (h->root.root.string)
+               name = h->root.root.string;
+             else
+               name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+                                        NULL);
+             (*_bfd_error_handler)
+               (_("%B: relocation %s against STT_GNU_IFUNC "
+                  "symbol `%s' isn't supported"), input_bfd,
+                howto->name, name);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+
+           case R_386_32:
+             /* Generate dynamic relcoation only when there is a
+                non-GOT reference in a shared object.  */
+             if ((bfd_link_pic (info) && h->non_got_ref)
+                 || h->plt.offset == (bfd_vma) -1)
+               {
+                 Elf_Internal_Rela outrel;
+                 asection *sreloc;
+                 bfd_vma offset;
+
+do_ifunc_pointer:
+                 /* Need a dynamic relocation to get the real function
+                    adddress.  */
+                 offset = _bfd_elf_section_offset (output_bfd,
+                                                   info,
+                                                   input_section,
+                                                   rel->r_offset);
+                 if (offset == (bfd_vma) -1
+                     || offset == (bfd_vma) -2)
+                   abort ();
+
+                 outrel.r_offset = (input_section->output_section->vma
+                                    + input_section->output_offset
+                                    + offset);
+
+                 if (h->dynindx == -1
+                     || h->forced_local
+                     || bfd_link_executable (info))
+                   {
+                     /* This symbol is resolved locally.  */
+                     outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+                     bfd_put_32 (output_bfd,
+                                 (h->root.u.def.value
+                                  + h->root.u.def.section->output_section->vma
+                                  + h->root.u.def.section->output_offset),
+                                 contents + offset);
+                   }
+                 else
+                   outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+
+                 /* Dynamic relocations are stored in
+                    1. .rel.ifunc section in PIC object.
+                    2. .rel.got section in dynamic executable.
+                    3. .rel.iplt section in static executable.  */
+                 if (bfd_link_pic (info))
+                   sreloc = htab->elf.irelifunc;
+                 else if (htab->elf.splt != NULL)
+                   sreloc = htab->elf.srelgot;
+                 else
+                   sreloc = htab->elf.irelplt;
+                 elf_append_rel (output_bfd, sreloc, &outrel);
+
+                 /* If this reloc is against an external symbol, we
+                    do not want to fiddle with the addend.  Otherwise,
+                    we need to include the symbol value so that it
+                    becomes an addend for the dynamic reloc.  For an
+                    internal symbol, we have updated addend.  */
+                 continue;
+               }
+             /* FALLTHROUGH */
+           case R_386_PC32:
+           case R_386_PLT32:
+             goto do_relocation;
 
            case R_386_GOTOFF:
              relocation -= (gotplt->output_section->vma
@@ -5432,6 +5475,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
       && !local_undefweak)
     {
       Elf_Internal_Rela rel;
+      asection *relgot = htab->elf.srelgot;
 
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
@@ -5451,7 +5495,28 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
       if (h->def_regular
          && h->type == STT_GNU_IFUNC)
        {
-         if (bfd_link_pic (info))
+         if (h->plt.offset == (bfd_vma) -1)
+           {
+             /* STT_GNU_IFUNC is referenced without PLT.  */
+             if (htab->elf.splt == NULL)
+               {
+                 /* use .rel[a].iplt section to store .got relocations
+                    in static executable.  */
+                 relgot = htab->elf.irelplt;
+               }
+             if (SYMBOL_REFERENCES_LOCAL (info, h))
+               {
+                 bfd_put_32 (output_bfd,
+                             (h->root.u.def.value
+                              + h->root.u.def.section->output_section->vma
+                              + h->root.u.def.section->output_offset),
+                             htab->elf.sgot->contents + h->got.offset);
+                 rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+               }
+             else
+               goto do_glob_dat;
+           }
+         else if (bfd_link_pic (info))
            {
              /* Generate R_386_GLOB_DAT.  */
              goto do_glob_dat;
@@ -5489,7 +5554,7 @@ do_glob_dat:
          rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
        }
 
-      elf_append_rel (output_bfd, htab->elf.srelgot, &rel);
+      elf_append_rel (output_bfd, relgot, &rel);
     }
 
   if (h->needs_copy)
@@ -5826,11 +5891,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
   if (htab->elf.sgot && htab->elf.sgot->size > 0)
     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
 
-  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
-  htab_traverse (htab->loc_hash_table,
-                elf_i386_finish_local_dynamic_symbol,
-                info);
-
   /* Fill PLT entries for undefined weak symbols in PIE.  */
   if (bfd_link_pie (info))
     bfd_hash_traverse (&info->hash->table,
@@ -5840,6 +5900,33 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
   return TRUE;
 }
 
+/* Fill PLT/GOT entries and allocate dynamic relocations for local
+   STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
+   It has to be done before elf_link_sort_relocs is called so that
+   dynamic relocations are properly sorted.  */
+
+static bfd_boolean
+elf_i386_output_arch_local_syms
+  (bfd *output_bfd ATTRIBUTE_UNUSED,
+   struct bfd_link_info *info,
+   void *flaginfo ATTRIBUTE_UNUSED,
+   int (*func) (void *, const char *,
+               Elf_Internal_Sym *,
+               asection *,
+               struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
+{
+  struct elf_i386_link_hash_table *htab = elf_i386_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
+  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
+  htab_traverse (htab->loc_hash_table,
+                elf_i386_finish_local_dynamic_symbol,
+                info);
+
+  return TRUE;
+}
+
 /* Return an array of PLT entry symbol values.  */
 
 static bfd_vma *
@@ -5982,6 +6069,7 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
 #define elf_backend_fake_sections            elf_i386_fake_sections
 #define elf_backend_finish_dynamic_sections   elf_i386_finish_dynamic_sections
 #define elf_backend_finish_dynamic_symbol     elf_i386_finish_dynamic_symbol
+#define elf_backend_output_arch_local_syms     elf_i386_output_arch_local_syms
 #define elf_backend_gc_mark_hook             elf_i386_gc_mark_hook
 #define elf_backend_grok_prstatus            elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo                      elf_i386_grok_psinfo
index 57a3c73b83a5fd5a2bc05cbfec4b69d2e8a9ca5d..f9202085b38968cdada56b190a210ebcfd3b409f 100644 (file)
@@ -2556,9 +2556,13 @@ pointer:
                 adjust_dynamic_symbol.  */
              h->non_got_ref = 1;
 
-             /* We may need a .plt entry if the function this reloc
-                refers to is in a shared lib.  */
-             h->plt.refcount += 1;
+             /* We may need a .plt entry if the symbol is a function
+                defined in a shared lib or is a STT_GNU_IFUNC function
+                referenced from the code or read-only section.  */
+             if (!h->def_regular
+                 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+               h->plt.refcount += 1;
+
              if (r_type == R_X86_64_PC32)
                {
                  /* Since something like ".long foo - ." may be used
@@ -2605,7 +2609,10 @@ do_size:
             If on the other hand, we are creating an executable, we
             may need to keep relocations for symbols satisfied by a
             dynamic library if we manage to avoid copy relocs for the
-            symbol.  */
+            symbol.
+
+            Generate dynamic pointer relocation against STT_GNU_IFUNC
+            symbol in the non-code section.  */
          if ((bfd_link_pic (info)
               && (! IS_X86_64_PCREL_TYPE (r_type)
                   || (h != NULL
@@ -2613,6 +2620,10 @@ do_size:
                              || SYMBOLIC_BIND (info, h))
                           || h->root.type == bfd_link_hash_defweak
                           || !h->def_regular))))
+             || (h != NULL
+                 && h->type == STT_GNU_IFUNC
+                 && r_type == htab->pointer_r_type
+                 && (sec->flags & SEC_CODE) == 0)
              || (ELIMINATE_COPY_RELOCS
                  && !bfd_link_pic (info)
                  && h != NULL
@@ -2850,12 +2861,17 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
 
          if (pc_count || count)
            {
-             h->needs_plt = 1;
              h->non_got_ref = 1;
-             if (h->plt.refcount <= 0)
-               h->plt.refcount = 1;
-             else
-               h->plt.refcount += 1;
+             if (pc_count)
+               {
+                 /* Increment PLT reference count only for PC-relative
+                    references.  */
+                 h->needs_plt = 1;
+                 if (h->plt.refcount <= 0)
+                   h->plt.refcount = 1;
+                 else
+                   h->plt.refcount += 1;
+               }
            }
        }
 
@@ -3049,7 +3065,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
                                              &htab->readonly_dynrelocs_against_ifunc,
                                              plt_entry_size,
                                              plt_entry_size,
-                                             GOT_ENTRY_SIZE))
+                                             GOT_ENTRY_SIZE, TRUE))
        {
          asection *s = htab->plt_bnd;
          if (h->plt.offset != (bfd_vma) -1 && s != NULL)
@@ -4233,8 +4249,84 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                continue;
              abort ();
            }
-         else if (h->plt.offset == (bfd_vma) -1)
-           abort ();
+
+         switch (r_type)
+           {
+           default:
+             break;
+
+           case R_X86_64_GOTPCREL:
+           case R_X86_64_GOTPCRELX:
+           case R_X86_64_REX_GOTPCRELX:
+           case R_X86_64_GOTPCREL64:
+             base_got = htab->elf.sgot;
+             off = h->got.offset;
+
+             if (base_got == NULL)
+               abort ();
+
+             if (off == (bfd_vma) -1)
+               {
+                 /* We can't use h->got.offset here to save state, or
+                    even just remember the offset, as finish_dynamic_symbol
+                    would use that as offset into .got.  */
+
+                 if (h->plt.offset == (bfd_vma) -1)
+                   abort ();
+
+                 if (htab->elf.splt != NULL)
+                   {
+                     plt_index = h->plt.offset / plt_entry_size - 1;
+                     off = (plt_index + 3) * GOT_ENTRY_SIZE;
+                     base_got = htab->elf.sgotplt;
+                   }
+                 else
+                   {
+                     plt_index = h->plt.offset / plt_entry_size;
+                     off = plt_index * GOT_ENTRY_SIZE;
+                     base_got = htab->elf.igotplt;
+                   }
+
+                 if (h->dynindx == -1
+                     || h->forced_local
+                     || info->symbolic)
+                   {
+                     /* This references the local defitionion.  We must
+                        initialize this entry in the global offset table.
+                        Since the offset must always be a multiple of 8,
+                        we use the least significant bit to record
+                        whether we have initialized it already.
+
+                        When doing a dynamic link, we create a .rela.got
+                        relocation entry to initialize the value.  This
+                        is done in the finish_dynamic_symbol routine.   */
+                     if ((off & 1) != 0)
+                       off &= ~1;
+                     else
+                       {
+                         bfd_put_64 (output_bfd, relocation,
+                                     base_got->contents + off);
+                         /* Note that this is harmless for the GOTPLT64
+                            case, as -1 | 1 still is -1.  */
+                         h->got.offset |= 1;
+                       }
+                   }
+               }
+
+             relocation = (base_got->output_section->vma
+                           + base_got->output_offset + off);
+
+             goto do_relocation;
+           }
+
+         if (h->plt.offset == (bfd_vma) -1)
+           {
+             /* Handle static pointers of STT_GNU_IFUNC symbols.  */
+             if (r_type == htab->pointer_r_type
+                 && (input_section->flags & SEC_CODE) == 0)
+               goto do_ifunc_pointer;
+             goto bad_ifunc_reloc;
+           }
 
          /* STT_GNU_IFUNC symbol must go through PLT.  */
          if (htab->elf.splt != NULL)
@@ -4262,6 +4354,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
          switch (r_type)
            {
            default:
+bad_ifunc_reloc:
              if (h->root.root.string)
                name = h->root.root.string;
              else
@@ -4269,8 +4362,8 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                                         NULL);
              (*_bfd_error_handler)
                (_("%B: relocation %s against STT_GNU_IFUNC "
-                  "symbol `%s' isn't handled by %s"), input_bfd,
-                howto->name, name, __FUNCTION__);
+                  "symbol `%s' isn't supported"), input_bfd,
+                howto->name, name);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
 
@@ -4284,6 +4377,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                goto do_relocation;
              /* FALLTHROUGH */
            case R_X86_64_64:
+do_ifunc_pointer:
              if (rel->r_addend != 0)
                {
                  if (h->root.root.string)
@@ -4300,8 +4394,10 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                }
 
              /* Generate dynamic relcoation only when there is a
-                non-GOT reference in a shared object.  */
-             if (bfd_link_pic (info) && h->non_got_ref)
+                non-GOT reference in a shared object or there is no
+                PLT.  */
+             if ((bfd_link_pic (info) && h->non_got_ref)
+                 || h->plt.offset == (bfd_vma) -1)
                {
                  Elf_Internal_Rela outrel;
                  asection *sreloc;
@@ -4335,7 +4431,16 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                      outrel.r_addend = 0;
                    }
 
-                 sreloc = htab->elf.irelifunc;
+                 /* Dynamic relocations are stored in
+                    1. .rela.ifunc section in PIC object.
+                    2. .rela.got section in dynamic executable.
+                    3. .rela.iplt section in static executable.  */
+                 if (bfd_link_pic (info))
+                   sreloc = htab->elf.irelifunc;
+                 else if (htab->elf.splt != NULL)
+                   sreloc = htab->elf.srelgot;
+                 else
+                   sreloc = htab->elf.irelplt;
                  elf_append_rela (output_bfd, sreloc, &outrel);
 
                  /* If this reloc is against an external symbol, we
@@ -4352,66 +4457,6 @@ elf_x86_64_relocate_section (bfd *output_bfd,
            case R_X86_64_PLT32:
            case R_X86_64_PLT32_BND:
              goto do_relocation;
-
-           case R_X86_64_GOTPCREL:
-           case R_X86_64_GOTPCRELX:
-           case R_X86_64_REX_GOTPCRELX:
-           case R_X86_64_GOTPCREL64:
-             base_got = htab->elf.sgot;
-             off = h->got.offset;
-
-             if (base_got == NULL)
-               abort ();
-
-             if (off == (bfd_vma) -1)
-               {
-                 /* We can't use h->got.offset here to save state, or
-                    even just remember the offset, as finish_dynamic_symbol
-                    would use that as offset into .got.  */
-
-                 if (htab->elf.splt != NULL)
-                   {
-                     plt_index = h->plt.offset / plt_entry_size - 1;
-                     off = (plt_index + 3) * GOT_ENTRY_SIZE;
-                     base_got = htab->elf.sgotplt;
-                   }
-                 else
-                   {
-                     plt_index = h->plt.offset / plt_entry_size;
-                     off = plt_index * GOT_ENTRY_SIZE;
-                     base_got = htab->elf.igotplt;
-                   }
-
-                 if (h->dynindx == -1
-                     || h->forced_local
-                     || info->symbolic)
-                   {
-                     /* This references the local defitionion.  We must
-                        initialize this entry in the global offset table.
-                        Since the offset must always be a multiple of 8,
-                        we use the least significant bit to record
-                        whether we have initialized it already.
-
-                        When doing a dynamic link, we create a .rela.got
-                        relocation entry to initialize the value.  This
-                        is done in the finish_dynamic_symbol routine.   */
-                     if ((off & 1) != 0)
-                       off &= ~1;
-                     else
-                       {
-                         bfd_put_64 (output_bfd, relocation,
-                                     base_got->contents + off);
-                         /* Note that this is harmless for the GOTPLT64
-                            case, as -1 | 1 still is -1.  */
-                         h->got.offset |= 1;
-                       }
-                   }
-               }
-
-             relocation = (base_got->output_section->vma
-                           + base_got->output_offset + off);
-
-             goto do_relocation;
            }
        }
 
@@ -5870,6 +5915,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
       && !local_undefweak)
     {
       Elf_Internal_Rela rela;
+      asection *relgot = htab->elf.srelgot;
 
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
@@ -5888,7 +5934,27 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
       if (h->def_regular
          && h->type == STT_GNU_IFUNC)
        {
-         if (bfd_link_pic (info))
+         if (h->plt.offset == (bfd_vma) -1)
+           {
+             /* STT_GNU_IFUNC is referenced without PLT.  */
+             if (htab->elf.splt == NULL)
+               {
+                 /* use .rel[a].iplt section to store .got relocations
+                    in static executable.  */
+                 relgot = htab->elf.irelplt;
+               }
+             if (SYMBOL_REFERENCES_LOCAL (info, h))
+               {
+                 rela.r_info = htab->r_info (0,
+                                             R_X86_64_IRELATIVE);
+                 rela.r_addend = (h->root.u.def.value
+                                  + h->root.u.def.section->output_section->vma
+                                  + h->root.u.def.section->output_offset);
+               }
+             else
+               goto do_glob_dat;
+           }
+         else if (bfd_link_pic (info))
            {
              /* Generate R_X86_64_GLOB_DAT.  */
              goto do_glob_dat;
@@ -5932,7 +5998,7 @@ do_glob_dat:
          rela.r_addend = 0;
        }
 
-      elf_append_rela (output_bfd, htab->elf.srelgot, &rela);
+      elf_append_rela (output_bfd, relgot, &rela);
     }
 
   if (h->needs_copy)
@@ -6265,11 +6331,6 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
       = GOT_ENTRY_SIZE;
 
-  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
-  htab_traverse (htab->loc_hash_table,
-                elf_x86_64_finish_local_dynamic_symbol,
-                info);
-
   /* Fill PLT entries for undefined weak symbols in PIE.  */
   if (bfd_link_pie (info))
     bfd_hash_traverse (&info->hash->table,
@@ -6279,6 +6340,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
   return TRUE;
 }
 
+/* Fill PLT/GOT entries and allocate dynamic relocations for local
+   STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
+   It has to be done before elf_link_sort_relocs is called so that
+   dynamic relocations are properly sorted.  */
+
+static bfd_boolean
+elf_x86_64_output_arch_local_syms
+  (bfd *output_bfd ATTRIBUTE_UNUSED,
+   struct bfd_link_info *info,
+   void *flaginfo ATTRIBUTE_UNUSED,
+   int (*func) (void *, const char *,
+               Elf_Internal_Sym *,
+               asection *,
+               struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
+{
+  struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
+  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
+  htab_traverse (htab->loc_hash_table,
+                elf_x86_64_finish_local_dynamic_symbol,
+                info);
+
+  return TRUE;
+}
+
 /* Return an array of PLT entry symbol values.  */
 
 static bfd_vma *
@@ -6641,6 +6729,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections
 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
 #define elf_backend_finish_dynamic_symbol   elf_x86_64_finish_dynamic_symbol
+#define elf_backend_output_arch_local_syms  elf_x86_64_output_arch_local_syms
 #define elf_backend_gc_mark_hook           elf_x86_64_gc_mark_hook
 #define elf_backend_grok_prstatus          elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo                    elf_x86_64_grok_psinfo
index 774364a83aa481c066cd38dfb55500c44e5f77a0..fa66b0f595042c72729243cfb374208613ec904b 100644 (file)
@@ -8238,7 +8238,8 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
                                               NULL,
                                               htab->plt_entry_size,
                                               htab->plt_header_size,
-                                              GOT_ENTRY_SIZE);
+                                              GOT_ENTRY_SIZE,
+                                              FALSE);
   return TRUE;
 }
 
index cd5f4e3915657db13ba4496bf62c094fdd448c75..09de0c7a0130a7e4d1543082b4899a0a0246250e 100644 (file)
@@ -1,3 +1,94 @@
+2016-06-18  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20253
+       * testsuite/ld-i386/i386.exp: Run PR ld/20253 tests.
+       * testsuite/ld-i386/no-plt.exp: Likewise.
+       * testsuite/ld-x86-64/no-plt.exp: Likewise.
+       * testsuite/ld-i386/pr13302.d: Remove .rel.plt section.
+       * testsuite/ld-ifunc/ifunc-13-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-13-x86-64.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-15-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-15-x86-64.d: Likewise.
+       * testsuite/ld-x86-64/pr13082-5a.d: Likewise.
+       * testsuite/ld-x86-64/pr13082-5b.d: Likewise.
+       * testsuite/ld-x86-64/pr13082-6a.d: Likewise.
+       * testsuite/ld-x86-64/pr13082-6b.d: Likewise.
+       * testsuite/ld-i386/pr20244-2a.d: Remove .plt section.
+       * testsuite/ld-ifunc/ifunc-21-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-22-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise.
+       * testsuite/ld-i386/pr20244-2b.d: Updated.
+       * testsuite/ld-i386/pr20244-2c.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18a-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise.
+       * testsuite/ld-i386/pr20253-1a.c: New file.
+       * testsuite/ld-i386/pr20253-1b.S: Likewise.
+       * testsuite/ld-i386/pr20253-1c.S: Likewise.
+       * testsuite/ld-i386/pr20253-1d.S: Likewise.
+       * testsuite/ld-i386/pr20253-2a.c: Likewise.
+       * testsuite/ld-i386/pr20253-2b.S: Likewise.
+       * testsuite/ld-i386/pr20253-2c.S: Likewise.
+       * testsuite/ld-i386/pr20253-2d.S: Likewise.
+       * testsuite/ld-i386/pr20253-3.d: Likewise.
+       * testsuite/ld-i386/pr20253-3.s: Likewise.
+       * testsuite/ld-i386/pr20253-4.s: Likewise.
+       * testsuite/ld-i386/pr20253-4a.d: Likewise.
+       * testsuite/ld-i386/pr20253-4b.d: Likewise.
+       * testsuite/ld-i386/pr20253-4c.d: Likewise.
+       * testsuite/ld-i386/pr20253-5.d: Likewise.
+       * testsuite/ld-i386/pr20253-5.s: Likewise.
+       * testsuite/ld-ifunc/ifunc-23-x86.s: Likewise.
+       * testsuite/ld-ifunc/ifunc-23a-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-23b-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-23c-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-24-x86.s: Likewise.
+       * testsuite/ld-ifunc/ifunc-24a-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-24b-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-24c-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-25-x86.s: Likewise.
+       * testsuite/ld-ifunc/ifunc-25a-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-25b-x86.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-25c-x86.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1.s: Likewise.
+       * testsuite/ld-x86-64/pr20253-1a.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1b.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1c.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1d.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1e.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1f.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1g.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1h.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1i.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1j.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1k.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-1l.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-2a.c: Likewise.
+       * testsuite/ld-x86-64/pr20253-2b.S: Likewise.
+       * testsuite/ld-x86-64/pr20253-2c.S: Likewise.
+       * testsuite/ld-x86-64/pr20253-2d.S: Likewise.
+       * testsuite/ld-x86-64/pr20253-3.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-3.s: Likewise.
+       * testsuite/ld-x86-64/pr20253-4.s: Likewise.
+       * testsuite/ld-x86-64/pr20253-4a.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-4b.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-4c.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-4d.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-4e.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-4f.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-5.s: Likewise.
+       * testsuite/ld-x86-64/pr20253-5a.d: Likewise.
+       * testsuite/ld-x86-64/pr20253-5b.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18a-i386.d: Remove extra IRELATIVE
+       relocation.
+       * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise.
+       * testsuite/ld-ifunc/ifunc-18a.s: Fix a typo.
+       * testsuite/ld-x86-64/x86-64.exp: Run pr20253-1 tests.
+
 2016-06-17  Thomas Preud'homme  <thomas.preudhomme@arm.com>
            Tony Wang  <tony.wang@arm.com>
 
index 98f0b1c73fe7e75ed24a417fa8cebd0d7226cd8b..9efe406b9b5d666b975a268c7cea40ddac27684f 100644 (file)
@@ -408,6 +408,11 @@ run_dump_test "pr20244-2a"
 run_dump_test "pr20244-2b"
 run_dump_test "pr20244-2c"
 run_dump_test "pr20244-2d"
+run_dump_test "pr20253-3"
+run_dump_test "pr20253-4a"
+run_dump_test "pr20253-4b"
+run_dump_test "pr20253-4c"
+run_dump_test "pr20253-5"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
index c4af0a9b6905fd3e83c7cd4f21d5b29d2cee36fa..377253ce3b499c598ef08c2c16861e8550d26843 100644 (file)
@@ -265,6 +265,27 @@ if { [check_ifunc_available] } {
            "-fPIC -O2 -g" \
            { pr20244-3a.c pr20244-3b.S pr20244-3c.S pr20244-3d.S } \
        ] \
+       [list \
+           "Build pr20253-1a.o pr20253-1b.o pr20253-1c.o pr20253-1d.o" \
+           "" \
+           "-fPIE -O2 -g" \
+           { pr20253-1a.c pr20253-1b.S pr20253-1c.S pr20253-1d.S } \
+       ] \
+       [list \
+           "Build libpr20253-1a.so" \
+           "-shared tmpdir/pr20253-1b.o \
+            tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \
+           "" \
+           { dummy.s } \
+           {} \
+           "libpr20253-1a.so" \
+       ] \
+       [list \
+           "Build pr20253-2a.o pr20253-2b.o pr20253-2c.o pr20253-2d.o" \
+           "" \
+           "-fPIE -O2 -g" \
+           { pr20253-2a.c pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+       ] \
     ]
 
     run_ld_link_exec_tests [] [list \
@@ -286,5 +307,102 @@ if { [check_ifunc_available] } {
            "pr20244-3b" \
            "pass.out" \
        ] \
+       [list \
+           "Run pr20253-1a" \
+           "tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \
+            tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-1a" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-1b" \
+           "--static tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \
+           tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-1b" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-1c" \
+           "-pie tmpdir/pr20253-1a.o tmpdir/pr20253-1b.o \
+           tmpdir/pr20253-1c.o tmpdir/pr20253-1d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-1c" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-1d" \
+           "tmpdir/pr20253-1a.o tmpdir/libpr20253-1a.so" \
+           "" \
+           { dummy.s } \
+           "pr20253-1d" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-1e" \
+           "-pie tmpdir/pr20253-1a.o tmpdir/libpr20253-1a.so" \
+           "" \
+           { dummy.s } \
+           "pr20253-1e" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-1f" \
+           "tmpdir/pr20253-1a.o" \
+           "" \
+           { pr20253-1b.S pr20253-1c.S pr20253-1d.S } \
+           "pr20253-1f" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
+       [list \
+           "Run pr20253-1g" \
+           "--static tmpdir/pr20253-1a.o" \
+           "" \
+           { pr20253-1b.S pr20253-1c.S pr20253-1d.S } \
+           "pr20253-1g" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
+       [list \
+           "Run pr20253-2a" \
+           "tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \
+            tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-2a" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2b" \
+           "--static tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \
+           tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-2b" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2c" \
+           "tmpdir/pr20253-2a.o" \
+           "" \
+           { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+           "pr20253-2c" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
+       [list \
+           "Run pr20253-2d" \
+           "--static tmpdir/pr20253-2a.o" \
+           "" \
+           { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+           "pr20253-2d" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
     ]
 }
index 35c09ae0de24d0b0820e19f02cec6c97785526b7..9ab4fa59ae33fd87463c7204b1d006ae18a6172e 100644 (file)
@@ -6,7 +6,3 @@
 Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name
 [0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
-
-Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name
-[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
index a04902fb0faedaf254d2666e4402012b7af98ac4..ec3948e5bc04b345acd6916f3150d0cd54262b3f 100644 (file)
@@ -8,36 +8,25 @@
 
 SYMBOL TABLE:
 #...
-0+80480b1 l   i   .text        00000000 bar
+0+8048085 l   i   .text        00000000 bar
 #...
-0+80480b2 g     F .text        00000000 _start
+0+8048086 g     F .text        00000000 _start
 #...
-0+80480b0 g   i   .text        00000000 foo
+0+8048084 g   i   .text        00000000 foo
 #...
 
-
-Disassembly of section .plt:
-
-0+8048090 <.plt>:
- +[a-f0-9]+:   ff 25 e0 90 04 08       jmp    \*0x80490e0
- +[a-f0-9]+:   68 00 00 00 00          push   \$0x0
- +[a-f0-9]+:   e9 00 00 00 00          jmp    80480a0 <foo-0x10>
- +[a-f0-9]+:   ff 25 e4 90 04 08       jmp    \*0x80490e4
- +[a-f0-9]+:   68 00 00 00 00          push   \$0x0
- +[a-f0-9]+:   e9 00 00 00 00          jmp    80480b0 <foo>
-
 Disassembly of section .text:
 
-0+80480b0 <foo>:
+0+8048084 <foo>:
  +[a-f0-9]+:   c3                      ret    
 
-0+80480b1 <bar>:
+0+8048085 <bar>:
  +[a-f0-9]+:   c3                      ret    
 
-0+80480b2 <_start>:
- +[a-f0-9]+:   ff 15 e0 90 04 08       call   \*0x80490e0
- +[a-f0-9]+:   ff 25 e4 90 04 08       jmp    \*0x80490e4
- +[a-f0-9]+:   c7 05 e4 90 04 08 00 00 00 00   movl   \$0x0,0x80490e4
- +[a-f0-9]+:   83 3d e0 90 04 08 00    cmpl   \$0x0,0x80490e0
- +[a-f0-9]+:   b9 10 00 00 00          mov    \$0x10,%ecx
+0+8048086 <_start>:
+ +[a-f0-9]+:   ff 15 a8 90 04 08       call   \*0x80490a8
+ +[a-f0-9]+:   ff 25 ac 90 04 08       jmp    \*0x80490ac
+ +[a-f0-9]+:   c7 05 ac 90 04 08 00 00 00 00   movl   \$0x0,0x80490ac
+ +[a-f0-9]+:   83 3d a8 90 04 08 00    cmpl   \$0x0,0x80490a8
+ +[a-f0-9]+:   b9 fc ff ff ff          mov    \$0xfffffffc,%ecx
 #pass
index fc0fa17ca0777f13f4b0854b4dadbf6c3a2eff98..f23a406553fdaf35c3e57b40490efcbc0c2349c4 100644 (file)
@@ -7,5 +7,4 @@
 .*: +file format .*
 
 Contents of section .got.plt:
- 80490d4 00000000 00000000 00000000 b0800408  ................
- 80490e4 b1800408                             ....            
+ 80490b0 00000000 00000000 00000000           ............    
index 54eee9f9c295b3d27923ab96e7b629de9d038d09..acca56000098e7eaf97c131ef13347e905527ca9 100644 (file)
@@ -6,5 +6,5 @@
 
 Relocation section '.rel.plt' at offset 0x74 contains 2 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name
-0+80490e4  0000002a R_386_IRELATIVE       
-0+80490e0  0000002a R_386_IRELATIVE       
+0+80490ac  0000002a R_386_IRELATIVE       
+0+80490a8  0000002a R_386_IRELATIVE       
diff --git a/ld/testsuite/ld-i386/pr20253-1a.c b/ld/testsuite/ld-i386/pr20253-1a.c
new file mode 100644 (file)
index 0000000..370275a
--- /dev/null
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/pr20253-1b.S b/ld/testsuite/ld-i386/pr20253-1b.S
new file mode 100644 (file)
index 0000000..93c6d26
--- /dev/null
@@ -0,0 +1,52 @@
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "PASS"
+       .text
+       .globl  check
+       .type   check, @function
+check:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       call    *get_func1@GOT(%ebx)
+#ifdef CHECK_PLT
+       cmpl    $func1, %eax
+#else
+       cmpl    func1@GOT(%ebx), %eax
+#endif
+       jne     .L3
+       movl    func1_p@GOT(%ebx), %edx
+       cmpl    %eax, (%edx)
+       jne     .L3
+       call    *func1@GOT(%ebx)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func1@GOT(%ebx)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *get_func2@GOT(%ebx)
+       movl    func2_p@GOT(%ebx), %edx
+       cmpl    %eax, (%edx)
+       jne     .L3
+       call    *call_func2@GOT(%ebx)
+       cmpl    $2, %eax
+       jne     .L3
+       leal    .LC0@GOTOFF(%ebx), %eax
+       subl    $12, %esp
+       pushl   %eax
+       call    *puts@GOT(%ebx)
+       addl    $24, %esp
+       popl    %ebx
+       ret
+.L3:
+       call    *abort@GOT(%ebx)
+       .size   check, .-check
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-1c.S b/ld/testsuite/ld-i386/pr20253-1c.S
new file mode 100644 (file)
index 0000000..8a17e7c
--- /dev/null
@@ -0,0 +1,35 @@
+       .text
+       .globl  get_func1
+       .type   get_func1, @function
+get_func1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       movl    func1@GOT(%eax), %eax
+       ret
+       .size   get_func1, .-get_func1
+       .globl  call_func1
+       .type   call_func1, @function
+call_func1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       jmp     *func1@GOT(%eax)
+       .size   call_func1, .-call_func1
+       .globl  func1_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+       .align 4
+       .type   func1_p, @object
+       .size   func1_p, 4
+func1_p:
+       .long   func1
+       .section        .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+       .globl  __x86.get_pc_thunk.ax
+       .hidden __x86.get_pc_thunk.ax
+       .type   __x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+       movl    (%esp), %eax
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-1d.S b/ld/testsuite/ld-i386/pr20253-1d.S
new file mode 100644 (file)
index 0000000..2d6a1de
--- /dev/null
@@ -0,0 +1,81 @@
+       .text
+       .type   implementation1, @function
+implementation1:
+       movl    $1, %eax
+       ret
+       .size   implementation1, .-implementation1
+       .type   implementation2, @function
+implementation2:
+       movl    $2, %eax
+       ret
+       .size   implementation2, .-implementation2
+       .type   resolver2, @function
+resolver2:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       leal    implementation2@GOTOFF(%eax), %eax
+       ret
+       .size   resolver2, .-resolver2
+       .type   func2, @gnu_indirect_function
+       .set    func2,resolver2
+       .type   resolver1, @function
+resolver1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       leal    implementation1@GOTOFF(%eax), %eax
+       ret
+       .size   resolver1, .-resolver1
+       .globl  func1
+       .type   func1, @gnu_indirect_function
+       .set    func1,resolver1
+       .globl  get_func2
+       .type   get_func2, @function
+get_func2:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       movl    func2@GOT(%eax), %eax
+       ret
+       .size   get_func2, .-get_func2
+       .globl  call_func2
+       .type   call_func2, @function
+call_func2:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       call    *get_func2@GOT(%ebx)
+       cmpl    func2@GOT(%ebx), %eax
+       jne     .L10
+       addl    $8, %esp
+       movl    %ebx, %eax
+       popl    %ebx
+       jmp     *func2@GOT(%eax)
+.L10:
+       call    *abort@GOT(%ebx)
+       .size   call_func2, .-call_func2
+       .globl  func2_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+       .align 4
+       .type   func2_p, @object
+       .size   func2_p, 4
+func2_p:
+       .long   func2
+       .section        .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+       .globl  __x86.get_pc_thunk.ax
+       .hidden __x86.get_pc_thunk.ax
+       .type   __x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+       movl    (%esp), %eax
+       ret
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-2a.c b/ld/testsuite/ld-i386/pr20253-2a.c
new file mode 100644 (file)
index 0000000..370275a
--- /dev/null
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/pr20253-2b.S b/ld/testsuite/ld-i386/pr20253-2b.S
new file mode 100644 (file)
index 0000000..46ab4f4
--- /dev/null
@@ -0,0 +1,39 @@
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "PASS"
+       .text
+       .globl  check
+       .type   check, @function
+check:
+       subl    $12, %esp
+       call    *get_func1@GOT
+#ifdef CHECK_PLT
+       movl    $func1, %edx
+#else
+       movl    func1@GOT, %edx
+#endif
+       cmpl    %edx, %eax
+       jne     .L3
+       cmpl    %edx, func1_p
+       jne     .L3
+       call    *func1@GOT
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func1@GOT
+       cmpl    $1, %eax
+       jne     .L3
+       call    *get_func2@GOT
+       cmpl    %eax, func2_p
+       jne     .L3
+       call    *call_func2@GOT
+       cmpl    $2, %eax
+       jne     .L3
+       subl    $12, %esp
+       pushl   $.LC0
+       call    *puts@GOT
+       addl    $28, %esp
+       ret
+.L3:
+       call    *abort@GOT
+       .size   check, .-check
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-2c.S b/ld/testsuite/ld-i386/pr20253-2c.S
new file mode 100644 (file)
index 0000000..7e724b4
--- /dev/null
@@ -0,0 +1,24 @@
+       .text
+       .globl  get_func1
+       .type   get_func1, @function
+get_func1:
+       movl    func1@GOT, %eax
+       ret
+       .size   get_func1, .-get_func1
+       .globl  call_func1
+       .type   call_func1, @function
+call_func1:
+       jmp     *func1@GOT
+       .size   call_func1, .-call_func1
+       .globl  func1_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+       .align 4
+       .type   func1_p, @object
+       .size   func1_p, 4
+func1_p:
+       .long   func1
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-2d.S b/ld/testsuite/ld-i386/pr20253-2d.S
new file mode 100644 (file)
index 0000000..5c1f9ae
--- /dev/null
@@ -0,0 +1,49 @@
+       .text
+       .type   implementation1, @function
+implementation1:
+       movl    $1, %eax
+       ret
+       .size   implementation1, .-implementation1
+       .type   implementation2, @function
+implementation2:
+       movl    $2, %eax
+       ret
+       .size   implementation2, .-implementation2
+       .type   resolver2, @function
+resolver2:
+       movl    $implementation2, %eax
+       ret
+       .size   resolver2, .-resolver2
+       .type   func2, @gnu_indirect_function
+       .set    func2,resolver2
+       .type   resolver1, @function
+resolver1:
+       movl    $implementation1, %eax
+       ret
+       .size   resolver1, .-resolver1
+       .globl  func1
+       .type   func1, @gnu_indirect_function
+       .set    func1,resolver1
+       .globl  get_func2
+       .type   get_func2, @function
+get_func2:
+       movl    func2@GOT, %eax
+       ret
+       .size   get_func2, .-get_func2
+       .globl  call_func2
+       .type   call_func2, @function
+call_func2:
+       jmp     *func2@GOT
+       .size   call_func2, .-call_func2
+       .globl  func2_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+       .align 4
+       .type   func2_p, @object
+       .size   func2_p, 4
+func2_p:
+       .long   func2
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20253-3.d b/ld/testsuite/ld-i386/pr20253-3.d
new file mode 100644 (file)
index 0000000..7ce0b58
--- /dev/null
@@ -0,0 +1,3 @@
+#as: --32
+#ld: -melf_i386
+#error: relocation R_386_PC32 against STT_GNU_IFUNC symbol `foo' isn't supported
diff --git a/ld/testsuite/ld-i386/pr20253-3.s b/ld/testsuite/ld-i386/pr20253-3.s
new file mode 100644 (file)
index 0000000..8cd25fb
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       ret
+       .globl __start
+__start:
+       .data
+       .long foo - .
diff --git a/ld/testsuite/ld-i386/pr20253-4.s b/ld/testsuite/ld-i386/pr20253-4.s
new file mode 100644 (file)
index 0000000..88f0f1b
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       movl    __start@GOT(%eax), %eax
+       .globl __start
+__start:
+       .data
+       .dc.a foo
diff --git a/ld/testsuite/ld-i386/pr20253-4a.d b/ld/testsuite/ld-i386/pr20253-4a.d
new file mode 100644 (file)
index 0000000..cd10080
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr20253-4b.d b/ld/testsuite/ld-i386/pr20253-4b.d
new file mode 100644 (file)
index 0000000..3b45f8f
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --32 -mrelax-relocations=yes
+#ld: -pie -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr20253-4c.d b/ld/testsuite/ld-i386/pr20253-4c.d
new file mode 100644 (file)
index 0000000..6fa68aa
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-4.s
+#as: --32 -mrelax-relocations=yes
+#ld: -shared -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +[0-9a-f]+ +__start
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr20253-5.d b/ld/testsuite/ld-i386/pr20253-5.d
new file mode 100644 (file)
index 0000000..0936d98
--- /dev/null
@@ -0,0 +1,7 @@
+#as: --32
+#ld: -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr20253-5.s b/ld/testsuite/ld-i386/pr20253-5.s
new file mode 100644 (file)
index 0000000..0cc1803
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       .globl  _start
+       .type   _start, @function
+_start:
+       call    *func1@GOT(%eax)
+       cmp     $func1,%eax
+       .globl func1
+       .type   func1, @gnu_indirect_function
+func1:
+       ret
index 677fa9284c3fb2e35a8326317fd8e36a948c8ca7..8dd3fed890fc462c7598d123ed60ea265d7ea0f3 100644 (file)
@@ -8,7 +8,3 @@
 Relocation section '.rel.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_32[ ]+ifunc\(\)[ ]+ifunc
-
-Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
-[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc
index b01c735679578afea910931ba84d71341289de02..1a1d061ac840413f6b9996d848590d6de3c60e85 100644 (file)
@@ -8,7 +8,3 @@
 Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_64[ ]+ifunc\(\)[ ]+ifunc \+ 0
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
-[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
index c37dd51e6639172d6e01268a86c16cc0255563a1..0d44ba1b3a152ad25d372fcf15bd1ded0165731d 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rel.got' at offset 0x[0-9a-f]+ contains 1 entries:
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_GLOB_DAT[ ]+ifunc\(\)[ ]+ifunc
-
-Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
-[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc
index a4a5cb14cf54f079c643abbd64ce42f80083f525..8a28ec9cda8b17d50e9c0f0b9a8353f5761e394d 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rela.got' at offset 0x[0-9a-f]+ contains 1 entries:
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_GLOB_DAT[ ]+ifunc\(\)[ ]+ifunc \+ 0
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
-[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
index 10490b112b7e8c332cadfe37477b11cc5babf82e..7c392fb881ce9c2207c969e5afeceeb96ce19033 100644 (file)
@@ -12,4 +12,3 @@ Relocation section '.rel.ifunc' at .*
 Relocation section '.rel.plt' at .*
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
index 0d600eb382146f75f831c18f5437d4d8376c03e1..e9d603176c7eb547b509a900b25055198cc0779d 100644 (file)
@@ -12,4 +12,3 @@ Relocation section '.rela.ifunc' at .*
 Relocation section '.rela.plt' at .*
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
index c29c121c2355cfc3edf11e6356379ef7506105fe..f68c151ac91b91b76726a25d3b556134d6d5f2ca 100644 (file)
@@ -1,5 +1,5 @@
        .section .data.rel,"aw",@progbits
-       .globl foo_ptrt
+       .globl foo_ptr
        .type   foo_ptr, @object
 foo_ptr:
        .dc.a foo
index a5eda9495a46d8012f7b251375fd359ff17fee4a..4b63c57f57a45463272213e9262dbb1224ed0380 100644 (file)
@@ -12,4 +12,3 @@ Relocation section '.rel.ifunc' at .*
 Relocation section '.rel.plt' at .*
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
index 8dfebfb8e9de8cf9e947592b4ea57ab05be863df..b4ff6c3c41c483dadfdad11bf25a43933539b8a1 100644 (file)
@@ -12,4 +12,3 @@ Relocation section '.rela.ifunc' at .*
 Relocation section '.rela.plt' at .*
 [ ]+Offset[ ]+Info[ ]+Type[ ]+.*
 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
-[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
index e609dbe74afdf0a078234d0119d90be0c1d7ebb4..d61ccd0d9a840f53bcf3d28409d2fcda601b35eb 100644 (file)
@@ -5,18 +5,20 @@
 
 .*: +file format .*
 
-#...
-0+8048090 <__start>:
-[      ]*[a-f0-9]+:    ff 93 0c 00 00 00       call   \*0xc\(%ebx\)
-[      ]*[a-f0-9]+:    ff a3 0c 00 00 00       jmp    \*0xc\(%ebx\)
-[      ]*[a-f0-9]+:    03 83 0c 00 00 00       add    0xc\(%ebx\),%eax
-[      ]*[a-f0-9]+:    8b 83 0c 00 00 00       mov    0xc\(%ebx\),%eax
-[      ]*[a-f0-9]+:    85 83 0c 00 00 00       test   %eax,0xc\(%ebx\)
-[      ]*[a-f0-9]+:    c7 c0 b5 80 04 08       mov    \$0x80480b5,%eax
 
-0+80480b4 <foo>:
-[      ]*[a-f0-9]+:    c3                      ret    
+Disassembly of section .text:
 
-0+80480b5 <bar>:
-[      ]*[a-f0-9]+:    c3                      ret    
+0+804807c <__start>:
+ +[a-f0-9]+:   ff 93 fc ff ff ff       call   \*-0x4\(%ebx\)
+ +[a-f0-9]+:   ff a3 fc ff ff ff       jmp    \*-0x4\(%ebx\)
+ +[a-f0-9]+:   03 83 fc ff ff ff       add    -0x4\(%ebx\),%eax
+ +[a-f0-9]+:   8b 83 fc ff ff ff       mov    -0x4\(%ebx\),%eax
+ +[a-f0-9]+:   85 83 fc ff ff ff       test   %eax,-0x4\(%ebx\)
+ +[a-f0-9]+:   c7 c0 a1 80 04 08       mov    \$0x80480a1,%eax
+
+0+80480a0 <foo>:
+ +[a-f0-9]+:   c3                      ret    
+
+0+80480a1 <bar>:
+ +[a-f0-9]+:   c3                      ret    
 #pass
index e28734e1cfc5aea872b0dd6bb207e5be56fa91aa..4e3582dee966b0166c05d51317a6b1f32f64a3ee 100644 (file)
@@ -5,18 +5,20 @@
 
 .*: +file format .*
 
-#...
-0+4000e0 <__start>:
-[      ]*[a-f0-9]+:    ff 15 42 00 20 00       callq  \*0x200042\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    ff 25 3c 00 20 00       jmpq   \*0x20003c\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 03 05 35 00 20 00    add    0x200035\(%rip\),%rax        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 8b 05 2e 00 20 00    mov    0x20002e\(%rip\),%rax        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 85 05 27 00 20 00    test   %rax,0x200027\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 c7 c0 09 01 40 00    mov    \$0x400109,%rax
 
-0+400108 <foo>:
-[      ]*[a-f0-9]+:    c3                      retq   
+Disassembly of section .text:
 
-0+400109 <bar>:
-[      ]*[a-f0-9]+:    c3                      retq   
+0+4000c8 <__start>:
+ +[a-f0-9]+:   ff 15 2a 00 20 00       callq  \*0x20002a\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   ff 25 24 00 20 00       jmpq   \*0x200024\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 03 05 1d 00 20 00    add    0x20001d\(%rip\),%rax        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 8b 05 16 00 20 00    mov    0x200016\(%rip\),%rax        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 85 05 0f 00 20 00    test   %rax,0x20000f\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 c7 c0 f1 00 40 00    mov    \$0x4000f1,%rax
+
+0+4000f0 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+4000f1 <bar>:
+ +[a-f0-9]+:   c3                      retq   
 #pass
index e609dbe74afdf0a078234d0119d90be0c1d7ebb4..d61ccd0d9a840f53bcf3d28409d2fcda601b35eb 100644 (file)
@@ -5,18 +5,20 @@
 
 .*: +file format .*
 
-#...
-0+8048090 <__start>:
-[      ]*[a-f0-9]+:    ff 93 0c 00 00 00       call   \*0xc\(%ebx\)
-[      ]*[a-f0-9]+:    ff a3 0c 00 00 00       jmp    \*0xc\(%ebx\)
-[      ]*[a-f0-9]+:    03 83 0c 00 00 00       add    0xc\(%ebx\),%eax
-[      ]*[a-f0-9]+:    8b 83 0c 00 00 00       mov    0xc\(%ebx\),%eax
-[      ]*[a-f0-9]+:    85 83 0c 00 00 00       test   %eax,0xc\(%ebx\)
-[      ]*[a-f0-9]+:    c7 c0 b5 80 04 08       mov    \$0x80480b5,%eax
 
-0+80480b4 <foo>:
-[      ]*[a-f0-9]+:    c3                      ret    
+Disassembly of section .text:
 
-0+80480b5 <bar>:
-[      ]*[a-f0-9]+:    c3                      ret    
+0+804807c <__start>:
+ +[a-f0-9]+:   ff 93 fc ff ff ff       call   \*-0x4\(%ebx\)
+ +[a-f0-9]+:   ff a3 fc ff ff ff       jmp    \*-0x4\(%ebx\)
+ +[a-f0-9]+:   03 83 fc ff ff ff       add    -0x4\(%ebx\),%eax
+ +[a-f0-9]+:   8b 83 fc ff ff ff       mov    -0x4\(%ebx\),%eax
+ +[a-f0-9]+:   85 83 fc ff ff ff       test   %eax,-0x4\(%ebx\)
+ +[a-f0-9]+:   c7 c0 a1 80 04 08       mov    \$0x80480a1,%eax
+
+0+80480a0 <foo>:
+ +[a-f0-9]+:   c3                      ret    
+
+0+80480a1 <bar>:
+ +[a-f0-9]+:   c3                      ret    
 #pass
index e28734e1cfc5aea872b0dd6bb207e5be56fa91aa..4e3582dee966b0166c05d51317a6b1f32f64a3ee 100644 (file)
@@ -5,18 +5,20 @@
 
 .*: +file format .*
 
-#...
-0+4000e0 <__start>:
-[      ]*[a-f0-9]+:    ff 15 42 00 20 00       callq  \*0x200042\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    ff 25 3c 00 20 00       jmpq   \*0x20003c\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 03 05 35 00 20 00    add    0x200035\(%rip\),%rax        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 8b 05 2e 00 20 00    mov    0x20002e\(%rip\),%rax        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 85 05 27 00 20 00    test   %rax,0x200027\(%rip\)        # 600128 <_GLOBAL_OFFSET_TABLE_\+0x18>
-[      ]*[a-f0-9]+:    48 c7 c0 09 01 40 00    mov    \$0x400109,%rax
 
-0+400108 <foo>:
-[      ]*[a-f0-9]+:    c3                      retq   
+Disassembly of section .text:
 
-0+400109 <bar>:
-[      ]*[a-f0-9]+:    c3                      retq   
+0+4000c8 <__start>:
+ +[a-f0-9]+:   ff 15 2a 00 20 00       callq  \*0x20002a\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   ff 25 24 00 20 00       jmpq   \*0x200024\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 03 05 1d 00 20 00    add    0x20001d\(%rip\),%rax        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 8b 05 16 00 20 00    mov    0x200016\(%rip\),%rax        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 85 05 0f 00 20 00    test   %rax,0x20000f\(%rip\)        # 6000f8 <bar\+0x200007>
+ +[a-f0-9]+:   48 c7 c0 f1 00 40 00    mov    \$0x4000f1,%rax
+
+0+4000f0 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+4000f1 <bar>:
+ +[a-f0-9]+:   c3                      retq   
 #pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-23-x86.s b/ld/testsuite/ld-ifunc/ifunc-23-x86.s
new file mode 100644 (file)
index 0000000..69c2279
--- /dev/null
@@ -0,0 +1,10 @@
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       ret
+       .globl __start
+__start:
+       .data
+       .dc.a foo
diff --git a/ld/testsuite/ld-ifunc/ifunc-23a-x86.d b/ld/testsuite/ld-ifunc/ifunc-23a-x86.d
new file mode 100644 (file)
index 0000000..47ec5d1
--- /dev/null
@@ -0,0 +1,8 @@
+#source: ifunc-23-x86.s
+#ld:
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-23b-x86.d b/ld/testsuite/ld-ifunc/ifunc-23b-x86.d
new file mode 100644 (file)
index 0000000..dbe2ec1
--- /dev/null
@@ -0,0 +1,8 @@
+#source: ifunc-23-x86.s
+#ld: -pie
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-23c-x86.d b/ld/testsuite/ld-ifunc/ifunc-23c-x86.d
new file mode 100644 (file)
index 0000000..dc7e5c1
--- /dev/null
@@ -0,0 +1,8 @@
+#source: ifunc-23-x86.s
+#ld: -shared
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-24-x86.s b/ld/testsuite/ld-ifunc/ifunc-24-x86.s
new file mode 100644 (file)
index 0000000..967cdf6
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       call    foo@PLT
+       .globl __start
+__start:
+       .data
+       .dc.a foo
diff --git a/ld/testsuite/ld-ifunc/ifunc-24a-x86.d b/ld/testsuite/ld-ifunc/ifunc-24a-x86.d
new file mode 100644 (file)
index 0000000..78bd4e2
--- /dev/null
@@ -0,0 +1,8 @@
+#source: ifunc-24-x86.s
+#ld:
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-24b-x86.d b/ld/testsuite/ld-ifunc/ifunc-24b-x86.d
new file mode 100644 (file)
index 0000000..c73b019
--- /dev/null
@@ -0,0 +1,12 @@
+#source: ifunc-24-x86.s
+#ld: -pie
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-24c-x86.d b/ld/testsuite/ld-ifunc/ifunc-24c-x86.d
new file mode 100644 (file)
index 0000000..db16754
--- /dev/null
@@ -0,0 +1,12 @@
+#source: ifunc-24-x86.s
+#ld: -shared
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-25-x86.s b/ld/testsuite/ld-ifunc/ifunc-25-x86.s
new file mode 100644 (file)
index 0000000..0549cbf
--- /dev/null
@@ -0,0 +1,12 @@
+       .text
+       .globl foo
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       call    foo@PLT
+       .globl __start
+__start:
+       .data
+       .dc.a foo
diff --git a/ld/testsuite/ld-ifunc/ifunc-25a-x86.d b/ld/testsuite/ld-ifunc/ifunc-25a-x86.d
new file mode 100644 (file)
index 0000000..0f37f52
--- /dev/null
@@ -0,0 +1,8 @@
+#source: ifunc-25-x86.s
+#ld:
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-25b-x86.d b/ld/testsuite/ld-ifunc/ifunc-25b-x86.d
new file mode 100644 (file)
index 0000000..96b0ed5
--- /dev/null
@@ -0,0 +1,12 @@
+#source: ifunc-25-x86.s
+#ld: -pie
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)+_IRELATIVE[ ]*[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-25c-x86.d b/ld/testsuite/ld-ifunc/ifunc-25c-x86.d
new file mode 100644 (file)
index 0000000..f9c08dc
--- /dev/null
@@ -0,0 +1,12 @@
+#source: ifunc-25-x86.s
+#ld: -shared
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel(a|).dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)_(32|64) +foo\(\) +foo( \+ 0|)
+
+Relocation section '.rel(a|).plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_(386|X86_64)_JUMP_SLOT +foo\(\) +foo( \+ 0|)
index d57ccb51ce2fa43d741fb282e536cb279e988ea5..bdf1843d52ff493f7b170a0e404ab7a374b63eed 100644 (file)
@@ -199,3 +199,88 @@ run_ld_link_exec_tests [] [list \
        "pass.out" \
     ] \
 ]
+
+# Run-time tests which require working IFUNC support.
+if { [check_ifunc_available] } {
+    run_cc_link_tests [list \
+       [list \
+           "Build pr20253-2a.o pr20253-2b.o pr20253-2c.o pr20253-2d.o" \
+           "" \
+           "-fPIE -O2 -g" \
+           { pr20253-2a.c pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+       ] \
+       [list \
+           "Build libpr20253-2a.so" \
+           "-shared tmpdir/pr20253-2b.o \
+            tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           {} \
+           "libpr20253-2a.so" \
+       ] \
+    ]
+
+    run_ld_link_exec_tests [] [list \
+       [list \
+           "Run pr20253-2a" \
+           "tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \
+            tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-2a" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2b" \
+           "--static tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \
+           tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-2b" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2c" \
+           "-pie tmpdir/pr20253-2a.o tmpdir/pr20253-2b.o \
+           tmpdir/pr20253-2c.o tmpdir/pr20253-2d.o" \
+           "" \
+           { dummy.s } \
+           "pr20253-2c" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2d" \
+           "tmpdir/pr20253-2a.o tmpdir/libpr20253-2a.so" \
+           "" \
+           { dummy.s } \
+           "pr20253-2d" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2e" \
+           "-pie tmpdir/pr20253-2a.o tmpdir/libpr20253-2a.so" \
+           "" \
+           { dummy.s } \
+           "pr20253-2e" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run pr20253-2f" \
+           "tmpdir/pr20253-2a.o" \
+           "" \
+           { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+           "pr20253-2f" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
+       [list \
+           "Run pr20253-2g" \
+           "--static tmpdir/pr20253-2a.o" \
+           "" \
+           { pr20253-2b.S pr20253-2c.S pr20253-2d.S } \
+           "pr20253-2g" \
+           "pass.out" \
+           "-DCHECK_PLT" \
+       ] \
+    ]
+}
index 191c29e9af72a0ab6da5408cfff955878aabe08f..d1b100d3b9799c7eeddf40ab7448d58ca98ca49d 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ifunc\(\)+ +ifunc \+ 0
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +ifunc\(\)+ +ifunc \+ 0
index 1c5a5e79b536b97da25444e98f4e0e394d6eecab..01e403bbf5be4d354635b81818f35cd7e020659e 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
index 9a1a6551853fcff556283701c3e2bb7f9a3353b0..5914f3d50e7b351e74c43bf46c439f8890c833ae 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
index 792c3483eba3406a71fb2ecaa253fc70375fc206..6ff23ffcc56bafb8ab73687f91625fa70445cd4e 100644 (file)
@@ -7,7 +7,3 @@
 Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
  Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
-
-Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1.s b/ld/testsuite/ld-x86-64/pr20253-1.s
new file mode 100644 (file)
index 0000000..4b9b7a4
--- /dev/null
@@ -0,0 +1,18 @@
+       .text
+       .globl  foo
+       .type   foo, @gnu_indirect_function
+foo:
+       ret
+       .text
+       .type   bar, @gnu_indirect_function
+bar:
+       ret
+       .globl  _start
+       .type   _start, @function
+_start:
+       call    *foo@GOTPCREL(%rip)
+       jmp     *bar@GOTPCREL(%rip)
+       movq    $0, bar@GOTPCREL(%rip)
+       cmpq    $0, foo@GOTPCREL(%rip)
+       cmpq    foo@GOTPCREL(%rip), %rcx
+       cmpq    bar@GOTPCREL(%rip), %rcx
diff --git a/ld/testsuite/ld-x86-64/pr20253-1a.d b/ld/testsuite/ld-x86-64/pr20253-1a.d
new file mode 100644 (file)
index 0000000..94c7c1d
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1b.d b/ld/testsuite/ld-x86-64/pr20253-1b.d
new file mode 100644 (file)
index 0000000..247e042
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -melf_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+4000e0 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+4000e1 <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+4000e2 <_start>:
+ +[a-f0-9]+:   ff 15 28 00 20 00       callq  \*0x200028\(%rip\)        # 600110 <_start\+0x20002e>
+ +[a-f0-9]+:   ff 25 2a 00 20 00       jmpq   \*0x20002a\(%rip\)        # 600118 <_start\+0x200036>
+ +[a-f0-9]+:   48 c7 05 1f 00 20 00 00 00 00 00        movq   \$0x0,0x20001f\(%rip\)        # 600118 <_start\+0x200036>
+ +[a-f0-9]+:   48 83 3d 0f 00 20 00 00         cmpq   \$0x0,0x20000f\(%rip\)        # 600110 <_start\+0x20002e>
+ +[a-f0-9]+:   48 3b 0d 08 00 20 00    cmp    0x200008\(%rip\),%rcx        # 600110 <_start\+0x20002e>
+ +[a-f0-9]+:   48 3b 0d 09 00 20 00    cmp    0x200009\(%rip\),%rcx        # 600118 <_start\+0x200036>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-1c.d b/ld/testsuite/ld-x86-64/pr20253-1c.d
new file mode 100644 (file)
index 0000000..02c4542
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -pie -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1d.d b/ld/testsuite/ld-x86-64/pr20253-1d.d
new file mode 100644 (file)
index 0000000..35c04f8
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -pie -melf_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+1c8 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+1c9 <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+1ca <_start>:
+ +[a-f0-9]+:   ff 15 28 01 20 00       callq  \*0x200128\(%rip\)        # 2002f8 <_DYNAMIC\+0x100>
+ +[a-f0-9]+:   ff 25 2a 01 20 00       jmpq   \*0x20012a\(%rip\)        # 200300 <_DYNAMIC\+0x108>
+ +[a-f0-9]+:   48 c7 05 1f 01 20 00 00 00 00 00        movq   \$0x0,0x20011f\(%rip\)        # 200300 <_DYNAMIC\+0x108>
+ +[a-f0-9]+:   48 83 3d 0f 01 20 00 00         cmpq   \$0x0,0x20010f\(%rip\)        # 2002f8 <_DYNAMIC\+0x100>
+ +[a-f0-9]+:   48 3b 0d 08 01 20 00    cmp    0x200108\(%rip\),%rcx        # 2002f8 <_DYNAMIC\+0x100>
+ +[a-f0-9]+:   48 3b 0d 09 01 20 00    cmp    0x200109\(%rip\),%rcx        # 200300 <_DYNAMIC\+0x108>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-1e.d b/ld/testsuite/ld-x86-64/pr20253-1e.d
new file mode 100644 (file)
index 0000000..722fdf7
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +foo\(\)+ +foo \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1f.d b/ld/testsuite/ld-x86-64/pr20253-1f.d
new file mode 100644 (file)
index 0000000..d84b60e
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+1f8 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+1f9 <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+1fa <_start>:
+ +[a-f0-9]+:   ff 15 08 01 20 00       callq  \*0x200108\(%rip\)        # 200308 <_DYNAMIC\+0xe0>
+ +[a-f0-9]+:   ff 25 0a 01 20 00       jmpq   \*0x20010a\(%rip\)        # 200310 <_DYNAMIC\+0xe8>
+ +[a-f0-9]+:   48 c7 05 ff 00 20 00 00 00 00 00        movq   \$0x0,0x2000ff\(%rip\)        # 200310 <_DYNAMIC\+0xe8>
+ +[a-f0-9]+:   48 83 3d ef 00 20 00 00         cmpq   \$0x0,0x2000ef\(%rip\)        # 200308 <_DYNAMIC\+0xe0>
+ +[a-f0-9]+:   48 3b 0d e8 00 20 00    cmp    0x2000e8\(%rip\),%rcx        # 200308 <_DYNAMIC\+0xe0>
+ +[a-f0-9]+:   48 3b 0d e9 00 20 00    cmp    0x2000e9\(%rip\),%rcx        # 200310 <_DYNAMIC\+0xe8>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-1g.d b/ld/testsuite/ld-x86-64/pr20253-1g.d
new file mode 100644 (file)
index 0000000..671a980
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1h.d b/ld/testsuite/ld-x86-64/pr20253-1h.d
new file mode 100644 (file)
index 0000000..77ff100
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -melf32_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+40008c <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+40008d <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+40008e <_start>:
+ +[a-f0-9]+:   ff 15 28 00 20 00       callq  \*0x200028\(%rip\)        # 6000bc <_start\+0x20002e>
+ +[a-f0-9]+:   ff 25 2a 00 20 00       jmpq   \*0x20002a\(%rip\)        # 6000c4 <_start\+0x200036>
+ +[a-f0-9]+:   48 c7 05 1f 00 20 00 00 00 00 00        movq   \$0x0,0x20001f\(%rip\)        # 6000c4 <_start\+0x200036>
+ +[a-f0-9]+:   48 83 3d 0f 00 20 00 00         cmpq   \$0x0,0x20000f\(%rip\)        # 6000bc <_start\+0x20002e>
+ +[a-f0-9]+:   48 3b 0d 08 00 20 00    cmp    0x200008\(%rip\),%rcx        # 6000bc <_start\+0x20002e>
+ +[a-f0-9]+:   48 3b 0d 09 00 20 00    cmp    0x200009\(%rip\),%rcx        # 6000c4 <_start\+0x200036>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-1i.d b/ld/testsuite/ld-x86-64/pr20253-1i.d
new file mode 100644 (file)
index 0000000..bf42ed1
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1j.d b/ld/testsuite/ld-x86-64/pr20253-1j.d
new file mode 100644 (file)
index 0000000..6f5d666
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -pie -melf32_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+120 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+121 <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+122 <_start>:
+ +[a-f0-9]+:   ff 15 a8 00 20 00       callq  \*0x2000a8\(%rip\)        # 2001d0 <_DYNAMIC\+0x80>
+ +[a-f0-9]+:   ff 25 aa 00 20 00       jmpq   \*0x2000aa\(%rip\)        # 2001d8 <_DYNAMIC\+0x88>
+ +[a-f0-9]+:   48 c7 05 9f 00 20 00 00 00 00 00        movq   \$0x0,0x20009f\(%rip\)        # 2001d8 <_DYNAMIC\+0x88>
+ +[a-f0-9]+:   48 83 3d 8f 00 20 00 00         cmpq   \$0x0,0x20008f\(%rip\)        # 2001d0 <_DYNAMIC\+0x80>
+ +[a-f0-9]+:   48 3b 0d 88 00 20 00    cmp    0x200088\(%rip\),%rcx        # 2001d0 <_DYNAMIC\+0x80>
+ +[a-f0-9]+:   48 3b 0d 89 00 20 00    cmp    0x200089\(%rip\),%rcx        # 2001d8 <_DYNAMIC\+0x88>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-1k.d b/ld/testsuite/ld-x86-64/pr20253-1k.d
new file mode 100644 (file)
index 0000000..1d55770
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +foo\(\)+ +foo \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-1l.d b/ld/testsuite/ld-x86-64/pr20253-1l.d
new file mode 100644 (file)
index 0000000..0276558
--- /dev/null
@@ -0,0 +1,25 @@
+#source: pr20253-1.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#objdump: -dw
+#notarget: x86_64-*-nacl*
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+158 <foo>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+159 <bar>:
+ +[a-f0-9]+:   c3                      retq   
+
+0+15a <_start>:
+ +[a-f0-9]+:   ff 15 98 00 20 00       callq  \*0x200098\(%rip\)        # 2001f8 <_DYNAMIC\+0x70>
+ +[a-f0-9]+:   ff 25 9a 00 20 00       jmpq   \*0x20009a\(%rip\)        # 200200 <_DYNAMIC\+0x78>
+ +[a-f0-9]+:   48 c7 05 8f 00 20 00 00 00 00 00        movq   \$0x0,0x20008f\(%rip\)        # 200200 <_DYNAMIC\+0x78>
+ +[a-f0-9]+:   48 83 3d 7f 00 20 00 00         cmpq   \$0x0,0x20007f\(%rip\)        # 2001f8 <_DYNAMIC\+0x70>
+ +[a-f0-9]+:   48 3b 0d 78 00 20 00    cmp    0x200078\(%rip\),%rcx        # 2001f8 <_DYNAMIC\+0x70>
+ +[a-f0-9]+:   48 3b 0d 79 00 20 00    cmp    0x200079\(%rip\),%rcx        # 200200 <_DYNAMIC\+0x78>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20253-2a.c b/ld/testsuite/ld-x86-64/pr20253-2a.c
new file mode 100644 (file)
index 0000000..370275a
--- /dev/null
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/pr20253-2b.S b/ld/testsuite/ld-x86-64/pr20253-2b.S
new file mode 100644 (file)
index 0000000..9bfab0c
--- /dev/null
@@ -0,0 +1,46 @@
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "PASS"
+       .text
+       .globl  check
+       .type   check, @function
+check:
+       subq    $8, %rsp
+       call    *get_func1@GOTPCREL(%rip)
+#ifdef CHECK_PLT
+       cmpl    $func1, %eax
+#else
+       cmpq    func1@GOTPCREL(%rip), %rax
+#endif
+       jne     .L3
+       movq    func1_p@GOTPCREL(%rip), %rdx
+#ifdef __LP64__
+       cmpq    %rax, (%rdx)
+#else
+       cmpl    %eax, (%rdx)
+#endif
+       jne     .L3
+       call    *func1@GOTPCREL(%rip)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func1@GOTPCREL(%rip)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *get_func2@GOTPCREL(%rip)
+       movq    func2_p@GOTPCREL(%rip), %rdx
+#ifdef __LP64__
+       cmpq    %rax, (%rdx)
+#else
+       cmpl    %eax, (%rdx)
+#endif
+       jne     .L3
+       call    *call_func2@GOTPCREL(%rip)
+       cmpl    $2, %eax
+       jne     .L3
+       leaq    .LC0(%rip), %rdi
+       addq    $8, %rsp
+       jmp     *puts@GOTPCREL(%rip)
+.L3:
+       call    *abort@GOTPCREL(%rip)
+       .size   check, .-check
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr20253-2c.S b/ld/testsuite/ld-x86-64/pr20253-2c.S
new file mode 100644 (file)
index 0000000..5ec7e76
--- /dev/null
@@ -0,0 +1,29 @@
+       .text
+       .globl  get_func1
+       .type   get_func1, @function
+get_func1:
+       movq    func1@GOTPCREL(%rip), %rax
+       ret
+       .size   get_func1, .-get_func1
+       .globl  call_func1
+       .type   call_func1, @function
+call_func1:
+       jmp     *func1@GOTPCREL(%rip)
+       .size   call_func1, .-call_func1
+       .globl  func1_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+#ifdef __LP64__
+       .align 8
+       .size   func1_p, 8
+#else
+       .align 4
+       .size   func1_p, 4
+#endif
+       .type   func1_p, @object
+func1_p:
+       .dc.a   func1
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr20253-2d.S b/ld/testsuite/ld-x86-64/pr20253-2d.S
new file mode 100644 (file)
index 0000000..bc4c32e
--- /dev/null
@@ -0,0 +1,61 @@
+       .text
+       .type   implementation1, @function
+implementation1:
+       movl    $1, %eax
+       ret
+       .size   implementation1, .-implementation1
+       .type   implementation2, @function
+implementation2:
+       movl    $2, %eax
+       ret
+       .size   implementation2, .-implementation2
+       .type   resolver2, @function
+resolver2:
+       leaq    implementation2(%rip), %rax
+       ret
+       .size   resolver2, .-resolver2
+       .type   func2, @gnu_indirect_function
+       .set    func2,resolver2
+       .type   resolver1, @function
+resolver1:
+       leaq    implementation1(%rip), %rax
+       ret
+       .size   resolver1, .-resolver1
+       .globl  func1
+       .type   func1, @gnu_indirect_function
+       .set    func1,resolver1
+       .globl  get_func2
+       .type   get_func2, @function
+get_func2:
+       movq    func2@GOTPCREL(%rip), %rax
+       ret
+       .size   get_func2, .-get_func2
+       .globl  call_func2
+       .type   call_func2, @function
+call_func2:
+       subq    $8, %rsp
+       call    *get_func2@GOTPCREL(%rip)
+       cmpq    func2@GOTPCREL(%rip), %rax
+       jne     .L10
+       addq    $8, %rsp
+       jmp     *func2@GOTPCREL(%rip)
+.L10:
+       call    *abort@GOTPCREL(%rip)
+       .size   call_func2, .-call_func2
+       .globl  func2_p
+#ifdef CHECK_PLT
+       .section        .rodata,"a",@progbits
+#else
+       .section        .data.rel,"aw",@progbits
+#endif
+#ifdef __LP64__
+       .align 8
+       .size   func2_p, 8
+#else
+       .align 4
+       .size   func2_p, 4
+#endif
+       .type   func2_p, @object
+func2_p:
+       .dc.a   func2
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr20253-3.d b/ld/testsuite/ld-x86-64/pr20253-3.d
new file mode 100644 (file)
index 0000000..30db29c
--- /dev/null
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -melf_x86_64
+#error: relocation R_X86_64_PC32 against STT_GNU_IFUNC symbol `foo' isn't supported
diff --git a/ld/testsuite/ld-x86-64/pr20253-3.s b/ld/testsuite/ld-x86-64/pr20253-3.s
new file mode 100644 (file)
index 0000000..8cd25fb
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       ret
+       .globl __start
+__start:
+       .data
+       .long foo - .
diff --git a/ld/testsuite/ld-x86-64/pr20253-4.s b/ld/testsuite/ld-x86-64/pr20253-4.s
new file mode 100644 (file)
index 0000000..7dc9aa3
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .type foo,%gnu_indirect_function
+foo:
+       ret
+       .globl _start
+_start:
+       movq    __start@GOTPCREL(%rip), %rax
+       .globl __start
+__start:
+       .data
+       .dc.a foo
diff --git a/ld/testsuite/ld-x86-64/pr20253-4a.d b/ld/testsuite/ld-x86-64/pr20253-4a.d
new file mode 100644 (file)
index 0000000..041c164
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --64
+#ld: -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-4b.d b/ld/testsuite/ld-x86-64/pr20253-4b.d
new file mode 100644 (file)
index 0000000..6dc95b5
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --64
+#ld: -pie -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-4c.d b/ld/testsuite/ld-x86-64/pr20253-4c.d
new file mode 100644 (file)
index 0000000..26fa0df
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-4.s
+#as: --64
+#ld: -shared -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +__start \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-4d.d b/ld/testsuite/ld-x86-64/pr20253-4d.d
new file mode 100644 (file)
index 0000000..52dd877
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --x32
+#ld: -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-4e.d b/ld/testsuite/ld-x86-64/pr20253-4e.d
new file mode 100644 (file)
index 0000000..d9f2fa4
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-4.s
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-4f.d b/ld/testsuite/ld-x86-64/pr20253-4f.d
new file mode 100644 (file)
index 0000000..fb3d6f8
--- /dev/null
@@ -0,0 +1,9 @@
+#source: pr20253-4.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +__start \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-5.s b/ld/testsuite/ld-x86-64/pr20253-5.s
new file mode 100644 (file)
index 0000000..ade0e8b
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       .globl  _start
+       .type   _start, @function
+_start:
+       call    *func1@GOTPCREL(%rip)
+       cmp     $func1,%eax
+       .globl func1
+       .type   func1, @gnu_indirect_function
+func1:
+       ret
diff --git a/ld/testsuite/ld-x86-64/pr20253-5a.d b/ld/testsuite/ld-x86-64/pr20253-5a.d
new file mode 100644 (file)
index 0000000..1eceda4
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-5.s
+#as: --64
+#ld: -melf_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr20253-5b.d b/ld/testsuite/ld-x86-64/pr20253-5b.d
new file mode 100644 (file)
index 0000000..c1cb335
--- /dev/null
@@ -0,0 +1,8 @@
+#source: pr20253-5.s
+#as: --x32
+#ld: -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
index 7fd953b8b789bda8540d649d9b2f56ca005061ef..f6f89e2aadb76cb3a3e446ed8b263bc44d8cf31b 100644 (file)
@@ -503,6 +503,27 @@ run_dump_test "pr19609-7d"
 run_dump_test "pr19939a"
 run_dump_test "pr19939b"
 run_dump_test "pr19719"
+run_dump_test "pr20253-1a"
+run_dump_test "pr20253-1b"
+run_dump_test "pr20253-1c"
+run_dump_test "pr20253-1d"
+run_dump_test "pr20253-1e"
+run_dump_test "pr20253-1f"
+run_dump_test "pr20253-1g"
+run_dump_test "pr20253-1h"
+run_dump_test "pr20253-1i"
+run_dump_test "pr20253-1j"
+run_dump_test "pr20253-1k"
+run_dump_test "pr20253-1l"
+run_dump_test "pr20253-3"
+run_dump_test "pr20253-4a"
+run_dump_test "pr20253-4b"
+run_dump_test "pr20253-4c"
+run_dump_test "pr20253-4d"
+run_dump_test "pr20253-4e"
+run_dump_test "pr20253-4f"
+run_dump_test "pr20253-5a"
+run_dump_test "pr20253-5b"
 
 proc undefined_weak {cflags ldflags} {
     set testname "Undefined weak symbol"