aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-08-18 09:47:59 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-08-18 09:50:08 -0700
commitcae1fbbb7e3d770702a0d7a5027b46835e6adc13 (patch)
tree892f4044f4c7e0e5bcd830f51fa7b0728e63050f /bfd/elf64-x86-64.c
parent2b4bf6afd4506165007c0e76bc7c4381031cfaf6 (diff)
downloadgdb-cae1fbbb7e3d770702a0d7a5027b46835e6adc13.zip
gdb-cae1fbbb7e3d770702a0d7a5027b46835e6adc13.tar.gz
gdb-cae1fbbb7e3d770702a0d7a5027b46835e6adc13.tar.bz2
Return reloc_class_ifunc for reloc against IFUNC
elf_XXX_reloc_type_class should return reloc_class_ifunc for relocation against STT_GNU_IFUNC symbol. bfd/ PR ld/18841 * elf-bfd.h (elf_link_hash_table): Add dynsym. * elf32-i386.c (elf_i386_reloc_type_class): Return reloc_class_ifunc for relocation against STT_GNU_IFUNC symbol. * elf64-x86-64.c (elf_x86_64_reloc_type_class): Likewise. * elflink.c (_bfd_elf_link_create_dynamic_sections): Set dynsym. (bfd_elf_size_dynsym_hash_dynstr): Use dynsym. (elf_final_link_info): Remove dynsym_sec. (elf_link_output_extsym): Replace dynsym_sec with dynsym. (bfd_elf_final_link): Remove reference to dynsym_sec. Replace dynsym_sec with dynsym. ld/testsuite/ PR ld/18841 * ld-ifunc/ifunc.exp: Add a test for PR ld/18841. * ld-ifunc/pr18841.out: New file. * ld-ifunc/pr18841a.c: Likewise. * ld-ifunc/pr18841b.c: Likewise.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 987ce0e..f15d33e 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -5464,10 +5464,27 @@ elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_x86_64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
const asection *rel_sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *rela)
{
+ bfd *abfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
+ unsigned long r_symndx = htab->r_sym (rela->r_info);
+ Elf_Internal_Sym sym;
+
+ if (htab->elf.dynsym == NULL
+ || !bed->s->swap_symbol_in (abfd,
+ (htab->elf.dynsym->contents
+ + r_symndx * bed->s->sizeof_sym),
+ 0, &sym))
+ abort ();
+
+ /* Check relocation against STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+ return reloc_class_ifunc;
+
switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_X86_64_RELATIVE: