Don't generate PLT for IFUNC GOT/pointer reference

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.
This commit is contained in:
H.J. Lu 2016-06-18 09:16:52 -07:00
parent 854594f5ce
commit 233cc9c13a
89 changed files with 1923 additions and 389 deletions

View 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>

View 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 *));

View 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;
/* 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 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)
/* 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;

View 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

View 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,125 +4249,11 @@ elf_x86_64_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)
{
if (htab->plt_bnd != NULL)
{
resolved_plt = htab->plt_bnd;
plt_offset = eh->plt_bnd.offset;
}
else
{
resolved_plt = htab->elf.splt;
plt_offset = h->plt.offset;
}
}
else
{
resolved_plt = htab->elf.iplt;
plt_offset = h->plt.offset;
}
relocation = (resolved_plt->output_section->vma
+ resolved_plt->output_offset + 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,
howto->name, name, __FUNCTION__);
bfd_set_error (bfd_error_bad_value);
return FALSE;
case R_X86_64_32S:
if (bfd_link_pic (info))
abort ();
goto do_relocation;
case R_X86_64_32:
if (ABI_64_P (output_bfd))
goto do_relocation;
/* FALLTHROUGH */
case R_X86_64_64:
if (rel->r_addend != 0)
{
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' has non-zero addend: %d"),
input_bfd, howto->name, name, rel->r_addend);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* 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;
/* Need a dynamic relocation to get the real function
address. */
outrel.r_offset = _bfd_elf_section_offset (output_bfd,
info,
input_section,
rel->r_offset);
if (outrel.r_offset == (bfd_vma) -1
|| outrel.r_offset == (bfd_vma) -2)
abort ();
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
if (h->dynindx == -1
|| h->forced_local
|| bfd_link_executable (info))
{
/* This symbol is resolved locally. */
outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
outrel.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else
{
outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = 0;
}
sreloc = htab->elf.irelifunc;
elf_append_rela (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_X86_64_PC32:
case R_X86_64_PC32_BND:
case R_X86_64_PC64:
case R_X86_64_PLT32:
case R_X86_64_PLT32_BND:
goto do_relocation;
break;
case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCRELX:
@ -4369,6 +4271,9 @@ elf_x86_64_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;
@ -4413,6 +4318,146 @@ elf_x86_64_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 == 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)
{
if (htab->plt_bnd != NULL)
{
resolved_plt = htab->plt_bnd;
plt_offset = eh->plt_bnd.offset;
}
else
{
resolved_plt = htab->elf.splt;
plt_offset = h->plt.offset;
}
}
else
{
resolved_plt = htab->elf.iplt;
plt_offset = h->plt.offset;
}
relocation = (resolved_plt->output_section->vma
+ resolved_plt->output_offset + 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_X86_64_32S:
if (bfd_link_pic (info))
abort ();
goto do_relocation;
case R_X86_64_32:
if (ABI_64_P (output_bfd))
goto do_relocation;
/* FALLTHROUGH */
case R_X86_64_64:
do_ifunc_pointer:
if (rel->r_addend != 0)
{
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' has non-zero addend: %d"),
input_bfd, howto->name, name, rel->r_addend);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* Generate dynamic relcoation only when there is a
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;
/* Need a dynamic relocation to get the real function
address. */
outrel.r_offset = _bfd_elf_section_offset (output_bfd,
info,
input_section,
rel->r_offset);
if (outrel.r_offset == (bfd_vma) -1
|| outrel.r_offset == (bfd_vma) -2)
abort ();
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
if (h->dynindx == -1
|| h->forced_local
|| bfd_link_executable (info))
{
/* This symbol is resolved locally. */
outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
outrel.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else
{
outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = 0;
}
/* 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
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_X86_64_PC32:
case R_X86_64_PC32_BND:
case R_X86_64_PC64:
case R_X86_64_PLT32:
case R_X86_64_PLT32_BND:
goto do_relocation;
}
}
resolved_to_zero = (eh != NULL
@ -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

View 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;
}

View 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>

View 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*"]

View 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" \
] \
]
}

View 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 +

View 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

View File

@ -7,5 +7,4 @@
.*: +file format .*
Contents of section .got.plt:
80490d4 00000000 00000000 00000000 b0800408 ................
80490e4 b1800408 ....
80490b0 00000000 00000000 00000000 ............

View 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

View File

@ -0,0 +1,8 @@
extern void check (void);
int
main ()
{
check ();
return 0;
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,8 @@
extern void check (void);
int
main ()
{
check ();
return 0;
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
#as: --32
#ld: -melf_i386
#error: relocation R_386_PC32 against STT_GNU_IFUNC symbol `foo' isn't supported

View File

@ -0,0 +1,11 @@
.text
.type foo,%gnu_indirect_function
foo:
ret
.globl _start
_start:
ret
.globl __start
__start:
.data
.long foo - .

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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[ ]*

View 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]*

View 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

View 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[ ]*

View 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]*

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,10 @@
.type foo,%gnu_indirect_function
foo:
ret
.globl _start
_start:
ret
.globl __start
__start:
.data
.dc.a foo

View File

@ -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]*

View File

@ -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]*

View File

@ -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]*

View File

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

View File

@ -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]*

View File

@ -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]*

View File

@ -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]*

View File

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

View File

@ -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]*

View File

@ -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]*

View File

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

View 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" \
] \
]
}

View 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

View 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]+

View 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]+

View 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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -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]+

View File

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

View File

@ -0,0 +1,8 @@
extern void check (void);
int
main ()
{
check ();
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,11 @@
.text
.type foo,%gnu_indirect_function
foo:
ret
.globl _start
_start:
ret
.globl __start
__start:
.data
.long foo - .

View File

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

View File

@ -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]+

View File

@ -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]+

View File

@ -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]+

View File

@ -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]+

View File

@ -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]+

View File

@ -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]+

View File

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

View File

@ -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]+

View File

@ -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]+

View 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"