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:14:00 +0100 |
commit | 1532a937c64105681d74055389f0e846244fb830 (patch) | |
tree | 5439fcb9dd58f3b6d818f5a4a0ac6fdb3c117749 /bfd | |
parent | 1c92e98f548b70b08f01cf512ed755ef84e6f223 (diff) | |
download | fsf-binutils-gdb-1532a937c64105681d74055389f0e846244fb830.zip fsf-binutils-gdb-1532a937c64105681d74055389f0e846244fb830.tar.gz fsf-binutils-gdb-1532a937c64105681d74055389f0e846244fb830.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')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-sparc.c | 33 | ||||
-rw-r--r-- | bfd/elf64-sparc.c | 33 |
3 files changed, 71 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 75ed014..45c24e1 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 4378b61..80e807f 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 8c45d32..86004d1 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -784,13 +784,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: |