diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6f4a5b30c93..9f478f2eaa4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2017-07-19 Szabolcs Nagy + + PR ld/18841 + * elfnn-aarch64.c (elfNN_aarch64_reloc_type_class): Return + reloc_class_ifunc for ifunc symbols. + 2017-07-19 Nick Clifton PR 21787 diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index de7b627004f..be2f89cfc30 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -7634,8 +7634,39 @@ elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSE const asection *rel_sec ATTRIBUTE_UNUSED, const Elf_Internal_Rela *rela) { + struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info); + + if (htab->root.dynsym != NULL + && htab->root.dynsym->contents != NULL) + { + /* Check relocation against STT_GNU_IFUNC symbol if there are + dynamic symbols. */ + bfd *abfd = info->output_bfd; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + unsigned long r_symndx = ELFNN_R_SYM (rela->r_info); + if (r_symndx != STN_UNDEF) + { + Elf_Internal_Sym sym; + if (!bed->s->swap_symbol_in (abfd, + (htab->root.dynsym->contents + + r_symndx * bed->s->sizeof_sym), + 0, &sym)) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%B symbol number %lu references" + " nonexistent SHT_SYMTAB_SHNDX section"), + abfd, r_symndx); + /* Ideally an error class should be returned here. */ + } + else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) + return reloc_class_ifunc; + } + } + switch ((int) ELFNN_R_TYPE (rela->r_info)) { + case AARCH64_R (IRELATIVE): + return reloc_class_ifunc; case AARCH64_R (RELATIVE): return reloc_class_relative; case AARCH64_R (JUMP_SLOT):