This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_32-branch] SPARC: fix PR ld/18841


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

commit afbdeb58468604ede2d51fb00c4ea9850fcf2617
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Thu Feb 7 17:04:31 2019 +0100

    SPARC: fix PR ld/18841
    
    This fixes the last ld failures on SPARC64/Linux:
    
    FAIL: Run pr18841 with libpr18841b.so
    FAIL: Run pr18841 with libpr18841c.so
    FAIL: Run pr18841 with libpr18841bn.so (-z now)
    FAIL: Run pr18841 with libpr18841cn.so (-z now)
    
    by mimicing what has been done on x86-64 and Aarch64 to fix the PR.
    
    bfd/
    	PR ld/18841
            * elf32-sparc.c (elf32_sparc_reloc_type_class): Return
            reloc_class_ifunc for ifunc symbols.
            * elf64-sparc.c (elf64_sparc_reloc_type_class): Likewise.

Diff:
---
 bfd/ChangeLog     |  7 +++++++
 bfd/elf32-sparc.c | 33 ++++++++++++++++++++++++++++++++-
 bfd/elf64-sparc.c | 33 ++++++++++++++++++++++++++++++++-
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3714662..3faecb8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
 2019-02-07  Eric Botcazou  <ebotcazou@adacore.com>
 
+	PR ld/18841
+	* elf32-sparc.c (elf32_sparc_reloc_type_class): Return
+	reloc_class_ifunc for ifunc symbols.
+	* elf64-sparc.c (elf64_sparc_reloc_type_class): Likewise.
+
+2019-02-07  Eric Botcazou  <ebotcazou@adacore.com>
+
 	* elf32-visium.c (visium_elf_howto_parity_reloc): Minor tweak.
 	<R_VISIUM_PC16>: Use explicit range test to detect an overflow.
 
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index 1873b1a..f5c5863 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -157,13 +157,44 @@ elf32_sparc_final_write_processing (bfd *abfd,
     }
 }
 
+/* Used to decide how to sort relocs in an optimal manner for the
+   dynamic linker, before writing them out.  */
+
 static enum elf_reloc_type_class
-elf32_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf32_sparc_reloc_type_class (const struct bfd_link_info *info,
 			      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 _bfd_sparc_elf_link_hash_table *htab
+    = _bfd_sparc_elf_hash_table (info);
+  BFD_ASSERT (htab != NULL);
+
+  if (htab->elf.dynsym != NULL
+      && htab->elf.dynsym->contents != NULL)
+    {
+      /* Check relocation against STT_GNU_IFUNC symbol if there are
+	 dynamic symbols.  */
+      unsigned long r_symndx = htab->r_symndx (rela->r_info);
+      if (r_symndx != STN_UNDEF)
+	{
+	  Elf_Internal_Sym sym;
+	  if (!bed->s->swap_symbol_in (abfd,
+				       (htab->elf.dynsym->contents
+					+ r_symndx * bed->s->sizeof_sym),
+				       0, &sym))
+	    abort ();
+
+	  if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+	    return reloc_class_ifunc;
+	}
+    }
+
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
+    case R_SPARC_IRELATIVE:
+      return reloc_class_ifunc;
     case R_SPARC_RELATIVE:
       return reloc_class_relative;
     case R_SPARC_JMP_SLOT:
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 7de32c9..bd29be3 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -769,13 +769,44 @@ elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, void * filep,
     return symbol->name;
 }
 
+/* Used to decide how to sort relocs in an optimal manner for the
+   dynamic linker, before writing them out.  */
+
 static enum elf_reloc_type_class
-elf64_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf64_sparc_reloc_type_class (const struct bfd_link_info *info,
 			      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 _bfd_sparc_elf_link_hash_table *htab
+    = _bfd_sparc_elf_hash_table (info);
+  BFD_ASSERT (htab != NULL);
+
+  if (htab->elf.dynsym != NULL
+      && htab->elf.dynsym->contents != NULL)
+    {
+      /* Check relocation against STT_GNU_IFUNC symbol if there are
+	 dynamic symbols.  */
+      unsigned long r_symndx = htab->r_symndx (rela->r_info);
+      if (r_symndx != STN_UNDEF)
+	{
+	  Elf_Internal_Sym sym;
+	  if (!bed->s->swap_symbol_in (abfd,
+				       (htab->elf.dynsym->contents
+					+ r_symndx * bed->s->sizeof_sym),
+				       0, &sym))
+	    abort ();
+
+	  if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+	    return reloc_class_ifunc;
+	}
+    }
+
   switch ((int) ELF64_R_TYPE (rela->r_info))
     {
+    case R_SPARC_IRELATIVE:
+      return reloc_class_ifunc;
     case R_SPARC_RELATIVE:
       return reloc_class_relative;
     case R_SPARC_JMP_SLOT:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]