[binutils-gdb] S/390: ifunc: Fix PR18841.

Andreas Krebbel krebbel@sourceware.org
Thu Oct 22 08:16:00 GMT 2015


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0f042c67a04d5d0c8f879c27d651a7ed5aa6566f

commit 0f042c67a04d5d0c8f879c27d651a7ed5aa6566f
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date:   Thu Oct 22 10:11:07 2015 +0200

    S/390: ifunc: Fix PR18841.
    
    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.

Diff:
---
 bfd/ChangeLog    |  7 +++++++
 bfd/elf32-s390.c | 17 +++++++++++++++++
 bfd/elf64-s390.c | 17 +++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 44dd4d2..0ab1aed 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
 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
 	elf_s390_finish_ifunc_symbol only for actually defined symbols.
 	* elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index 85ac298..b1f9dbc 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -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:
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 1add8d5..588892f 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -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:



More information about the Binutils-cvs mailing list