aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-rx.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-12-07 14:43:47 +0000
committerNick Clifton <nickc@redhat.com>2015-12-07 14:43:47 +0000
commit5ee4a06adea76e607f47eceff65c6bd4a98c49ff (patch)
treee78fa3d9931b461b2ffd30b17fdbb0733f582b4d /bfd/elf32-rx.c
parentd72413e64a3444868e72e315ba2ceaf5a9d2bf6f (diff)
downloadfsf-binutils-gdb-5ee4a06adea76e607f47eceff65c6bd4a98c49ff.zip
fsf-binutils-gdb-5ee4a06adea76e607f47eceff65c6bd4a98c49ff.tar.gz
fsf-binutils-gdb-5ee4a06adea76e607f47eceff65c6bd4a98c49ff.tar.bz2
Fix relaxation in RX linker when --no-keep-memory is specified.
* elf32-rx.c (elf32_rx_relax_delete_bytes): Add extra parameter - the start of the relocs for the section. Delete code to load in the relocs. (elf32_rx_relax_section): Do not free the loaded relocs.
Diffstat (limited to 'bfd/elf32-rx.c')
-rw-r--r--bfd/elf32-rx.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c
index c58c184..004d7c2 100644
--- a/bfd/elf32-rx.c
+++ b/bfd/elf32-rx.c
@@ -1531,7 +1531,8 @@ next_smaller_reloc (int r)
static bfd_boolean
elf32_rx_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
- Elf_Internal_Rela *alignment_rel, int force_snip)
+ Elf_Internal_Rela *alignment_rel, int force_snip,
+ Elf_Internal_Rela *irelstart)
{
Elf_Internal_Shdr * symtab_hdr;
unsigned int sec_shndx;
@@ -1558,20 +1559,7 @@ elf32_rx_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
if (alignment_rel)
toaddr = alignment_rel->r_offset;
- irel = elf_section_data (sec)->relocs;
- irelend = irel + sec->reloc_count;
-
- if (irel == NULL && sec->reloc_count > 0)
- {
- /* If the relocs have not been kept in the section data
- structure (because -no-keep-memory was used) then
- reread them now. */
- irel = (_bfd_elf_link_read_relocs
- (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, FALSE));
- if (irel == NULL)
- /* FIXME: Return FALSE instead ? */
- irelend = irel;
- }
+ BFD_ASSERT (toaddr > addr);
/* Actually delete the bytes. */
memmove (contents + addr, contents + addr + count,
@@ -1585,6 +1573,10 @@ elf32_rx_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
else
memset (contents + toaddr - count, 0x03, count);
+ irel = irelstart;
+ BFD_ASSERT (irel != NULL || sec->reloc_count == 0);
+ irelend = irel + sec->reloc_count;
+
/* Adjust all the relocs. */
for (; irel < irelend; irel++)
{
@@ -1977,7 +1969,6 @@ elf32_rx_relax_section (bfd * abfd,
Elf_Internal_Shdr * symtab_hdr;
Elf_Internal_Shdr * shndx_hdr;
Elf_Internal_Rela * internal_relocs;
- Elf_Internal_Rela * free_relocs = NULL;
Elf_Internal_Rela * irel;
Elf_Internal_Rela * srel;
Elf_Internal_Rela * irelend;
@@ -2054,13 +2045,15 @@ elf32_rx_relax_section (bfd * abfd,
}
/* Get a copy of the native relocations. */
- internal_relocs = (_bfd_elf_link_read_relocs
- (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
- link_info->keep_memory));
+ /* Note - we ignore the setting of link_info->keep_memory when reading
+ in these relocs. We have to maintain a permanent copy of the relocs
+ because we are going to walk over them multiple times, adjusting them
+ as bytes are deleted from the section, and with this relaxation
+ function itself being called multiple times on the same section... */
+ internal_relocs = _bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, TRUE);
if (internal_relocs == NULL)
goto error_return;
- if (! link_info->keep_memory)
- free_relocs = internal_relocs;
/* The RL_ relocs must be just before the operand relocs they go
with, so we must sort them to guarantee this. We use bubblesort
@@ -2150,7 +2143,7 @@ elf32_rx_relax_section (bfd * abfd,
nbytes *= alignment;
elf32_rx_relax_delete_bytes (abfd, sec, erel->r_offset-nbytes, nbytes, next_alignment,
- erel->r_offset == sec->size);
+ erel->r_offset == sec->size, internal_relocs);
*again = TRUE;
continue;
@@ -2189,7 +2182,7 @@ elf32_rx_relax_section (bfd * abfd,
nrelocs --;
#define SNIPNR(offset, nbytes) \
- elf32_rx_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
+ elf32_rx_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0, internal_relocs);
#define SNIP(offset, nbytes, newtype) \
SNIPNR (offset, nbytes); \
srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
@@ -3009,9 +3002,6 @@ elf32_rx_relax_section (bfd * abfd,
return TRUE;
error_return:
- if (free_relocs != NULL)
- free (free_relocs);
-
if (free_contents != NULL)
free (free_contents);