aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2017-07-04 15:43:59 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2017-07-19 18:47:22 +0100
commitf2e6a8430e72d58e70aaaaefbb32dc3953d5cf33 (patch)
tree7664b9a14de92a4b907cfad315b0e0e399ed12dd
parent6c4e7b6bfbc4679f695106de2817ecf02b27c8be (diff)
[AArch64] Fix PR18841 ifunc relocation ordering
In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for x86. Fixes FAIL: Run pr18841 with libpr18841c.so bfd/ PR ld/18841 * elfnn-aarch64.c (elfNN_aarch64_reloc_type_class): Return reloc_class_ifunc for ifunc symbols.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elfnn-aarch64.c31
2 files changed, 37 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6f4a5b30c9..9f478f2eaa 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-07-19 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+ PR ld/18841
+ * elfnn-aarch64.c (elfNN_aarch64_reloc_type_class): Return
+ reloc_class_ifunc for ifunc symbols.
+
2017-07-19 Nick Clifton <nickc@redhat.com>
PR 21787
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index de7b627004..be2f89cfc3 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):