mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 13:56:22 +08:00
Fix performance regression on x86 with ld -r
Similar fix to "commit c316a17c40e44e8798b34ff84130904f2e7a53de". * elf32-i386.c (elf_i386_relocate_section): Use read and write pointers to reloc array, rather than memmove when deleting a reloc. Don't use RELOC_AGAINST_DISCARDED_SECTION. Adjust reloc counts at end of loop. * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2015-11-09 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* elf32-i386.c (elf_i386_relocate_section): Use read and write
|
||||||
|
pointers to reloc array, rather than memmove when deleting a
|
||||||
|
reloc. Don't use RELOC_AGAINST_DISCARDED_SECTION. Adjust
|
||||||
|
reloc counts at end of loop.
|
||||||
|
* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
|
||||||
|
|
||||||
2015-11-10 Alan Modra <amodra@gmail.com>
|
2015-11-10 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf64-ppc.c (ppc64_elf_relocate_section): Use read and write
|
* elf64-ppc.c (ppc64_elf_relocate_section): Use read and write
|
||||||
|
@ -3599,6 +3599,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
bfd_vma *local_got_offsets;
|
bfd_vma *local_got_offsets;
|
||||||
bfd_vma *local_tlsdesc_gotents;
|
bfd_vma *local_tlsdesc_gotents;
|
||||||
Elf_Internal_Rela *rel;
|
Elf_Internal_Rela *rel;
|
||||||
|
Elf_Internal_Rela *wrel;
|
||||||
Elf_Internal_Rela *relend;
|
Elf_Internal_Rela *relend;
|
||||||
bfd_boolean is_vxworks_tls;
|
bfd_boolean is_vxworks_tls;
|
||||||
unsigned plt_entry_size;
|
unsigned plt_entry_size;
|
||||||
@ -3623,9 +3624,9 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
|
plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
|
||||||
|
|
||||||
rel = relocs;
|
rel = wrel = relocs;
|
||||||
relend = relocs + input_section->reloc_count;
|
relend = relocs + input_section->reloc_count;
|
||||||
for (; rel < relend; rel++)
|
for (; rel < relend; wrel++, rel++)
|
||||||
{
|
{
|
||||||
unsigned int r_type;
|
unsigned int r_type;
|
||||||
reloc_howto_type *howto;
|
reloc_howto_type *howto;
|
||||||
@ -3772,8 +3773,22 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sec != NULL && discarded_section (sec))
|
if (sec != NULL && discarded_section (sec))
|
||||||
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
|
{
|
||||||
rel, 1, relend, howto, 0, contents);
|
_bfd_clear_contents (howto, input_bfd, input_section,
|
||||||
|
contents + rel->r_offset);
|
||||||
|
wrel->r_offset = rel->r_offset;
|
||||||
|
wrel->r_info = 0;
|
||||||
|
wrel->r_addend = 0;
|
||||||
|
|
||||||
|
/* For ld -r, remove relocations in debug sections against
|
||||||
|
sections defined in discarded sections. Not done for
|
||||||
|
eh_frame editing code expects to be present. */
|
||||||
|
if (bfd_link_relocatable (info)
|
||||||
|
&& (input_section->flags & SEC_DEBUGGING))
|
||||||
|
wrel--;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bfd_link_relocatable (info))
|
if (bfd_link_relocatable (info))
|
||||||
continue;
|
continue;
|
||||||
@ -4365,6 +4380,7 @@ r_386_got32:
|
|||||||
contents + roff);
|
contents + roff);
|
||||||
/* Skip R_386_PC32/R_386_PLT32. */
|
/* Skip R_386_PC32/R_386_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
||||||
@ -4704,6 +4720,7 @@ r_386_got32:
|
|||||||
contents + roff + 8);
|
contents + roff + 8);
|
||||||
/* Skip R_386_PLT32. */
|
/* Skip R_386_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
||||||
@ -4801,6 +4818,7 @@ r_386_got32:
|
|||||||
"\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
|
"\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
|
||||||
/* Skip R_386_PC32/R_386_PLT32. */
|
/* Skip R_386_PC32/R_386_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4942,6 +4960,29 @@ check_relocation_error:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wrel != rel)
|
||||||
|
*wrel = *rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrel != rel)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *rel_hdr;
|
||||||
|
size_t deleted = rel - wrel;
|
||||||
|
|
||||||
|
rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
|
||||||
|
rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
|
||||||
|
if (rel_hdr->sh_size == 0)
|
||||||
|
{
|
||||||
|
/* It is too late to remove an empty reloc section. Leave
|
||||||
|
one NONE reloc.
|
||||||
|
??? What is wrong with an empty section??? */
|
||||||
|
rel_hdr->sh_size = rel_hdr->sh_entsize;
|
||||||
|
deleted -= 1;
|
||||||
|
}
|
||||||
|
rel_hdr = _bfd_elf_single_rel_hdr (input_section);
|
||||||
|
rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
|
||||||
|
input_section->reloc_count -= deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -3866,6 +3866,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
bfd_vma *local_got_offsets;
|
bfd_vma *local_got_offsets;
|
||||||
bfd_vma *local_tlsdesc_gotents;
|
bfd_vma *local_tlsdesc_gotents;
|
||||||
Elf_Internal_Rela *rel;
|
Elf_Internal_Rela *rel;
|
||||||
|
Elf_Internal_Rela *wrel;
|
||||||
Elf_Internal_Rela *relend;
|
Elf_Internal_Rela *relend;
|
||||||
const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
|
const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
|
||||||
|
|
||||||
@ -3881,9 +3882,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
elf_x86_64_set_tls_module_base (info);
|
elf_x86_64_set_tls_module_base (info);
|
||||||
|
|
||||||
rel = relocs;
|
rel = wrel = relocs;
|
||||||
relend = relocs + input_section->reloc_count;
|
relend = relocs + input_section->reloc_count;
|
||||||
for (; rel < relend; rel++)
|
for (; rel < relend; wrel++, rel++)
|
||||||
{
|
{
|
||||||
unsigned int r_type;
|
unsigned int r_type;
|
||||||
reloc_howto_type *howto;
|
reloc_howto_type *howto;
|
||||||
@ -3961,8 +3962,22 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sec != NULL && discarded_section (sec))
|
if (sec != NULL && discarded_section (sec))
|
||||||
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
|
{
|
||||||
rel, 1, relend, howto, 0, contents);
|
_bfd_clear_contents (howto, input_bfd, input_section,
|
||||||
|
contents + rel->r_offset);
|
||||||
|
wrel->r_offset = rel->r_offset;
|
||||||
|
wrel->r_info = 0;
|
||||||
|
wrel->r_addend = 0;
|
||||||
|
|
||||||
|
/* For ld -r, remove relocations in debug sections against
|
||||||
|
sections defined in discarded sections. Not done for
|
||||||
|
eh_frame editing code expects to be present. */
|
||||||
|
if (bfd_link_relocatable (info)
|
||||||
|
&& (input_section->flags & SEC_DEBUGGING))
|
||||||
|
wrel--;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bfd_link_relocatable (info))
|
if (bfd_link_relocatable (info))
|
||||||
continue;
|
continue;
|
||||||
@ -4782,6 +4797,7 @@ direct:
|
|||||||
contents + roff + 8 + largepic);
|
contents + roff + 8 + largepic);
|
||||||
/* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
/* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
||||||
@ -5064,6 +5080,7 @@ direct:
|
|||||||
contents + roff + 8 + largepic);
|
contents + roff + 8 + largepic);
|
||||||
/* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
/* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
||||||
@ -5148,6 +5165,7 @@ direct:
|
|||||||
"\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
|
"\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
|
||||||
/* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
/* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
|
||||||
rel++;
|
rel++;
|
||||||
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5264,6 +5282,29 @@ check_relocation_error:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wrel != rel)
|
||||||
|
*wrel = *rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrel != rel)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *rel_hdr;
|
||||||
|
size_t deleted = rel - wrel;
|
||||||
|
|
||||||
|
rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
|
||||||
|
rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
|
||||||
|
if (rel_hdr->sh_size == 0)
|
||||||
|
{
|
||||||
|
/* It is too late to remove an empty reloc section. Leave
|
||||||
|
one NONE reloc.
|
||||||
|
??? What is wrong with an empty section??? */
|
||||||
|
rel_hdr->sh_size = rel_hdr->sh_entsize;
|
||||||
|
deleted -= 1;
|
||||||
|
}
|
||||||
|
rel_hdr = _bfd_elf_single_rel_hdr (input_section);
|
||||||
|
rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
|
||||||
|
input_section->reloc_count -= deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Reference in New Issue
Block a user