aarch64: Add support for GNU indirect functions.
Add support for STT_GNU_IFUNC symbols to the AArch64 bfd backend. The tests are ported from the ld-ifunc tests but are enabled for cross builds so can be run easily without hardware or a simulator. bfd/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * configure: Regenerate. * configure.in: Build elf-ifunc.o for AArch64. * elfnn-aarch64.c: Include objalloc.h. (elfNN_aarch64_local_htab_hash): New function. (elfNN_aarch64_local_htab_eq): New function. (elfNN_aarch64_get_local_sym_hash): New function. (elfNN_aarch64_link_hash_table_create): Initialize local STT_GNU_IFUNC symbol hash. (elfNN_aarch64_hash_table_free): Free local STT_GNU_IFUNC symbol hash. (elfNN_aarch64_final_link_relocate): Add sym argument. Add support for handling STT_GNU_IFUNC symbols. (elfNN_aarch64_gc_sweep_hook): Add support for garbage collecting references to STT_GNU_IFUNC symbols. (elfNN_aarch64_adjust_dynamic_symbol): Add support for handling STT_GNU_IFUNC symbols. (elfNN_aarch64_check_relocs): Add support for handling STT_GNU_IFUNC symbols. Ensure we don't increase plt.refcount from -1 to 0. (elfNN_aarch64_post_process_headers): Call _bfd_elf_set_osabi. (elfNN_aarch64_is_function_type): Remove function. (elfNN_aarch64_allocate_dynrelocs): Handle STT_GNU_IFUNC symbols. (elfNN_aarch64_allocate_ifunc_dynrelocs): New function. (elfNN_aarch64_allocate_local_dynrelocs): New function. (elfNN_aarch64_allocate_local_ifunc_dynrelocs): New function. (elfNN_aarch64_size_dynamic_sections): Call elfNN_aarch64_allocate_local_dynrelocs. (elfNN_aarch64_create_small_pltn_entry): Add info argument. Add support for creating .iplt entries for STT_GNU_IFUNC symbols. (elfNN_aarch64_finish_dynamic_symbol): Add support for handling STT_GNU_IFUNC symbols and .iplt. (elfNN_aarch64_finish_local_dynamic_symbol): New function. (elfNN_aarch64_finish_dynamic_sections): Call elfNN_aarch64_finish_local_dynamic_symbol. ld/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * emulparams/aarch64elf.sh: Add IREL_IN_PLT. * emulparams/aarch64elf32.sh: Likewise. ld/testsuite/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * ld-ifunc/ifunc.exp: Enable ifunc tests for AArch64. * ld-aarch64/aarch64-elf.exp: Run ifunc tests. * ld-aarch64/ifunc-1-local.d: New file. * ld-aarch64/ifunc-1-local.s: Likewise. * ld-aarch64/ifunc-1.d: Likewise. * ld-aarch64/ifunc-1.s: Likewise. * ld-aarch64/ifunc-10.d: Likewise. * ld-aarch64/ifunc-10.s: Likewise. * ld-aarch64/ifunc-11.d: Likewise. * ld-aarch64/ifunc-11.s: Likewise. * ld-aarch64/ifunc-12.d: Likewise. * ld-aarch64/ifunc-12.s: Likewise. * ld-aarch64/ifunc-13.d: Likewise. * ld-aarch64/ifunc-13a.s: Likewise. * ld-aarch64/ifunc-13b.s: Likewise. * ld-aarch64/ifunc-14a.d: Likewise. * ld-aarch64/ifunc-14a.s: Likewise. * ld-aarch64/ifunc-14b.d: Likewise. * ld-aarch64/ifunc-14b.s: Likewise. * ld-aarch64/ifunc-14c.d: Likewise. * ld-aarch64/ifunc-14c.s: Likewise. * ld-aarch64/ifunc-14d.d: Likewise. * ld-aarch64/ifunc-14e.d: Likewise. * ld-aarch64/ifunc-14f.d: Likewise. * ld-aarch64/ifunc-15.d: Likewise. * ld-aarch64/ifunc-15.s: Likewise. * ld-aarch64/ifunc-16.d: Likewise. * ld-aarch64/ifunc-16.s: Likewise. * ld-aarch64/ifunc-17a.d: Likewise. * ld-aarch64/ifunc-17a.s: Likewise. * ld-aarch64/ifunc-17b.d: Likewise. * ld-aarch64/ifunc-17b.s: Likewise. * ld-aarch64/ifunc-18a.d: Likewise. * ld-aarch64/ifunc-18a.s: Likewise. * ld-aarch64/ifunc-18b.d: Likewise. * ld-aarch64/ifunc-18b.s: Likewise. * ld-aarch64/ifunc-19a.d: Likewise. * ld-aarch64/ifunc-19a.s: Likewise. * ld-aarch64/ifunc-19b.d: Likewise. * ld-aarch64/ifunc-19b.s: Likewise. * ld-aarch64/ifunc-2-local.d: Likewise. * ld-aarch64/ifunc-2-local.s: Likewise. * ld-aarch64/ifunc-2.d: Likewise. * ld-aarch64/ifunc-2.s: Likewise. * ld-aarch64/ifunc-20.d: Likewise. * ld-aarch64/ifunc-20.s: Likewise. * ld-aarch64/ifunc-3.s: Likewise. * ld-aarch64/ifunc-3a.d: Likewise. * ld-aarch64/ifunc-3b.d: Likewise. * ld-aarch64/ifunc-4.d: Likewise. * ld-aarch64/ifunc-4.s: Likewise. * ld-aarch64/ifunc-4a.d: Likewise. * ld-aarch64/ifunc-5-local.s: Likewise. * ld-aarch64/ifunc-5.s: Likewise. * ld-aarch64/ifunc-5a-local.d: Likewise. * ld-aarch64/ifunc-5a.d: Likewise. * ld-aarch64/ifunc-5b-local.d: Likewise. * ld-aarch64/ifunc-5b.d: Likewise. * ld-aarch64/ifunc-5r-local.d: Likewise. * ld-aarch64/ifunc-6.s: Likewise. * ld-aarch64/ifunc-6a.d: Likewise. * ld-aarch64/ifunc-6b.d: Likewise. * ld-aarch64/ifunc-7.s: Likewise. * ld-aarch64/ifunc-7a.d: Likewise. * ld-aarch64/ifunc-7b.d: Likewise. * ld-aarch64/ifunc-7c.d: Likewise. * ld-aarch64/ifunc-8.d: Likewise. * ld-aarch64/ifunc-8a.s: Likewise. * ld-aarch64/ifunc-8b.s: Likewise. * ld-aarch64/ifunc-9.d: Likewise. * ld-aarch64/ifunc-9.s: Likewise.
This commit is contained in:
parent
06ab7b19e0
commit
1419bbe571
78 changed files with 1569 additions and 71 deletions
|
@ -1,3 +1,38 @@
|
|||
2013-10-03 Will Newton <will.newton@linaro.org>
|
||||
|
||||
* configure: Regenerate.
|
||||
* configure.in: Build elf-ifunc.o for AArch64.
|
||||
* elfnn-aarch64.c: Include objalloc.h.
|
||||
(elfNN_aarch64_local_htab_hash): New function.
|
||||
(elfNN_aarch64_local_htab_eq): New function.
|
||||
(elfNN_aarch64_get_local_sym_hash): New function.
|
||||
(elfNN_aarch64_link_hash_table_create): Initialize local STT_GNU_IFUNC
|
||||
symbol hash.
|
||||
(elfNN_aarch64_hash_table_free): Free local STT_GNU_IFUNC symbol hash.
|
||||
(elfNN_aarch64_final_link_relocate): Add sym argument. Add support
|
||||
for handling STT_GNU_IFUNC symbols.
|
||||
(elfNN_aarch64_gc_sweep_hook): Add support for garbage collecting
|
||||
references to STT_GNU_IFUNC symbols.
|
||||
(elfNN_aarch64_adjust_dynamic_symbol): Add support for handling
|
||||
STT_GNU_IFUNC symbols.
|
||||
(elfNN_aarch64_check_relocs): Add support for handling STT_GNU_IFUNC
|
||||
symbols. Ensure we don't increase plt.refcount from -1 to 0.
|
||||
(elfNN_aarch64_post_process_headers): Call _bfd_elf_set_osabi.
|
||||
(elfNN_aarch64_is_function_type): Remove function.
|
||||
(elfNN_aarch64_allocate_dynrelocs): Handle STT_GNU_IFUNC symbols.
|
||||
(elfNN_aarch64_allocate_ifunc_dynrelocs): New function.
|
||||
(elfNN_aarch64_allocate_local_dynrelocs): New function.
|
||||
(elfNN_aarch64_allocate_local_ifunc_dynrelocs): New function.
|
||||
(elfNN_aarch64_size_dynamic_sections): Call
|
||||
elfNN_aarch64_allocate_local_dynrelocs.
|
||||
(elfNN_aarch64_create_small_pltn_entry): Add info argument.
|
||||
Add support for creating .iplt entries for STT_GNU_IFUNC symbols.
|
||||
(elfNN_aarch64_finish_dynamic_symbol): Add support for handling
|
||||
STT_GNU_IFUNC symbols and .iplt.
|
||||
(elfNN_aarch64_finish_local_dynamic_symbol): New function.
|
||||
(elfNN_aarch64_finish_dynamic_sections): Call
|
||||
elfNN_aarch64_finish_local_dynamic_symbol.
|
||||
|
||||
2013-09-30 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* cpu-msp430.c: Use printable names that match the values
|
||||
|
|
|
@ -859,8 +859,8 @@ do
|
|||
bfd_elf32_xtensa_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
|
||||
bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_bigaarch64_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf32_bigaarch64_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf32.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_bigaarch64_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf32_bigaarch64_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_bigmips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
|
||||
bfd_elf64_hppa_linux_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
|
||||
|
@ -869,8 +869,8 @@ do
|
|||
bfd_elf64_ia64_hpux_big_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_ia64_little_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_ia64_vms_vec) tb="$tb elf64-ia64-vms.lo elf64-ia64.lo elfxx-ia64.lo elf64.lo vms-lib.lo vms-misc.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_littleaarch64_vec)tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf32_littleaarch64_vec)tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf32.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_littleaarch64_vec)tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf32_littleaarch64_vec)tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_little_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
|
||||
bfd_elf64_littlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
|
||||
bfd_elf64_mmix_vec) tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
#include "bfd_stdint.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "bfdlink.h"
|
||||
#include "objalloc.h"
|
||||
#include "elf/aarch64.h"
|
||||
#include "elfxx-aarch64.h"
|
||||
|
||||
|
@ -1842,6 +1843,10 @@ struct elf_aarch64_link_hash_table
|
|||
loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
|
||||
indicates an offset is not allocated. */
|
||||
bfd_vma dt_tlsdesc_got;
|
||||
|
||||
/* Used by local STT_GNU_IFUNC symbols. */
|
||||
htab_t loc_hash_table;
|
||||
void * loc_hash_memory;
|
||||
};
|
||||
|
||||
/* Create an entry in an AArch64 ELF linker hash table. */
|
||||
|
@ -1915,6 +1920,72 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
|
|||
return entry;
|
||||
}
|
||||
|
||||
/* Compute a hash of a local hash entry. We use elf_link_hash_entry
|
||||
for local symbol so that we can handle local STT_GNU_IFUNC symbols
|
||||
as global symbol. We reuse indx and dynstr_index for local symbol
|
||||
hash since they aren't used by global symbols in this backend. */
|
||||
|
||||
static hashval_t
|
||||
elfNN_aarch64_local_htab_hash (const void *ptr)
|
||||
{
|
||||
struct elf_link_hash_entry *h
|
||||
= (struct elf_link_hash_entry *) ptr;
|
||||
return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
|
||||
}
|
||||
|
||||
/* Compare local hash entries. */
|
||||
|
||||
static int
|
||||
elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
|
||||
{
|
||||
struct elf_link_hash_entry *h1
|
||||
= (struct elf_link_hash_entry *) ptr1;
|
||||
struct elf_link_hash_entry *h2
|
||||
= (struct elf_link_hash_entry *) ptr2;
|
||||
|
||||
return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
|
||||
}
|
||||
|
||||
/* Find and/or create a hash entry for local symbol. */
|
||||
|
||||
static struct elf_link_hash_entry *
|
||||
elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
|
||||
bfd *abfd, const Elf_Internal_Rela *rel,
|
||||
bfd_boolean create)
|
||||
{
|
||||
struct elf_aarch64_link_hash_entry e, *ret;
|
||||
asection *sec = abfd->sections;
|
||||
hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
|
||||
ELFNN_R_SYM (rel->r_info));
|
||||
void **slot;
|
||||
|
||||
e.root.indx = sec->id;
|
||||
e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
|
||||
slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
|
||||
create ? INSERT : NO_INSERT);
|
||||
|
||||
if (!slot)
|
||||
return NULL;
|
||||
|
||||
if (*slot)
|
||||
{
|
||||
ret = (struct elf_aarch64_link_hash_entry *) *slot;
|
||||
return &ret->root;
|
||||
}
|
||||
|
||||
ret = (struct elf_aarch64_link_hash_entry *)
|
||||
objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
|
||||
sizeof (struct elf_aarch64_link_hash_entry));
|
||||
if (ret)
|
||||
{
|
||||
memset (ret, 0, sizeof (*ret));
|
||||
ret->root.indx = sec->id;
|
||||
ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
|
||||
ret->root.dynindx = -1;
|
||||
*slot = ret;
|
||||
}
|
||||
return &ret->root;
|
||||
}
|
||||
|
||||
/* Copy the extra info we tack onto an elf_link_hash_entry. */
|
||||
|
||||
|
@ -2004,6 +2075,17 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ret->loc_hash_table = htab_try_create (1024,
|
||||
elfNN_aarch64_local_htab_hash,
|
||||
elfNN_aarch64_local_htab_eq,
|
||||
NULL);
|
||||
ret->loc_hash_memory = objalloc_create ();
|
||||
if (!ret->loc_hash_table || !ret->loc_hash_memory)
|
||||
{
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &ret->root.root;
|
||||
}
|
||||
|
||||
|
@ -2015,6 +2097,11 @@ elfNN_aarch64_hash_table_free (struct bfd_link_hash_table *hash)
|
|||
struct elf_aarch64_link_hash_table *ret
|
||||
= (struct elf_aarch64_link_hash_table *) hash;
|
||||
|
||||
if (ret->loc_hash_table)
|
||||
htab_delete (ret->loc_hash_table);
|
||||
if (ret->loc_hash_memory)
|
||||
objalloc_free ((struct objalloc *) ret->loc_hash_memory);
|
||||
|
||||
bfd_hash_table_free (&ret->stub_hash_table);
|
||||
_bfd_elf_link_hash_table_free (hash);
|
||||
}
|
||||
|
@ -3321,8 +3408,10 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||
struct elf_link_hash_entry *h,
|
||||
bfd_boolean *unresolved_reloc_p,
|
||||
bfd_boolean save_addend,
|
||||
bfd_vma *saved_addend)
|
||||
bfd_vma *saved_addend,
|
||||
Elf_Internal_Sym *sym)
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
unsigned int r_type = howto->type;
|
||||
bfd_reloc_code_real_type bfd_r_type
|
||||
= elfNN_aarch64_bfd_reloc_from_howto (howto);
|
||||
|
@ -3336,6 +3425,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||
|
||||
globals = elf_aarch64_hash_table (info);
|
||||
|
||||
symtab_hdr = &elf_symtab_hdr (input_bfd);
|
||||
|
||||
BFD_ASSERT (is_aarch64_elf (input_bfd));
|
||||
|
||||
r_symndx = ELFNN_R_SYM (rel->r_info);
|
||||
|
@ -3362,6 +3453,180 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||
weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
|
||||
: bfd_is_und_section (sym_sec));
|
||||
|
||||
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle
|
||||
it here if it is defined in a non-shared object. */
|
||||
if (h != NULL
|
||||
&& h->type == STT_GNU_IFUNC
|
||||
&& h->def_regular)
|
||||
{
|
||||
asection *plt;
|
||||
const char *name;
|
||||
asection *base_got;
|
||||
bfd_vma off;
|
||||
|
||||
if ((input_section->flags & SEC_ALLOC) == 0
|
||||
|| h->plt.offset == (bfd_vma) -1)
|
||||
abort ();
|
||||
|
||||
/* STT_GNU_IFUNC symbol must go through PLT. */
|
||||
plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
|
||||
value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
|
||||
|
||||
switch (bfd_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 BFD_RELOC_AARCH64_NN:
|
||||
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 relocation only when there is a
|
||||
non-GOT reference in a shared object. */
|
||||
if (info->shared && 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
|
||||
|| info->executable)
|
||||
{
|
||||
/* This symbol is resolved locally. */
|
||||
outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (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 = ELFNN_R_INFO (h->dynindx, r_type);
|
||||
outrel.r_addend = 0;
|
||||
}
|
||||
|
||||
sreloc = globals->root.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. */
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case BFD_RELOC_AARCH64_JUMP26:
|
||||
case BFD_RELOC_AARCH64_CALL26:
|
||||
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
|
||||
signed_addend,
|
||||
weak_undef_p);
|
||||
return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
|
||||
howto, value);
|
||||
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
|
||||
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
|
||||
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
|
||||
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
|
||||
base_got = globals->root.sgot;
|
||||
off = h->got.offset;
|
||||
|
||||
if (base_got == NULL)
|
||||
abort ();
|
||||
|
||||
if (off == (bfd_vma) -1)
|
||||
{
|
||||
bfd_vma plt_index;
|
||||
|
||||
/* 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 (globals->root.splt != NULL)
|
||||
{
|
||||
plt_index = h->plt.offset / globals->plt_entry_size - 1;
|
||||
off = (plt_index + 3) * GOT_ENTRY_SIZE;
|
||||
base_got = globals->root.sgotplt;
|
||||
}
|
||||
else
|
||||
{
|
||||
plt_index = h->plt.offset / globals->plt_entry_size;
|
||||
off = plt_index * GOT_ENTRY_SIZE;
|
||||
base_got = globals->root.igotplt;
|
||||
}
|
||||
|
||||
if (h->dynindx == -1
|
||||
|| h->forced_local
|
||||
|| info->symbolic)
|
||||
{
|
||||
/* This references the local definition. 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_NN (output_bfd, value,
|
||||
base_got->contents + off);
|
||||
/* Note that this is harmless as -1 | 1 still is -1. */
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
}
|
||||
value = (base_got->output_section->vma
|
||||
+ base_got->output_offset + off);
|
||||
}
|
||||
else
|
||||
value = aarch64_calculate_got_entry_vma (h, globals, info,
|
||||
value, output_bfd,
|
||||
unresolved_reloc_p);
|
||||
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
|
||||
0, weak_undef_p);
|
||||
return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
|
||||
case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
|
||||
case BFD_RELOC_AARCH64_ADD_LO12:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (bfd_r_type)
|
||||
{
|
||||
case BFD_RELOC_AARCH64_NONE:
|
||||
|
@ -3387,11 +3652,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||
|
||||
*unresolved_reloc_p = FALSE;
|
||||
|
||||
sreloc = _bfd_elf_get_dynamic_reloc_section (input_bfd,
|
||||
input_section, 1);
|
||||
if (sreloc == NULL)
|
||||
return bfd_reloc_notsupported;
|
||||
|
||||
skip = FALSE;
|
||||
relocate = FALSE;
|
||||
|
||||
|
@ -3428,10 +3688,14 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||
outrel.r_addend += value;
|
||||
}
|
||||
|
||||
loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (htab);
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
if (sreloc == NULL || sreloc->contents == NULL)
|
||||
return bfd_reloc_notsupported;
|
||||
|
||||
loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
|
||||
bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
|
||||
|
||||
if (sreloc->reloc_count * RELOC_SIZE (htab) > sreloc->size)
|
||||
if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
|
||||
{
|
||||
/* Sanity to check that we have previously allocated
|
||||
sufficient space in the relocation section for the
|
||||
|
@ -3851,6 +4115,20 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
|
||||
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
|
||||
|
||||
/* Relocate against local STT_GNU_IFUNC symbol. */
|
||||
if (!info->relocatable
|
||||
&& ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
|
||||
{
|
||||
h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
|
||||
rel, FALSE);
|
||||
if (h == NULL)
|
||||
abort ();
|
||||
|
||||
/* Set STT_GNU_IFUNC symbol value. */
|
||||
h->root.u.def.value = sym->st_value;
|
||||
h->root.u.def.section = sec;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3940,7 +4218,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
|
|||
input_section, contents, rel,
|
||||
relocation, info, sec,
|
||||
h, &unresolved_reloc,
|
||||
save_addend, &addend);
|
||||
save_addend, &addend, sym);
|
||||
|
||||
switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
|
||||
{
|
||||
|
@ -4427,25 +4705,11 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
|
|||
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
{
|
||||
struct elf_aarch64_link_hash_entry *eh;
|
||||
struct elf_dyn_relocs **pp;
|
||||
struct elf_dyn_relocs *p;
|
||||
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
eh = (struct elf_aarch64_link_hash_entry *) h;
|
||||
|
||||
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
|
||||
{
|
||||
if (p->sec == sec)
|
||||
{
|
||||
/* Everything must go for SEC. */
|
||||
*pp = p->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4454,8 +4718,32 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
|
|||
/* A local symbol. */
|
||||
isym = bfd_sym_from_r_symndx (&htab->sym_cache,
|
||||
abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Check relocation against local STT_GNU_IFUNC symbol. */
|
||||
if (isym != NULL
|
||||
&& ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
||||
{
|
||||
h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel, FALSE);
|
||||
if (h == NULL)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
if (h)
|
||||
{
|
||||
struct elf_aarch64_link_hash_entry *eh;
|
||||
struct elf_dyn_relocs **pp;
|
||||
struct elf_dyn_relocs *p;
|
||||
|
||||
eh = (struct elf_aarch64_link_hash_entry *) h;
|
||||
|
||||
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
|
||||
if (p->sec == sec)
|
||||
{
|
||||
/* Everything must go for SEC. */
|
||||
*pp = p->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
|
@ -4486,6 +4774,12 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
|
|||
{
|
||||
if (h->got.refcount > 0)
|
||||
h->got.refcount -= 1;
|
||||
|
||||
if (h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
if (h->plt.refcount > 0)
|
||||
h->plt.refcount -= 1;
|
||||
}
|
||||
}
|
||||
else if (locals != NULL)
|
||||
{
|
||||
|
@ -4547,12 +4841,13 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|||
/* If this is a function, put it in the procedure linkage table. We
|
||||
will fill in the contents of the procedure linkage table later,
|
||||
when we know the address of the .got section. */
|
||||
if (h->type == STT_FUNC || h->needs_plt)
|
||||
if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
|
||||
{
|
||||
if (h->plt.refcount <= 0
|
||||
|| SYMBOL_CALLS_LOCAL (info, h)
|
||||
|| (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
||||
&& h->root.type == bfd_link_hash_undefweak))
|
||||
|| (h->type != STT_GNU_IFUNC
|
||||
&& (SYMBOL_CALLS_LOCAL (info, h)
|
||||
|| (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
||||
&& h->root.type == bfd_link_hash_undefweak))))
|
||||
{
|
||||
/* This case can occur if we saw a CALL26 reloc in
|
||||
an input file, but the symbol wasn't referred to
|
||||
|
@ -4746,6 +5041,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
unsigned long r_symndx;
|
||||
unsigned int r_type;
|
||||
bfd_reloc_code_real_type bfd_r_type;
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
r_symndx = ELFNN_R_SYM (rel->r_info);
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
|
@ -4758,7 +5054,31 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
}
|
||||
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
{
|
||||
/* A local symbol. */
|
||||
isym = bfd_sym_from_r_symndx (&htab->sym_cache,
|
||||
abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Check relocation against local STT_GNU_IFUNC symbol. */
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
||||
{
|
||||
h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
|
||||
TRUE);
|
||||
if (h == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Fake a STT_GNU_IFUNC symbol. */
|
||||
h->type = STT_GNU_IFUNC;
|
||||
h->def_regular = 1;
|
||||
h->ref_regular = 1;
|
||||
h->forced_local = 1;
|
||||
h->root.type = bfd_link_hash_defined;
|
||||
}
|
||||
else
|
||||
h = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
|
@ -4774,6 +5094,38 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
/* Could be done earlier, if h were already available. */
|
||||
bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
/* Create the ifunc sections for static executables. If we
|
||||
never see an indirect function symbol nor we are building
|
||||
a static executable, those sections will be empty and
|
||||
won't appear in output. */
|
||||
switch (bfd_r_type)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case BFD_RELOC_AARCH64_NN:
|
||||
case BFD_RELOC_AARCH64_CALL26:
|
||||
case BFD_RELOC_AARCH64_JUMP26:
|
||||
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
|
||||
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
|
||||
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
|
||||
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
|
||||
case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
|
||||
case BFD_RELOC_AARCH64_ADD_LO12:
|
||||
if (htab->root.dynobj == NULL)
|
||||
htab->root.dynobj = abfd;
|
||||
if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* It is referenced by a non-shared object. */
|
||||
h->ref_regular = 1;
|
||||
h->root.non_ir_ref = 1;
|
||||
}
|
||||
|
||||
switch (bfd_r_type)
|
||||
{
|
||||
case BFD_RELOC_AARCH64_NN:
|
||||
|
@ -4832,7 +5184,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
|
||||
asection *s;
|
||||
void **vpp;
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
isym = bfd_sym_from_r_symndx (&htab->sym_cache,
|
||||
abfd, r_symndx);
|
||||
|
@ -4982,7 +5333,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
continue;
|
||||
|
||||
h->needs_plt = 1;
|
||||
h->plt.refcount += 1;
|
||||
if (h->plt.refcount <= 0)
|
||||
h->plt.refcount = 1;
|
||||
else
|
||||
h->plt.refcount += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -5130,14 +5484,14 @@ elfNN_aarch64_find_inliner_info (bfd *abfd,
|
|||
|
||||
static void
|
||||
elfNN_aarch64_post_process_headers (bfd *abfd,
|
||||
struct bfd_link_info *link_info
|
||||
ATTRIBUTE_UNUSED)
|
||||
struct bfd_link_info *link_info)
|
||||
{
|
||||
Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
|
||||
|
||||
i_ehdrp = elf_elfheader (abfd);
|
||||
i_ehdrp->e_ident[EI_OSABI] = 0;
|
||||
i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
|
||||
|
||||
_bfd_elf_set_osabi (abfd, link_info);
|
||||
}
|
||||
|
||||
static enum elf_reloc_type_class
|
||||
|
@ -5529,12 +5883,6 @@ elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
|
|||
return _bfd_free_cached_info (abfd);
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
elfNN_aarch64_is_function_type (unsigned int type)
|
||||
{
|
||||
return type == STT_FUNC;
|
||||
}
|
||||
|
||||
/* Create dynamic sections. This is different from the ARM backend in that
|
||||
the got, plt, gotplt and their relocation sections are all created in the
|
||||
standard part of the bfd elf backend. */
|
||||
|
@ -5594,7 +5942,12 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||
info = (struct bfd_link_info *) inf;
|
||||
htab = elf_aarch64_hash_table (info);
|
||||
|
||||
if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
|
||||
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
|
||||
here if it is defined and referenced in a non-shared object. */
|
||||
if (h->type == STT_GNU_IFUNC
|
||||
&& h->def_regular)
|
||||
return TRUE;
|
||||
else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
|
||||
{
|
||||
/* Make sure this symbol is output as a dynamic symbol.
|
||||
Undefined weak syms won't yet be marked as dynamic. */
|
||||
|
@ -5849,6 +6202,87 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Allocate space in .plt, .got and associated reloc sections for
|
||||
ifunc dynamic relocs. */
|
||||
|
||||
static bfd_boolean
|
||||
elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
|
||||
void *inf)
|
||||
{
|
||||
struct bfd_link_info *info;
|
||||
struct elf_aarch64_link_hash_table *htab;
|
||||
struct elf_aarch64_link_hash_entry *eh;
|
||||
|
||||
/* An example of a bfd_link_hash_indirect symbol is versioned
|
||||
symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
|
||||
-> __gxx_personality_v0(bfd_link_hash_defined)
|
||||
|
||||
There is no need to process bfd_link_hash_indirect symbols here
|
||||
because we will also be presented with the concrete instance of
|
||||
the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
|
||||
called to copy all relevant data from the generic to the concrete
|
||||
symbol instance.
|
||||
*/
|
||||
if (h->root.type == bfd_link_hash_indirect)
|
||||
return TRUE;
|
||||
|
||||
if (h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
info = (struct bfd_link_info *) inf;
|
||||
htab = elf_aarch64_hash_table (info);
|
||||
|
||||
eh = (struct elf_aarch64_link_hash_entry *) h;
|
||||
|
||||
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
|
||||
here if it is defined and referenced in a non-shared object. */
|
||||
if (h->type == STT_GNU_IFUNC
|
||||
&& h->def_regular)
|
||||
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
|
||||
&eh->dyn_relocs,
|
||||
htab->plt_entry_size,
|
||||
htab->plt_header_size,
|
||||
GOT_ENTRY_SIZE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Allocate space in .plt, .got and associated reloc sections for
|
||||
local dynamic relocs. */
|
||||
|
||||
static bfd_boolean
|
||||
elfNN_aarch64_allocate_local_dynrelocs (void **slot, void *inf)
|
||||
{
|
||||
struct elf_link_hash_entry *h
|
||||
= (struct elf_link_hash_entry *) *slot;
|
||||
|
||||
if (h->type != STT_GNU_IFUNC
|
||||
|| !h->def_regular
|
||||
|| !h->ref_regular
|
||||
|| !h->forced_local
|
||||
|| h->root.type != bfd_link_hash_defined)
|
||||
abort ();
|
||||
|
||||
return elfNN_aarch64_allocate_dynrelocs (h, inf);
|
||||
}
|
||||
|
||||
/* Allocate space in .plt, .got and associated reloc sections for
|
||||
local ifunc dynamic relocs. */
|
||||
|
||||
static bfd_boolean
|
||||
elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
|
||||
{
|
||||
struct elf_link_hash_entry *h
|
||||
= (struct elf_link_hash_entry *) *slot;
|
||||
|
||||
if (h->type != STT_GNU_IFUNC
|
||||
|| !h->def_regular
|
||||
|| !h->ref_regular
|
||||
|| !h->forced_local
|
||||
|| h->root.type != bfd_link_hash_defined)
|
||||
abort ();
|
||||
|
||||
return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
|
||||
}
|
||||
|
||||
/* This is the most important function of all . Innocuosly named
|
||||
though ! */
|
||||
|
@ -5987,6 +6421,20 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||
elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
|
||||
info);
|
||||
|
||||
/* Allocate global ifunc sym .plt and .got entries, and space for global
|
||||
ifunc sym dynamic relocs. */
|
||||
elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
|
||||
info);
|
||||
|
||||
/* Allocate .plt and .got entries, and space for local symbols. */
|
||||
htab_traverse (htab->loc_hash_table,
|
||||
elfNN_aarch64_allocate_local_dynrelocs,
|
||||
info);
|
||||
|
||||
/* Allocate .plt and .got entries, and space for local ifunc symbols. */
|
||||
htab_traverse (htab->loc_hash_table,
|
||||
elfNN_aarch64_allocate_local_ifunc_dynrelocs,
|
||||
info);
|
||||
|
||||
/* For every jump slot reserved in the sgotplt, reloc_count is
|
||||
incremented. However, when we reserve space for TLS descriptors,
|
||||
|
@ -6140,7 +6588,8 @@ elf_aarch64_update_plt_entry (bfd *output_bfd,
|
|||
static void
|
||||
elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
|
||||
struct elf_aarch64_link_hash_table
|
||||
*htab, bfd *output_bfd)
|
||||
*htab, bfd *output_bfd,
|
||||
struct bfd_link_info *info)
|
||||
{
|
||||
bfd_byte *plt_entry;
|
||||
bfd_vma plt_index;
|
||||
|
@ -6149,17 +6598,50 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
|
|||
bfd_vma plt_entry_address;
|
||||
Elf_Internal_Rela rela;
|
||||
bfd_byte *loc;
|
||||
asection *plt, *gotplt, *relplt;
|
||||
|
||||
plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
|
||||
/* When building a static executable, use .iplt, .igot.plt and
|
||||
.rela.iplt sections for STT_GNU_IFUNC symbols. */
|
||||
if (htab->root.splt != NULL)
|
||||
{
|
||||
plt = htab->root.splt;
|
||||
gotplt = htab->root.sgotplt;
|
||||
relplt = htab->root.srelplt;
|
||||
}
|
||||
else
|
||||
{
|
||||
plt = htab->root.iplt;
|
||||
gotplt = htab->root.igotplt;
|
||||
relplt = htab->root.irelplt;
|
||||
}
|
||||
|
||||
/* Offset in the GOT is PLT index plus got GOT headers(3)
|
||||
times GOT_ENTRY_SIZE. */
|
||||
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
|
||||
plt_entry = htab->root.splt->contents + h->plt.offset;
|
||||
plt_entry_address = htab->root.splt->output_section->vma
|
||||
+ htab->root.splt->output_section->output_offset + h->plt.offset;
|
||||
gotplt_entry_address = htab->root.sgotplt->output_section->vma +
|
||||
htab->root.sgotplt->output_offset + got_offset;
|
||||
/* Get the index in the procedure linkage table which
|
||||
corresponds to this symbol. This is the index of this symbol
|
||||
in all the symbols for which we are making plt entries. The
|
||||
first entry in the procedure linkage table is reserved.
|
||||
|
||||
Get the offset into the .got table of the entry that
|
||||
corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
|
||||
bytes. The first three are reserved for the dynamic linker.
|
||||
|
||||
For static executables, we don't reserve anything. */
|
||||
|
||||
if (plt == htab->root.splt)
|
||||
{
|
||||
plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
|
||||
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
plt_index = h->plt.offset / htab->plt_entry_size;
|
||||
got_offset = plt_index * GOT_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
plt_entry = plt->contents + h->plt.offset;
|
||||
plt_entry_address = plt->output_section->vma
|
||||
+ plt->output_section->output_offset + h->plt.offset;
|
||||
gotplt_entry_address = gotplt->output_section->vma +
|
||||
gotplt->output_offset + got_offset;
|
||||
|
||||
/* Copy in the boiler-plate for the PLTn entry. */
|
||||
memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
|
||||
|
@ -6183,19 +6665,35 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
|
|||
|
||||
/* All the GOTPLT Entries are essentially initialized to PLT0. */
|
||||
bfd_put_NN (output_bfd,
|
||||
(htab->root.splt->output_section->vma
|
||||
+ htab->root.splt->output_offset),
|
||||
htab->root.sgotplt->contents + got_offset);
|
||||
plt->output_section->vma + plt->output_offset,
|
||||
gotplt->contents + got_offset);
|
||||
|
||||
/* Fill in the entry in the .rela.plt section. */
|
||||
rela.r_offset = gotplt_entry_address;
|
||||
rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
|
||||
rela.r_addend = 0;
|
||||
|
||||
if (h->dynindx == -1
|
||||
|| ((info->executable
|
||||
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|
||||
&& h->def_regular
|
||||
&& h->type == STT_GNU_IFUNC))
|
||||
{
|
||||
/* If an STT_GNU_IFUNC symbol is locally defined, generate
|
||||
R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
|
||||
rela.r_info = ELFNN_R_INFO (0, AARCH64_R (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
|
||||
{
|
||||
/* Fill in the entry in the .rela.plt section. */
|
||||
rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
|
||||
rela.r_addend = 0;
|
||||
}
|
||||
|
||||
/* Compute the relocation entry to used based on PLT index and do
|
||||
not adjust reloc_count. The reloc_count has already been adjusted
|
||||
to account for this entry. */
|
||||
loc = htab->root.srelplt->contents + plt_index * RELOC_SIZE (htab);
|
||||
loc = relplt->contents + plt_index * RELOC_SIZE (htab);
|
||||
bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
|
||||
}
|
||||
|
||||
|
@ -6255,15 +6753,38 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
|
|||
|
||||
if (h->plt.offset != (bfd_vma) - 1)
|
||||
{
|
||||
asection *plt, *gotplt, *relplt;
|
||||
|
||||
/* This symbol has an entry in the procedure linkage table. Set
|
||||
it up. */
|
||||
|
||||
if (h->dynindx == -1
|
||||
|| htab->root.splt == NULL
|
||||
|| htab->root.sgotplt == NULL || htab->root.srelplt == NULL)
|
||||
/* When building a static executable, use .iplt, .igot.plt and
|
||||
.rela.iplt sections for STT_GNU_IFUNC symbols. */
|
||||
if (htab->root.splt != NULL)
|
||||
{
|
||||
plt = htab->root.splt;
|
||||
gotplt = htab->root.sgotplt;
|
||||
relplt = htab->root.srelplt;
|
||||
}
|
||||
else
|
||||
{
|
||||
plt = htab->root.iplt;
|
||||
gotplt = htab->root.igotplt;
|
||||
relplt = htab->root.irelplt;
|
||||
}
|
||||
|
||||
/* This symbol has an entry in the procedure linkage table. Set
|
||||
it up. */
|
||||
if ((h->dynindx == -1
|
||||
&& !((h->forced_local || info->executable)
|
||||
&& h->def_regular
|
||||
&& h->type == STT_GNU_IFUNC))
|
||||
|| plt == NULL
|
||||
|| gotplt == NULL
|
||||
|| relplt == NULL)
|
||||
abort ();
|
||||
|
||||
elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd);
|
||||
elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
|
||||
if (!h->def_regular)
|
||||
{
|
||||
/* Mark the symbol as undefined, rather than as defined in
|
||||
|
@ -6348,6 +6869,21 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Finish up local dynamic symbol handling. We set the contents of
|
||||
various dynamic sections here. */
|
||||
|
||||
static bfd_boolean
|
||||
elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
|
||||
{
|
||||
struct elf_link_hash_entry *h
|
||||
= (struct elf_link_hash_entry *) *slot;
|
||||
struct bfd_link_info *info
|
||||
= (struct bfd_link_info *) inf;
|
||||
|
||||
return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
|
||||
info, h, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||
struct elf_aarch64_link_hash_table
|
||||
|
@ -6587,6 +7123,11 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
|
|||
elf_section_data (htab->root.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,
|
||||
elfNN_aarch64_finish_local_dynamic_symbol,
|
||||
info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -6706,9 +7247,6 @@ const struct elf_size_info elfNN_aarch64_size_info =
|
|||
#define elf_backend_init_index_section \
|
||||
_bfd_elf_init_2_index_sections
|
||||
|
||||
#define elf_backend_is_function_type \
|
||||
elfNN_aarch64_is_function_type
|
||||
|
||||
#define elf_backend_finish_dynamic_sections \
|
||||
elfNN_aarch64_finish_dynamic_sections
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-10-03 Will Newton <will.newton@linaro.org>
|
||||
|
||||
* emulparams/aarch64elf.sh: Add IREL_IN_PLT.
|
||||
* emulparams/aarch64elf32.sh: Likewise.
|
||||
|
||||
2013-09-30 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* emulparams/msp430all.sh: Update ARCH names.
|
||||
|
|
|
@ -18,6 +18,7 @@ MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
|
|||
ENTRY=_start
|
||||
EMBEDDED=yes
|
||||
SEPARATE_GOTPLT=24
|
||||
IREL_IN_PLT=
|
||||
TEXT_START_ADDR=0x00400000
|
||||
|
||||
DATA_START_SYMBOLS='__data_start = . ;';
|
||||
|
|
|
@ -18,6 +18,7 @@ MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
|
|||
ENTRY=_start
|
||||
EMBEDDED=yes
|
||||
SEPARATE_GOTPLT=24
|
||||
IREL_IN_PLT=
|
||||
TEXT_START_ADDR=0x00400000
|
||||
|
||||
DATA_START_SYMBOLS='__data_start = . ;';
|
||||
|
|
|
@ -1,3 +1,77 @@
|
|||
2013-10-03 Will Newton <will.newton@linaro.org>
|
||||
|
||||
* ld-ifunc/ifunc.exp: Enable ifunc tests for AArch64.
|
||||
* ld-aarch64/aarch64-elf.exp: Run ifunc tests.
|
||||
* ld-aarch64/ifunc-1-local.d: New file.
|
||||
* ld-aarch64/ifunc-1-local.s: Likewise.
|
||||
* ld-aarch64/ifunc-1.d: Likewise.
|
||||
* ld-aarch64/ifunc-1.s: Likewise.
|
||||
* ld-aarch64/ifunc-10.d: Likewise.
|
||||
* ld-aarch64/ifunc-10.s: Likewise.
|
||||
* ld-aarch64/ifunc-11.d: Likewise.
|
||||
* ld-aarch64/ifunc-11.s: Likewise.
|
||||
* ld-aarch64/ifunc-12.d: Likewise.
|
||||
* ld-aarch64/ifunc-12.s: Likewise.
|
||||
* ld-aarch64/ifunc-13.d: Likewise.
|
||||
* ld-aarch64/ifunc-13a.s: Likewise.
|
||||
* ld-aarch64/ifunc-13b.s: Likewise.
|
||||
* ld-aarch64/ifunc-14a.d: Likewise.
|
||||
* ld-aarch64/ifunc-14a.s: Likewise.
|
||||
* ld-aarch64/ifunc-14b.d: Likewise.
|
||||
* ld-aarch64/ifunc-14b.s: Likewise.
|
||||
* ld-aarch64/ifunc-14c.d: Likewise.
|
||||
* ld-aarch64/ifunc-14c.s: Likewise.
|
||||
* ld-aarch64/ifunc-14d.d: Likewise.
|
||||
* ld-aarch64/ifunc-14e.d: Likewise.
|
||||
* ld-aarch64/ifunc-14f.d: Likewise.
|
||||
* ld-aarch64/ifunc-15.d: Likewise.
|
||||
* ld-aarch64/ifunc-15.s: Likewise.
|
||||
* ld-aarch64/ifunc-16.d: Likewise.
|
||||
* ld-aarch64/ifunc-16.s: Likewise.
|
||||
* ld-aarch64/ifunc-17a.d: Likewise.
|
||||
* ld-aarch64/ifunc-17a.s: Likewise.
|
||||
* ld-aarch64/ifunc-17b.d: Likewise.
|
||||
* ld-aarch64/ifunc-17b.s: Likewise.
|
||||
* ld-aarch64/ifunc-18a.d: Likewise.
|
||||
* ld-aarch64/ifunc-18a.s: Likewise.
|
||||
* ld-aarch64/ifunc-18b.d: Likewise.
|
||||
* ld-aarch64/ifunc-18b.s: Likewise.
|
||||
* ld-aarch64/ifunc-19a.d: Likewise.
|
||||
* ld-aarch64/ifunc-19a.s: Likewise.
|
||||
* ld-aarch64/ifunc-19b.d: Likewise.
|
||||
* ld-aarch64/ifunc-19b.s: Likewise.
|
||||
* ld-aarch64/ifunc-2-local.d: Likewise.
|
||||
* ld-aarch64/ifunc-2-local.s: Likewise.
|
||||
* ld-aarch64/ifunc-2.d: Likewise.
|
||||
* ld-aarch64/ifunc-2.s: Likewise.
|
||||
* ld-aarch64/ifunc-20.d: Likewise.
|
||||
* ld-aarch64/ifunc-20.s: Likewise.
|
||||
* ld-aarch64/ifunc-3.s: Likewise.
|
||||
* ld-aarch64/ifunc-3a.d: Likewise.
|
||||
* ld-aarch64/ifunc-3b.d: Likewise.
|
||||
* ld-aarch64/ifunc-4.d: Likewise.
|
||||
* ld-aarch64/ifunc-4.s: Likewise.
|
||||
* ld-aarch64/ifunc-4a.d: Likewise.
|
||||
* ld-aarch64/ifunc-5-local.s: Likewise.
|
||||
* ld-aarch64/ifunc-5.s: Likewise.
|
||||
* ld-aarch64/ifunc-5a-local.d: Likewise.
|
||||
* ld-aarch64/ifunc-5a.d: Likewise.
|
||||
* ld-aarch64/ifunc-5b-local.d: Likewise.
|
||||
* ld-aarch64/ifunc-5b.d: Likewise.
|
||||
* ld-aarch64/ifunc-5r-local.d: Likewise.
|
||||
* ld-aarch64/ifunc-6.s: Likewise.
|
||||
* ld-aarch64/ifunc-6a.d: Likewise.
|
||||
* ld-aarch64/ifunc-6b.d: Likewise.
|
||||
* ld-aarch64/ifunc-7.s: Likewise.
|
||||
* ld-aarch64/ifunc-7a.d: Likewise.
|
||||
* ld-aarch64/ifunc-7b.d: Likewise.
|
||||
* ld-aarch64/ifunc-7c.d: Likewise.
|
||||
* ld-aarch64/ifunc-8.d: Likewise.
|
||||
* ld-aarch64/ifunc-8a.s: Likewise.
|
||||
* ld-aarch64/ifunc-8b.s: Likewise.
|
||||
* ld-aarch64/ifunc-9.d: Likewise.
|
||||
* ld-aarch64/ifunc-9.s: Likewise.
|
||||
|
||||
2013-09-24 Gregory Fong <gregory.0xf0@gmail.com>
|
||||
|
||||
* ld-mips-elf/eh-frame5.d, ld-mips-elf/jalx-2.dd,
|
||||
|
|
|
@ -114,3 +114,44 @@ run_dump_test "gc-tls-relocs"
|
|||
run_dump_test "gc-plt-relocs"
|
||||
run_dump_test "gc-relocs-257-dyn"
|
||||
run_dump_test "gc-relocs-257"
|
||||
|
||||
# ifunc tests
|
||||
run_dump_test "ifunc-1"
|
||||
run_dump_test "ifunc-1-local"
|
||||
run_dump_test "ifunc-2"
|
||||
run_dump_test "ifunc-2-local"
|
||||
run_dump_test "ifunc-3a"
|
||||
run_dump_test "ifunc-3b"
|
||||
run_dump_test "ifunc-4"
|
||||
run_dump_test "ifunc-4a"
|
||||
run_dump_test "ifunc-5a"
|
||||
run_dump_test "ifunc-5b"
|
||||
run_dump_test "ifunc-5a-local"
|
||||
run_dump_test "ifunc-5b-local"
|
||||
run_dump_test "ifunc-5r-local"
|
||||
run_dump_test "ifunc-6a"
|
||||
run_dump_test "ifunc-6b"
|
||||
run_dump_test "ifunc-7a"
|
||||
run_dump_test "ifunc-7b"
|
||||
run_dump_test "ifunc-7c"
|
||||
run_dump_test "ifunc-8"
|
||||
run_dump_test "ifunc-9"
|
||||
run_dump_test "ifunc-10"
|
||||
run_dump_test "ifunc-11"
|
||||
run_dump_test "ifunc-12"
|
||||
run_dump_test "ifunc-13"
|
||||
run_dump_test "ifunc-14a"
|
||||
run_dump_test "ifunc-14b"
|
||||
run_dump_test "ifunc-14c"
|
||||
run_dump_test "ifunc-14d"
|
||||
run_dump_test "ifunc-14e"
|
||||
run_dump_test "ifunc-14f"
|
||||
run_dump_test "ifunc-15"
|
||||
run_dump_test "ifunc-16"
|
||||
run_dump_test "ifunc-17a"
|
||||
run_dump_test "ifunc-17b"
|
||||
run_dump_test "ifunc-18a"
|
||||
run_dump_test "ifunc-18b"
|
||||
run_dump_test "ifunc-19a"
|
||||
run_dump_test "ifunc-19b"
|
||||
run_dump_test "ifunc-20"
|
||||
|
|
7
ld/testsuite/ld-aarch64/ifunc-1-local.d
Normal file
7
ld/testsuite/ld-aarch64/ifunc-1-local.d
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ld: -shared
|
||||
#objdump: -dw
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2a0|0x2f0)@plt>
|
||||
#pass
|
13
ld/testsuite/ld-aarch64/ifunc-1-local.s
Normal file
13
ld/testsuite/ld-aarch64/ifunc-1-local.s
Normal file
|
@ -0,0 +1,13 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.set __GI_foo, foo
|
||||
.text
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl __GI_foo
|
||||
ret
|
||||
.size bar, .-bar
|
7
ld/testsuite/ld-aarch64/ifunc-1.d
Normal file
7
ld/testsuite/ld-aarch64/ifunc-1.d
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ld: -shared
|
||||
#objdump: -dw
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2c0|0x308)@plt>
|
||||
#pass
|
16
ld/testsuite/ld-aarch64/ifunc-1.s
Normal file
16
ld/testsuite/ld-aarch64/ifunc-1.s
Normal file
|
@ -0,0 +1,16 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.global __GI_foo
|
||||
.hidden __GI_foo
|
||||
.set __GI_foo, foo
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl __GI_foo
|
||||
ret
|
||||
.size bar, .-bar
|
5
ld/testsuite/ld-aarch64/ifunc-10.d
Normal file
5
ld/testsuite/ld-aarch64/ifunc-10.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ld: -e bar --gc-sections
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
There are no relocations in this file.
|
25
ld/testsuite/ld-aarch64/ifunc-10.s
Normal file
25
ld/testsuite/ld-aarch64/ifunc-10.s
Normal file
|
@ -0,0 +1,25 @@
|
|||
.section .text.foo,"ax",@progbits
|
||||
.type foo, @function
|
||||
foo:
|
||||
.global foo
|
||||
adrp x0, :got:ifunc
|
||||
ldr x0, [x0, #:got_lo12:ifunc]
|
||||
bl ifunc
|
||||
adrp x0, xxx
|
||||
add x0, x0, :lo12:xxx
|
||||
ret
|
||||
|
||||
.section .text.bar,"ax",@progbits
|
||||
.type bar, @function
|
||||
bar:
|
||||
.global bar
|
||||
ret
|
||||
|
||||
.section .text.ifunc,"ax",@progbits
|
||||
.type ifunc, @gnu_indirect_function
|
||||
ifunc:
|
||||
ret
|
||||
|
||||
.section .data.foo,"aw",@progbits
|
||||
xxx:
|
||||
.quad ifunc
|
5
ld/testsuite/ld-aarch64/ifunc-11.d
Normal file
5
ld/testsuite/ld-aarch64/ifunc-11.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ld: -e bar --gc-sections
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
There are no relocations in this file.
|
26
ld/testsuite/ld-aarch64/ifunc-11.s
Normal file
26
ld/testsuite/ld-aarch64/ifunc-11.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
.section .text.foo,"ax",@progbits
|
||||
.type foo, @function
|
||||
foo:
|
||||
.global foo
|
||||
adrp x0, :got:ifunc
|
||||
ldr x0, [x0, #:got_lo12:ifunc]
|
||||
bl ifunc
|
||||
adrp x0, xxx
|
||||
add x0, x0, :lo12:xxx
|
||||
ret
|
||||
|
||||
.section .text.bar,"ax",@progbits
|
||||
.type bar, @function
|
||||
bar:
|
||||
.global bar
|
||||
ret
|
||||
|
||||
.section .text.ifunc,"ax",@progbits
|
||||
.type ifunc, @gnu_indirect_function
|
||||
.global ifunc
|
||||
ifunc:
|
||||
ret
|
||||
|
||||
.section .data.foo,"aw",@progbits
|
||||
xxx:
|
||||
.quad ifunc
|
5
ld/testsuite/ld-aarch64/ifunc-12.d
Normal file
5
ld/testsuite/ld-aarch64/ifunc-12.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ld: -shared -e bar --gc-sections
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
There are no relocations in this file.
|
24
ld/testsuite/ld-aarch64/ifunc-12.s
Normal file
24
ld/testsuite/ld-aarch64/ifunc-12.s
Normal file
|
@ -0,0 +1,24 @@
|
|||
.section .text.foo,"ax",@progbits
|
||||
.type foo, @function
|
||||
foo:
|
||||
adrp x0, :got:ifunc
|
||||
ldr x0, [x0, #:got_lo12:ifunc]
|
||||
bl ifunc
|
||||
adrp x0, xxx
|
||||
add x0, x0, :lo12:xxx
|
||||
ret
|
||||
|
||||
.section .text.bar,"ax",@progbits
|
||||
.type bar, @function
|
||||
bar:
|
||||
.global bar
|
||||
ret
|
||||
|
||||
.section .text.ifunc,"ax",@progbits
|
||||
.type ifunc, @gnu_indirect_function
|
||||
ifunc:
|
||||
ret
|
||||
|
||||
.section .data.foo,"aw",@progbits
|
||||
xxx:
|
||||
.quad ifunc
|
13
ld/testsuite/ld-aarch64/ifunc-13.d
Normal file
13
ld/testsuite/ld-aarch64/ifunc-13.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
#source: ifunc-13a.s
|
||||
#source: ifunc-13b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ABS64[ ]+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_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
|
11
ld/testsuite/ld-aarch64/ifunc-13a.s
Normal file
11
ld/testsuite/ld-aarch64/ifunc-13a.s
Normal file
|
@ -0,0 +1,11 @@
|
|||
.text
|
||||
.type foo, @function
|
||||
.global foo
|
||||
foo:
|
||||
adrp x0, xxx
|
||||
add x0, x0, :lo12:xxx
|
||||
ret
|
||||
|
||||
.data
|
||||
xxx:
|
||||
.quad ifunc
|
5
ld/testsuite/ld-aarch64/ifunc-13b.s
Normal file
5
ld/testsuite/ld-aarch64/ifunc-13b.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.text
|
||||
.type ifunc, @gnu_indirect_function
|
||||
.globl ifunc
|
||||
ifunc:
|
||||
ret
|
10
ld/testsuite/ld-aarch64/ifunc-14a.d
Normal file
10
ld/testsuite/ld-aarch64/ifunc-14a.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
#source: ifunc-14a.s
|
||||
#source: ifunc-14b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -d
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.*\(TEXTREL\).*
|
||||
#...
|
7
ld/testsuite/ld-aarch64/ifunc-14a.s
Normal file
7
ld/testsuite/ld-aarch64/ifunc-14a.s
Normal file
|
@ -0,0 +1,7 @@
|
|||
.text
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl foo
|
||||
.size bar, .-bar
|
||||
.hidden foo
|
10
ld/testsuite/ld-aarch64/ifunc-14b.d
Normal file
10
ld/testsuite/ld-aarch64/ifunc-14b.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
#source: ifunc-14b.s
|
||||
#source: ifunc-14a.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -d
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.*\(TEXTREL\).*
|
||||
#...
|
5
ld/testsuite/ld-aarch64/ifunc-14b.s
Normal file
5
ld/testsuite/ld-aarch64/ifunc-14b.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
10
ld/testsuite/ld-aarch64/ifunc-14c.d
Normal file
10
ld/testsuite/ld-aarch64/ifunc-14c.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
#source: ifunc-14a.s
|
||||
#source: ifunc-14b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.* +R_AARCH64_NONE +.*
|
||||
#...
|
7
ld/testsuite/ld-aarch64/ifunc-14c.s
Normal file
7
ld/testsuite/ld-aarch64/ifunc-14c.s
Normal file
|
@ -0,0 +1,7 @@
|
|||
.text
|
||||
.globl xxx
|
||||
.type xxx, @function
|
||||
xxx:
|
||||
bl foo
|
||||
.size xxx, .-xxx
|
||||
.hidden foo
|
10
ld/testsuite/ld-aarch64/ifunc-14d.d
Normal file
10
ld/testsuite/ld-aarch64/ifunc-14d.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
#source: ifunc-14b.s
|
||||
#source: ifunc-14a.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.* +R_AARCH64_NONE +.*
|
||||
#...
|
11
ld/testsuite/ld-aarch64/ifunc-14e.d
Normal file
11
ld/testsuite/ld-aarch64/ifunc-14e.d
Normal file
|
@ -0,0 +1,11 @@
|
|||
#source: ifunc-14a.s
|
||||
#source: ifunc-14c.s
|
||||
#source: ifunc-14b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.* +R_AARCH64_NONE +.*
|
||||
#...
|
11
ld/testsuite/ld-aarch64/ifunc-14f.d
Normal file
11
ld/testsuite/ld-aarch64/ifunc-14f.d
Normal file
|
@ -0,0 +1,11 @@
|
|||
#source: ifunc-14a.s
|
||||
#source: ifunc-14b.s
|
||||
#source: ifunc-14c.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#failif
|
||||
#...
|
||||
.* +R_AARCH64_NONE +.*
|
||||
#...
|
12
ld/testsuite/ld-aarch64/ifunc-15.d
Normal file
12
ld/testsuite/ld-aarch64/ifunc-15.d
Normal file
|
@ -0,0 +1,12 @@
|
|||
#source: ifunc-15.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.got' at offset 0x[0-9a-f]+ contains 1 entries:
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_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_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
|
11
ld/testsuite/ld-aarch64/ifunc-15.s
Normal file
11
ld/testsuite/ld-aarch64/ifunc-15.s
Normal file
|
@ -0,0 +1,11 @@
|
|||
.text
|
||||
.type foo, @function
|
||||
.global foo
|
||||
foo:
|
||||
adrp x0, :got:ifunc
|
||||
ldr x0, [x0, #:got_lo12:ifunc]
|
||||
ret
|
||||
.type ifunc, @gnu_indirect_function
|
||||
.globl ifunc
|
||||
ifunc:
|
||||
ret
|
9
ld/testsuite/ld-aarch64/ifunc-16.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-16.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#source: ifunc-16.s
|
||||
#ld: -shared
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+0+[ ]+ifunc \+ 0
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
17
ld/testsuite/ld-aarch64/ifunc-16.s
Normal file
17
ld/testsuite/ld-aarch64/ifunc-16.s
Normal file
|
@ -0,0 +1,17 @@
|
|||
.text
|
||||
.globl fct
|
||||
.type fct, @gnu_indirect_function
|
||||
.set fct,resolve
|
||||
.hidden int_fct
|
||||
.globl int_fct
|
||||
.set int_fct,fct
|
||||
.p2align 4,,15
|
||||
.type resolve, @function
|
||||
resolve:
|
||||
bl ifunc
|
||||
.size resolve, .-resolve
|
||||
.globl g
|
||||
.type g, @function
|
||||
g:
|
||||
bl int_fct
|
||||
.size g, .-g
|
9
ld/testsuite/ld-aarch64/ifunc-17a.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-17a.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#source: ifunc-17a.s
|
||||
#source: ifunc-17b.s
|
||||
#ld: -static
|
||||
#readelf: -s --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
11
ld/testsuite/ld-aarch64/ifunc-17a.s
Normal file
11
ld/testsuite/ld-aarch64/ifunc-17a.s
Normal file
|
@ -0,0 +1,11 @@
|
|||
.globl main
|
||||
.globl start
|
||||
.globl _start
|
||||
.globl __start
|
||||
.text
|
||||
main:
|
||||
start:
|
||||
_start:
|
||||
__start:
|
||||
.byte 0
|
||||
.common foo,4,4
|
9
ld/testsuite/ld-aarch64/ifunc-17b.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-17b.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#source: ifunc-17b.s
|
||||
#source: ifunc-17a.s
|
||||
#ld: -static
|
||||
#readelf: -s --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
6
ld/testsuite/ld-aarch64/ifunc-17b.s
Normal file
6
ld/testsuite/ld-aarch64/ifunc-17b.s
Normal file
|
@ -0,0 +1,6 @@
|
|||
.weak foo
|
||||
.type foo, %gnu_indirect_function
|
||||
.size foo,1
|
||||
.text
|
||||
foo:
|
||||
.byte 1
|
14
ld/testsuite/ld-aarch64/ifunc-18a.d
Normal file
14
ld/testsuite/ld-aarch64/ifunc-18a.d
Normal file
|
@ -0,0 +1,14 @@
|
|||
#source: ifunc-18a.s
|
||||
#source: ifunc-18b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
5
ld/testsuite/ld-aarch64/ifunc-18a.s
Normal file
5
ld/testsuite/ld-aarch64/ifunc-18a.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.section .data.rel,"aw",@progbits
|
||||
.globl foo_ptrt
|
||||
.type foo_ptr, @object
|
||||
foo_ptr:
|
||||
.dc.a foo
|
14
ld/testsuite/ld-aarch64/ifunc-18b.d
Normal file
14
ld/testsuite/ld-aarch64/ifunc-18b.d
Normal file
|
@ -0,0 +1,14 @@
|
|||
#source: ifunc-18b.s
|
||||
#source: ifunc-18a.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
15
ld/testsuite/ld-aarch64/ifunc-18b.s
Normal file
15
ld/testsuite/ld-aarch64/ifunc-18b.s
Normal file
|
@ -0,0 +1,15 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.hidden foo
|
||||
.globl foo
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
bar:
|
||||
bl foo1
|
||||
ret
|
||||
.size bar, .-bar
|
||||
.hidden foo1
|
||||
.globl foo1
|
||||
foo1 = foo
|
13
ld/testsuite/ld-aarch64/ifunc-19a.d
Normal file
13
ld/testsuite/ld-aarch64/ifunc-19a.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
#source: ifunc-19a.s
|
||||
#source: ifunc-19b.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
5
ld/testsuite/ld-aarch64/ifunc-19a.s
Normal file
5
ld/testsuite/ld-aarch64/ifunc-19a.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.section .data.rel,"aw",@progbits
|
||||
.globl foo_ptrt
|
||||
.type foo_ptr, @object
|
||||
foo_ptr:
|
||||
.dc.a foo1
|
13
ld/testsuite/ld-aarch64/ifunc-19b.d
Normal file
13
ld/testsuite/ld-aarch64/ifunc-19b.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
#source: ifunc-19b.s
|
||||
#source: ifunc-19a.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
15
ld/testsuite/ld-aarch64/ifunc-19b.s
Normal file
15
ld/testsuite/ld-aarch64/ifunc-19b.s
Normal file
|
@ -0,0 +1,15 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.hidden foo
|
||||
.globl foo
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
bar:
|
||||
bl foo1
|
||||
ret
|
||||
.size bar, .-bar
|
||||
.hidden foo1
|
||||
.globl foo1
|
||||
foo1 = foo
|
9
ld/testsuite/ld-aarch64/ifunc-2-local.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-2-local.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ld: -shared
|
||||
#objdump: -dw
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2a0|0x2f0)@plt>
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+x0, 0 <.*>
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+x0, x0, #(0x290|0x2e0)
|
||||
#pass
|
15
ld/testsuite/ld-aarch64/ifunc-2-local.s
Normal file
15
ld/testsuite/ld-aarch64/ifunc-2-local.s
Normal file
|
@ -0,0 +1,15 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.set __GI_foo, foo
|
||||
.text
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl __GI_foo
|
||||
adrp x0, __GI_foo
|
||||
add x0, x0, :lo12:__GI_foo
|
||||
ret
|
||||
.size bar, .-bar
|
9
ld/testsuite/ld-aarch64/ifunc-2.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-2.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ld: -shared
|
||||
#objdump: -dw
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2c0|0x308)@plt>
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+x0, 0 <.*>
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+x0, x0, #(0x2b0|0x2f8)
|
||||
#pass
|
18
ld/testsuite/ld-aarch64/ifunc-2.s
Normal file
18
ld/testsuite/ld-aarch64/ifunc-2.s
Normal file
|
@ -0,0 +1,18 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.global __GI_foo
|
||||
.hidden __GI_foo
|
||||
.set __GI_foo, foo
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl __GI_foo
|
||||
adrp x0, __GI_foo
|
||||
add x0, x0, :lo12:__GI_foo
|
||||
ret
|
||||
.size bar, .-bar
|
12
ld/testsuite/ld-aarch64/ifunc-20.d
Normal file
12
ld/testsuite/ld-aarch64/ifunc-20.d
Normal file
|
@ -0,0 +1,12 @@
|
|||
#source: ifunc-20.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ABS64[ ]+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_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
|
16
ld/testsuite/ld-aarch64/ifunc-20.s
Normal file
16
ld/testsuite/ld-aarch64/ifunc-20.s
Normal file
|
@ -0,0 +1,16 @@
|
|||
.section .data.rel,"aw",@progbits
|
||||
.globl ifunc_ptrt
|
||||
.type ifunc_ptr, @object
|
||||
ifunc_ptr:
|
||||
.dc.a ifunc
|
||||
.text
|
||||
.type ifunc, @gnu_indirect_function
|
||||
.globl ifunc
|
||||
ifunc:
|
||||
ret
|
||||
.size ifunc, .-ifunc
|
||||
.type bar, @function
|
||||
.globl bar
|
||||
bar:
|
||||
bl ifunc
|
||||
.size bar, .-bar
|
16
ld/testsuite/ld-aarch64/ifunc-3.s
Normal file
16
ld/testsuite/ld-aarch64/ifunc-3.s
Normal file
|
@ -0,0 +1,16 @@
|
|||
.type foo, %gnu_indirect_function
|
||||
.global __GI_foo
|
||||
.protected __GI_foo
|
||||
.set __GI_foo, foo
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.globl bar
|
||||
.type bar, @function
|
||||
bar:
|
||||
bl __GI_foo
|
||||
ret
|
||||
.size bar, .-bar
|
8
ld/testsuite/ld-aarch64/ifunc-3a.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-3a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-3.s
|
||||
#ld: -shared
|
||||
#objdump: -dw
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2e0|0x330)@plt>
|
||||
#pass
|
8
ld/testsuite/ld-aarch64/ifunc-3b.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-3b.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-3.s
|
||||
#ld: -shared
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
|
||||
#pass
|
7
ld/testsuite/ld-aarch64/ifunc-4.d
Normal file
7
ld/testsuite/ld-aarch64/ifunc-4.d
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
#...
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
|
||||
#pass
|
18
ld/testsuite/ld-aarch64/ifunc-4.s
Normal file
18
ld/testsuite/ld-aarch64/ifunc-4.s
Normal file
|
@ -0,0 +1,18 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
bl foo
|
8
ld/testsuite/ld-aarch64/ifunc-4a.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-4a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ld: -s
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
#source: ifunc-4.s
|
||||
|
||||
#...
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
|
||||
#pass
|
19
ld/testsuite/ld-aarch64/ifunc-5-local.s
Normal file
19
ld/testsuite/ld-aarch64/ifunc-5-local.s
Normal file
|
@ -0,0 +1,19 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
bl foo
|
||||
adrp x0, :got:foo
|
||||
ldr x0, [x0, #:got_lo12:foo]
|
20
ld/testsuite/ld-aarch64/ifunc-5.s
Normal file
20
ld/testsuite/ld-aarch64/ifunc-5.s
Normal file
|
@ -0,0 +1,20 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
bl foo
|
||||
adrp x0, :got:foo
|
||||
ldr x0, [x0, #:got_lo12:foo]
|
8
ld/testsuite/ld-aarch64/ifunc-5a-local.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-5a-local.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-5-local.s
|
||||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
8
ld/testsuite/ld-aarch64/ifunc-5a.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-5a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-5.s
|
||||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
8
ld/testsuite/ld-aarch64/ifunc-5b-local.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-5b-local.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-5-local.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
12
ld/testsuite/ld-aarch64/ifunc-5b.d
Normal file
12
ld/testsuite/ld-aarch64/ifunc-5b.d
Normal file
|
@ -0,0 +1,12 @@
|
|||
#source: ifunc-5.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.got' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_GLOB_DAT[ ]+foo\(\)[ ]+foo \+ 0
|
||||
#...
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0
|
10
ld/testsuite/ld-aarch64/ifunc-5r-local.d
Normal file
10
ld/testsuite/ld-aarch64/ifunc-5r-local.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
#source: ifunc-5-local.s
|
||||
#ld: -r
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.text' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_CALL26[ ]+foo\(\)[ ]+foo \+ 0
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ADR_GOT_PAGE[ ]+foo\(\)[ ]+foo \+ 0
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_LD64_GOT_LO1[ ]+foo\(\)[ ]+foo \+ 0
|
21
ld/testsuite/ld-aarch64/ifunc-6.s
Normal file
21
ld/testsuite/ld-aarch64/ifunc-6.s
Normal file
|
@ -0,0 +1,21 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.protected foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
bl foo
|
||||
adrp x0, :got:foo
|
||||
ldr x0, [x0, #:got_lo12:foo]
|
8
ld/testsuite/ld-aarch64/ifunc-6a.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-6a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-6.s
|
||||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
12
ld/testsuite/ld-aarch64/ifunc-6b.d
Normal file
12
ld/testsuite/ld-aarch64/ifunc-6b.d
Normal file
|
@ -0,0 +1,12 @@
|
|||
#source: ifunc-6.s
|
||||
#ld: -shared -z nocombreloc
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.got' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_GLOB_DAT[ ]+foo\(\)[ ]+foo \+ 0
|
||||
#...
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
21
ld/testsuite/ld-aarch64/ifunc-7.s
Normal file
21
ld/testsuite/ld-aarch64/ifunc-7.s
Normal file
|
@ -0,0 +1,21 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.hidden foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
bl foo
|
||||
adrp x0, :got:foo
|
||||
ldr x0, [x0, #:got_lo12:foo]
|
8
ld/testsuite/ld-aarch64/ifunc-7a.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-7a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-7.s
|
||||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
8
ld/testsuite/ld-aarch64/ifunc-7b.d
Normal file
8
ld/testsuite/ld-aarch64/ifunc-7b.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
#source: ifunc-7.s
|
||||
#ld: -shared
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
19
ld/testsuite/ld-aarch64/ifunc-7c.d
Normal file
19
ld/testsuite/ld-aarch64/ifunc-7c.d
Normal file
|
@ -0,0 +1,19 @@
|
|||
#source: ifunc-7.s
|
||||
#ld: -shared
|
||||
#objdump: -dr -j .text
|
||||
#target: aarch64*-*-*
|
||||
|
||||
# Check if adrp and ldr have been relocated correctly.
|
||||
|
||||
.*: file format elf.+aarch64.*
|
||||
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
[0-9a-f]+ <foo>:
|
||||
[0-9a-f]+: d65f03c0 ret
|
||||
|
||||
[0-9a-f]+ <__start>:
|
||||
[0-9a-f]+: [0-9a-f]+ bl [0-9a-f]+ <\*ABS\*\+0x[0-9a-f]+@plt>
|
||||
[0-9a-f]+: [0-9a-f]+ adrp x0, [0-9]+ <__start\+0x[0-9a-f]+>
|
||||
[0-9a-f]+: [0-9a-f]+ ldr x0, \[x0,.+\]
|
9
ld/testsuite/ld-aarch64/ifunc-8.d
Normal file
9
ld/testsuite/ld-aarch64/ifunc-8.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
#source: ifunc-8a.s
|
||||
#source: ifunc-8b.s
|
||||
#ld:
|
||||
#readelf: -r --wide
|
||||
#target: aarch64*-*-*
|
||||
|
||||
Relocation section '.rela.plt' at .*
|
||||
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
|
13
ld/testsuite/ld-aarch64/ifunc-8a.s
Normal file
13
ld/testsuite/ld-aarch64/ifunc-8a.s
Normal file
|
@ -0,0 +1,13 @@
|
|||
.text
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
adrp x0, :got:foo
|
||||
ldr x0, [x0, #:got_lo12:foo]
|
7
ld/testsuite/ld-aarch64/ifunc-8b.s
Normal file
7
ld/testsuite/ld-aarch64/ifunc-8b.s
Normal file
|
@ -0,0 +1,7 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
3
ld/testsuite/ld-aarch64/ifunc-9.d
Normal file
3
ld/testsuite/ld-aarch64/ifunc-9.d
Normal file
|
@ -0,0 +1,3 @@
|
|||
#ld: --export-dynamic
|
||||
#error: .*dynamic STT_GNU_IFUNC symbol `foo' with pointer equality in `.*.o' can not be used when making an executable; recompile with -fPIE and relink with -pie
|
||||
#target: aarch64*-*-*
|
23
ld/testsuite/ld-aarch64/ifunc-9.s
Normal file
23
ld/testsuite/ld-aarch64/ifunc-9.s
Normal file
|
@ -0,0 +1,23 @@
|
|||
.text
|
||||
.type foo, %gnu_indirect_function
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
.size foo, .-foo
|
||||
.type start,"function"
|
||||
.global start
|
||||
start:
|
||||
.type _start,"function"
|
||||
.global _start
|
||||
_start:
|
||||
.type __start,"function"
|
||||
.global __start
|
||||
__start:
|
||||
.type __start,"function"
|
||||
adrp x0, .LANCHOR0
|
||||
add x0, x0, :lo12:.LANCHOR0
|
||||
.data
|
||||
.align 3
|
||||
.LANCHOR0 = . + 0
|
||||
.xword foo
|
|
@ -24,10 +24,11 @@
|
|||
|
||||
|
||||
# IFUNC support has only been implemented for the ix86, x86_64, powerpc,
|
||||
# and sparc so far.
|
||||
# aarch64 and sparc so far.
|
||||
if {!(([istarget "i?86-*-*"]
|
||||
|| [istarget "x86_64-*-*"]
|
||||
|| [istarget "powerpc*-*-*"]
|
||||
|| [istarget "aarch64*-*-*"]
|
||||
|| [istarget "sparc*-*-*"])
|
||||
&& ([istarget "*-*-elf*"]
|
||||
|| [istarget "*-*-nacl*"]
|
||||
|
|
Loading…
Reference in a new issue