bfd: fix the deletion of relocs in sparc64
This patch fixes the deletion of relocations in BFD sections in sparc64 targets. A specialized `_bfd_set_reloc' function is provided that updates the internal canon_reloc_count(sec) counter instead of sec->reloc_count. Additionally, the `write_relocs' callback in elf64-sparc is adapted to use the canon_reloc_count to traverse `sec->orelocation'. Tested in sparc64-linux-gnu targets. Fixes an existing failure in the merge-notes objcopy test. No regressions. bfd/ChangeLog: 2017-05-10 Jose E. Marchesi <jose.marchesi@oracle.com> * elf64-sparc.c (elf64_sparc_set_reloc): New function. (bfd_elf64_set_reloc): Define. (elf64_sparc_write_relocs): Use `canon_reloc_count'.
This commit is contained in:
parent
2318686590
commit
db84b98a16
2 changed files with 25 additions and 5 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2017-05-10 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
|
* elf64-sparc.c (elf64_sparc_set_reloc): New function.
|
||||||
|
(bfd_elf64_set_reloc): Define.
|
||||||
|
(elf64_sparc_write_relocs): Use `canon_reloc_count'.
|
||||||
|
|
||||||
2017-05-10 Jose E. Marchesi <jose.marchesi@oracle.com>
|
2017-05-10 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
* targets.c (BFD_JUMP_TABLE_RELOCS): Add NAME##_set_reloc.
|
* targets.c (BFD_JUMP_TABLE_RELOCS): Add NAME##_set_reloc.
|
||||||
|
|
|
@ -278,6 +278,18 @@ elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Install a new set of internal relocs. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf64_sparc_set_reloc (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
|
asection *asect,
|
||||||
|
arelent **location,
|
||||||
|
unsigned int count)
|
||||||
|
{
|
||||||
|
asect->orelocation = location;
|
||||||
|
canon_reloc_count (asect) = count;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write out the relocs. */
|
/* Write out the relocs. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -302,14 +314,14 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
|
||||||
reloc_count field to zero to inhibit writing them here. Also,
|
reloc_count field to zero to inhibit writing them here. Also,
|
||||||
sometimes the SEC_RELOC flag gets set even when there aren't any
|
sometimes the SEC_RELOC flag gets set even when there aren't any
|
||||||
relocs. */
|
relocs. */
|
||||||
if (sec->reloc_count == 0)
|
if (canon_reloc_count (sec) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We can combine two relocs that refer to the same address
|
/* We can combine two relocs that refer to the same address
|
||||||
into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
|
into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
|
||||||
latter is R_SPARC_13 with no associated symbol. */
|
latter is R_SPARC_13 with no associated symbol. */
|
||||||
count = 0;
|
count = 0;
|
||||||
for (idx = 0; idx < sec->reloc_count; idx++)
|
for (idx = 0; idx < canon_reloc_count (sec); idx++)
|
||||||
{
|
{
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
|
|
||||||
|
@ -317,7 +329,7 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
|
||||||
|
|
||||||
addr = sec->orelocation[idx]->address;
|
addr = sec->orelocation[idx]->address;
|
||||||
if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
|
if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
|
||||||
&& idx < sec->reloc_count - 1)
|
&& idx < canon_reloc_count (sec) - 1)
|
||||||
{
|
{
|
||||||
arelent *r = sec->orelocation[idx + 1];
|
arelent *r = sec->orelocation[idx + 1];
|
||||||
|
|
||||||
|
@ -354,7 +366,7 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
|
||||||
outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
|
outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
|
||||||
src_rela = outbound_relocas;
|
src_rela = outbound_relocas;
|
||||||
|
|
||||||
for (idx = 0; idx < sec->reloc_count; idx++)
|
for (idx = 0; idx < canon_reloc_count (sec); idx++)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela dst_rela;
|
Elf_Internal_Rela dst_rela;
|
||||||
arelent *ptr;
|
arelent *ptr;
|
||||||
|
@ -388,7 +400,7 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->howto->type == R_SPARC_LO10
|
if (ptr->howto->type == R_SPARC_LO10
|
||||||
&& idx < sec->reloc_count - 1)
|
&& idx < canon_reloc_count (sec) - 1)
|
||||||
{
|
{
|
||||||
arelent *r = sec->orelocation[idx + 1];
|
arelent *r = sec->orelocation[idx + 1];
|
||||||
|
|
||||||
|
@ -854,6 +866,8 @@ const struct elf_size_info elf64_sparc_size_info =
|
||||||
elf64_sparc_canonicalize_reloc
|
elf64_sparc_canonicalize_reloc
|
||||||
#define bfd_elf64_canonicalize_dynamic_reloc \
|
#define bfd_elf64_canonicalize_dynamic_reloc \
|
||||||
elf64_sparc_canonicalize_dynamic_reloc
|
elf64_sparc_canonicalize_dynamic_reloc
|
||||||
|
#define bfd_elf64_set_reloc \
|
||||||
|
elf64_sparc_set_reloc
|
||||||
#define elf_backend_add_symbol_hook \
|
#define elf_backend_add_symbol_hook \
|
||||||
elf64_sparc_add_symbol_hook
|
elf64_sparc_add_symbol_hook
|
||||||
#define elf_backend_get_symbol_type \
|
#define elf_backend_get_symbol_type \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue