[AArch64] Fix PR18841 ifunc relocation ordering
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Tue, 4 Jul 2017 14:43:59 +0000 (15:43 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 19 Jul 2017 17:47:22 +0000 (18:47 +0100)
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.

bfd/ChangeLog
bfd/elfnn-aarch64.c

index 6f4a5b30c934d473fd85a2db2419ecdc712433f4..9f478f2eaa4ae4bc85bf9c34c04e676886cdd551 100644 (file)
@@ -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
index de7b627004fcc63a0c4a572167f016f698f37003..be2f89cfc30340ba69950b0a6db7b6b789b7cc9b 100644 (file)
@@ -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):