diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2019-02-07 17:04:31 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2019-02-07 17:04:31 +0100 |
commit | b2abe1bd8149dd9ad64432f620c3a034bf23a5fe (patch) | |
tree | 0e8ab9fa20f8319b7a2fff77200f3c797c17a608 /bfd/elf32-sparc.c | |
parent | 68a091326f6ac25005c49c4cbda1855080ba1d5f (diff) | |
download | gdb-b2abe1bd8149dd9ad64432f620c3a034bf23a5fe.zip gdb-b2abe1bd8149dd9ad64432f620c3a034bf23a5fe.tar.gz gdb-b2abe1bd8149dd9ad64432f620c3a034bf23a5fe.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf32-sparc.c')
-rw-r--r-- | bfd/elf32-sparc.c | 33 |
1 files changed, 32 insertions, 1 deletions
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: |