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.
This commit is contained in:
Nick Clifton 2015-12-07 14:43:47 +00:00
parent d72413e64a
commit 5ee4a06ade
1 changed files with 16 additions and 26 deletions

View File

@ -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);