S/390: ifunc: Fix PR18841.
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Thu, 22 Oct 2015 08:11:07 +0000 (10:11 +0200)
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Thu, 22 Oct 2015 08:11:07 +0000 (10:11 +0200)
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.

bfd/ChangeLog:

PR ld/18841
* elf32-s390.c (elf_s390_reloc_type_class): Return
reloc_class_ifunc for ifunc symbols.
* elf64-s390.c (elf_s390_reloc_type_class): Likewise.

bfd/ChangeLog
bfd/elf32-s390.c
bfd/elf64-s390.c

index 44dd4d245878302875170c111787233db616a04e..0ab1aed7f3c4a04e1f8e1d14220ed8303c946ba4 100644 (file)
@@ -1,3 +1,10 @@
+2015-10-22  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       PR ld/18841
+       * elf32-s390.c (elf_s390_reloc_type_class): Return
+       reloc_class_ifunc for ifunc symbols.
+       * elf64-s390.c (elf_s390_reloc_type_class): Likewise.
+
 2015-10-22  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * elf32-s390.c (elf_s390_finish_dynamic_symbol): Call
index 85ac2982252bc3783a46b002a7db1e6c838bf866..b1f9dbcb1159736355fff0656f05e5def52255cf 100644 (file)
@@ -3805,6 +3805,23 @@ elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
                           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_s390_link_hash_table *htab = elf_s390_hash_table (info);
+  unsigned long r_symndx = ELF32_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_390_RELATIVE:
index 1add8d50100a3af6fb9ad43cb433b3c52b86fad6..588892fb8cf538dc3aeafd021ef0e840e3c780ea 100644 (file)
@@ -3604,6 +3604,23 @@ elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
                           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_s390_link_hash_table *htab = elf_s390_hash_table (info);
+  unsigned long r_symndx = ELF64_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) ELF64_R_TYPE (rela->r_info))
     {
     case R_390_RELATIVE: