mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-18 03:27:52 +08:00
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:
@ -1531,7 +1531,8 @@ next_smaller_reloc (int r)
|
|||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf32_rx_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
|
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;
|
Elf_Internal_Shdr * symtab_hdr;
|
||||||
unsigned int sec_shndx;
|
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)
|
if (alignment_rel)
|
||||||
toaddr = alignment_rel->r_offset;
|
toaddr = alignment_rel->r_offset;
|
||||||
|
|
||||||
irel = elf_section_data (sec)->relocs;
|
BFD_ASSERT (toaddr > addr);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Actually delete the bytes. */
|
/* Actually delete the bytes. */
|
||||||
memmove (contents + addr, contents + addr + count,
|
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
|
else
|
||||||
memset (contents + toaddr - count, 0x03, count);
|
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. */
|
/* Adjust all the relocs. */
|
||||||
for (; irel < irelend; irel++)
|
for (; irel < irelend; irel++)
|
||||||
{
|
{
|
||||||
@ -1977,7 +1969,6 @@ elf32_rx_relax_section (bfd * abfd,
|
|||||||
Elf_Internal_Shdr * symtab_hdr;
|
Elf_Internal_Shdr * symtab_hdr;
|
||||||
Elf_Internal_Shdr * shndx_hdr;
|
Elf_Internal_Shdr * shndx_hdr;
|
||||||
Elf_Internal_Rela * internal_relocs;
|
Elf_Internal_Rela * internal_relocs;
|
||||||
Elf_Internal_Rela * free_relocs = NULL;
|
|
||||||
Elf_Internal_Rela * irel;
|
Elf_Internal_Rela * irel;
|
||||||
Elf_Internal_Rela * srel;
|
Elf_Internal_Rela * srel;
|
||||||
Elf_Internal_Rela * irelend;
|
Elf_Internal_Rela * irelend;
|
||||||
@ -2054,13 +2045,15 @@ elf32_rx_relax_section (bfd * abfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get a copy of the native relocations. */
|
/* Get a copy of the native relocations. */
|
||||||
internal_relocs = (_bfd_elf_link_read_relocs
|
/* Note - we ignore the setting of link_info->keep_memory when reading
|
||||||
(abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
|
in these relocs. We have to maintain a permanent copy of the relocs
|
||||||
link_info->keep_memory));
|
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)
|
if (internal_relocs == NULL)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
if (! link_info->keep_memory)
|
|
||||||
free_relocs = internal_relocs;
|
|
||||||
|
|
||||||
/* The RL_ relocs must be just before the operand relocs they go
|
/* The RL_ relocs must be just before the operand relocs they go
|
||||||
with, so we must sort them to guarantee this. We use bubblesort
|
with, so we must sort them to guarantee this. We use bubblesort
|
||||||
@ -2150,7 +2143,7 @@ elf32_rx_relax_section (bfd * abfd,
|
|||||||
nbytes *= alignment;
|
nbytes *= alignment;
|
||||||
|
|
||||||
elf32_rx_relax_delete_bytes (abfd, sec, erel->r_offset-nbytes, nbytes, next_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;
|
*again = TRUE;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -2189,7 +2182,7 @@ elf32_rx_relax_section (bfd * abfd,
|
|||||||
nrelocs --;
|
nrelocs --;
|
||||||
|
|
||||||
#define SNIPNR(offset, nbytes) \
|
#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) \
|
#define SNIP(offset, nbytes, newtype) \
|
||||||
SNIPNR (offset, nbytes); \
|
SNIPNR (offset, nbytes); \
|
||||||
srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
|
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;
|
return TRUE;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
if (free_relocs != NULL)
|
|
||||||
free (free_relocs);
|
|
||||||
|
|
||||||
if (free_contents != NULL)
|
if (free_contents != NULL)
|
||||||
free (free_contents);
|
free (free_contents);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user