From c428ce9d900c4acc4a7ee74791c55676d96f0818 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 14 Jun 2016 10:18:26 -0700 Subject: [PATCH] Check R_*_IRELATIVE in x86 reloc_type_class elf_{i386|x86_64}_reloc_type_class should return reloc_class_ifunc for R_386_IRELATIVE/R_X86_64_IRELATIVE relocations. There is no need to check symbol type for STN_UNDEF symbol index. * elf32-i386.c (elf_i386_reloc_type_class): Check R_386_IRELATIVE. Don't check symbol type for STN_UNDEF symbol index. * elf64-x86-64.c (elf_x86_64_reloc_type_class): Check R_X86_64_IRELATIVE. Don't check symbol type for STN_UNDEF symbol index. --- bfd/ChangeLog | 8 ++++++++ bfd/elf32-i386.c | 21 +++++++++++++-------- bfd/elf64-x86-64.c | 5 ++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7e64f86ec08..f88e18582f2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2016-06-14 H.J. Lu + + * elf32-i386.c (elf_i386_reloc_type_class): Check R_386_IRELATIVE. + Don't check symbol type for STN_UNDEF symbol index. + * elf64-x86-64.c (elf_x86_64_reloc_type_class): Check + R_X86_64_IRELATIVE. Don't check symbol type for STN_UNDEF symbol + index. + 2016-06-14 Thomas Preud'homme * elf32-arm.c (using_thumb_only): Force review of arch check logic for diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index a68ce1fc186..686c0682fb0 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -5562,19 +5562,24 @@ elf_i386_reloc_type_class (const struct bfd_link_info *info, /* Check relocation against STT_GNU_IFUNC symbol if there are dynamic symbols. */ unsigned long r_symndx = ELF32_R_SYM (rela->r_info); - Elf_Internal_Sym sym; - if (!bed->s->swap_symbol_in (abfd, - (htab->dynsym->contents - + r_symndx * sizeof (Elf32_External_Sym)), - 0, &sym)) - abort (); + if (r_symndx != STN_UNDEF) + { + Elf_Internal_Sym sym; + if (!bed->s->swap_symbol_in (abfd, + (htab->dynsym->contents + + r_symndx * sizeof (Elf32_External_Sym)), + 0, &sym)) + abort (); - if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) - return reloc_class_ifunc; + if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) + return reloc_class_ifunc; + } } switch (ELF32_R_TYPE (rela->r_info)) { + case R_386_IRELATIVE: + return reloc_class_ifunc; case R_386_RELATIVE: return reloc_class_relative; case R_386_JUMP_SLOT: diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index f8a7ca39e66..b2096044a10 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -6001,9 +6001,6 @@ elf_x86_64_reloc_type_class (const struct bfd_link_info *info, 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); - if ((int) ELF32_R_TYPE (rela->r_info) == R_X86_64_IRELATIVE) - return reloc_class_ifunc; - if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL) { @@ -6026,6 +6023,8 @@ elf_x86_64_reloc_type_class (const struct bfd_link_info *info, switch ((int) ELF32_R_TYPE (rela->r_info)) { + case R_X86_64_IRELATIVE: + return reloc_class_ifunc; case R_X86_64_RELATIVE: case R_X86_64_RELATIVE64: return reloc_class_relative; -- 2.30.2