Don't sort ld -r relocs for mips

HI16/LO16 are deliberately put adjacent, which might mean relocs are
then not sorted by r_offset.  See tc-mips.c:mips_frob_file.  Don't undo
the HI16/LO16 sorting.

	PR 17666
	* elf-bfd.h (struct elf_backend_data): Add sort_relocs_p.
	* elfxx-target.h (elf_backend_sort_relocs_p): Define.
	(elfNN_bed): Init new field.
	* elflink.c (elf_link_adjust_relocs): Conditionally sort.
	(bfd_elf_final_link): Control sorting of relocs.
	* elfxx-mips.c (_bfd_mips_elf_sort_relocs_p): New function.
	* elfxx-mips.h (_bfd_mips_elf_sort_relocs_p): Declare.
	* elf32-mips.c (elf_backend_sort_relocs_p): Define.
	* elf64-mips.c (elf_backend_sort_relocs_p): Define.
This commit is contained in:
Alan Modra 2014-12-09 14:32:22 +10:30
parent 4e3272393f
commit 28dbcedc7b
8 changed files with 68 additions and 22 deletions

View File

@ -1,3 +1,16 @@
2014-12-10 Alan Modra <amodra@gmail.com>
PR 17666
* elf-bfd.h (struct elf_backend_data): Add sort_relocs_p.
* elfxx-target.h (elf_backend_sort_relocs_p): Define.
(elfNN_bed): Init new field.
* elflink.c (elf_link_adjust_relocs): Conditionally sort.
(bfd_elf_final_link): Control sorting of relocs.
* elfxx-mips.c (_bfd_mips_elf_sort_relocs_p): New function.
* elfxx-mips.h (_bfd_mips_elf_sort_relocs_p): Declare.
* elf32-mips.c (elf_backend_sort_relocs_p): Define.
* elf64-mips.c (elf_backend_sort_relocs_p): Define.
2014-12-09 Nick Clifton <nickc@redhat.com> 2014-12-09 Nick Clifton <nickc@redhat.com>
PR binutils/17512 PR binutils/17512

View File

@ -1109,6 +1109,11 @@ struct elf_backend_data
unsigned int (*elf_backend_count_relocs) unsigned int (*elf_backend_count_relocs)
(struct bfd_link_info *, asection *); (struct bfd_link_info *, asection *);
/* Say whether to sort relocs output by ld -r and ld --emit-relocs,
by r_offset. If NULL, default to true. */
bfd_boolean (*sort_relocs_p)
(asection *);
/* This function, if defined, is called when an NT_PRSTATUS note is found /* This function, if defined, is called when an NT_PRSTATUS note is found
in a core file. */ in a core file. */
bfd_boolean (*elf_backend_grok_prstatus) bfd_boolean (*elf_backend_grok_prstatus)

View File

@ -2473,6 +2473,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define elf_backend_write_section _bfd_mips_elf_write_section #define elf_backend_write_section _bfd_mips_elf_write_section
#define elf_backend_mips_irix_compat elf32_mips_irix_compat #define elf_backend_mips_irix_compat elf32_mips_irix_compat
#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
#define elf_backend_sort_relocs_p _bfd_mips_elf_sort_relocs_p
#define bfd_elf32_bfd_is_local_label_name \ #define bfd_elf32_bfd_is_local_label_name \
mips_elf_is_local_label_name mips_elf_is_local_label_name
#define bfd_elf32_bfd_is_target_special_symbol \ #define bfd_elf32_bfd_is_target_special_symbol \

View File

@ -4444,6 +4444,7 @@ const struct elf_size_info mips_elf64_size_info =
#define elf_backend_sign_extend_vma TRUE #define elf_backend_sign_extend_vma TRUE
#define elf_backend_write_section _bfd_mips_elf_write_section #define elf_backend_write_section _bfd_mips_elf_write_section
#define elf_backend_sort_relocs_p _bfd_mips_elf_sort_relocs_p
/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
MIPS-specific function only applies to IRIX5, which had no 64-bit MIPS-specific function only applies to IRIX5, which had no 64-bit

View File

@ -8097,7 +8097,8 @@ cmp_ext64b_r_offset (const void *p, const void *q)
static void static void
elf_link_adjust_relocs (bfd *abfd, elf_link_adjust_relocs (bfd *abfd,
struct bfd_elf_section_reloc_data *reldata) struct bfd_elf_section_reloc_data *reldata,
bfd_boolean sort)
{ {
unsigned int i; unsigned int i;
const struct elf_backend_data *bed = get_elf_backend_data (abfd); const struct elf_backend_data *bed = get_elf_backend_data (abfd);
@ -8108,7 +8109,6 @@ elf_link_adjust_relocs (bfd *abfd,
int r_sym_shift; int r_sym_shift;
unsigned int count = reldata->count; unsigned int count = reldata->count;
struct elf_link_hash_entry **rel_hash = reldata->hashes; struct elf_link_hash_entry **rel_hash = reldata->hashes;
int (*compare) (const void *, const void *);
if (reldata->hdr->sh_entsize == bed->s->sizeof_rel) if (reldata->hdr->sh_entsize == bed->s->sizeof_rel)
{ {
@ -8155,29 +8155,34 @@ elf_link_adjust_relocs (bfd *abfd,
(*swap_out) (abfd, irela, erela); (*swap_out) (abfd, irela, erela);
} }
if (bed->s->arch_size == 32) if (sort)
{ {
if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE) int (*compare) (const void *, const void *);
compare = cmp_ext32l_r_offset;
else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) if (bed->s->arch_size == 32)
compare = cmp_ext32b_r_offset; {
if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
compare = cmp_ext32l_r_offset;
else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
compare = cmp_ext32b_r_offset;
else
abort ();
}
else else
abort (); {
}
else
{
#ifdef BFD_HOST_64_BIT #ifdef BFD_HOST_64_BIT
if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE) if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
compare = cmp_ext64l_r_offset; compare = cmp_ext64l_r_offset;
else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
compare = cmp_ext64b_r_offset; compare = cmp_ext64b_r_offset;
else else
#endif #endif
abort (); abort ();
}
qsort (reldata->hdr->contents, count, reldata->hdr->sh_entsize, compare);
free (reldata->hashes);
reldata->hashes = NULL;
} }
qsort (reldata->hdr->contents, count, reldata->hdr->sh_entsize, compare);
free (reldata->hashes);
reldata->hashes = NULL;
} }
struct elf_link_sort_rela struct elf_link_sort_rela
@ -11325,13 +11330,15 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
for (o = abfd->sections; o != NULL; o = o->next) for (o = abfd->sections; o != NULL; o = o->next)
{ {
struct bfd_elf_section_data *esdo = elf_section_data (o); struct bfd_elf_section_data *esdo = elf_section_data (o);
bfd_boolean sort;
if ((o->flags & SEC_RELOC) == 0) if ((o->flags & SEC_RELOC) == 0)
continue; continue;
sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o);
if (esdo->rel.hdr != NULL) if (esdo->rel.hdr != NULL)
elf_link_adjust_relocs (abfd, &esdo->rel); elf_link_adjust_relocs (abfd, &esdo->rel, sort);
if (esdo->rela.hdr != NULL) if (esdo->rela.hdr != NULL)
elf_link_adjust_relocs (abfd, &esdo->rela); elf_link_adjust_relocs (abfd, &esdo->rela, sort);
/* Set the reloc_count field to 0 to prevent write_relocs from /* Set the reloc_count field to 0 to prevent write_relocs from
trying to swap the relocs out itself. */ trying to swap the relocs out itself. */

View File

@ -11912,6 +11912,18 @@ mips_set_isa_flags (bfd *abfd)
} }
/* Whether to sort relocs output by ld -r or ld --emit-relocs, by r_offset.
Don't do so for code sections. We want to keep ordering of HI16/LO16
as is. On the other hand, elf-eh-frame.c processing requires .eh_frame
relocs to be sorted. */
bfd_boolean
_bfd_mips_elf_sort_relocs_p (asection *sec)
{
return (sec->flags & SEC_CODE) == 0;
}
/* The final processing done just before writing out a MIPS ELF object /* The final processing done just before writing out a MIPS ELF object
file. This gets the MIPS architecture right based on the machine file. This gets the MIPS architecture right based on the machine
number. This is used by both the 32-bit and the 64-bit ABI. */ number. This is used by both the 32-bit and the 64-bit ABI. */

View File

@ -67,6 +67,8 @@ extern bfd_boolean _bfd_mips_vxworks_finish_dynamic_symbol
Elf_Internal_Sym *); Elf_Internal_Sym *);
extern bfd_boolean _bfd_mips_elf_finish_dynamic_sections extern bfd_boolean _bfd_mips_elf_finish_dynamic_sections
(bfd *, struct bfd_link_info *); (bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_mips_elf_sort_relocs_p
(asection *);
extern void _bfd_mips_elf_final_write_processing extern void _bfd_mips_elf_final_write_processing
(bfd *, bfd_boolean); (bfd *, bfd_boolean);
extern int _bfd_mips_elf_additional_program_headers extern int _bfd_mips_elf_additional_program_headers

View File

@ -535,6 +535,9 @@
#ifndef elf_backend_count_relocs #ifndef elf_backend_count_relocs
#define elf_backend_count_relocs NULL #define elf_backend_count_relocs NULL
#endif #endif
#ifndef elf_backend_sort_relocs_p
#define elf_backend_sort_relocs_p NULL
#endif
#ifndef elf_backend_grok_prstatus #ifndef elf_backend_grok_prstatus
#define elf_backend_grok_prstatus NULL #define elf_backend_grok_prstatus NULL
#endif #endif
@ -737,6 +740,7 @@ static struct elf_backend_data elfNN_bed =
elf_backend_ignore_undef_symbol, elf_backend_ignore_undef_symbol,
elf_backend_emit_relocs, elf_backend_emit_relocs,
elf_backend_count_relocs, elf_backend_count_relocs,
elf_backend_sort_relocs_p,
elf_backend_grok_prstatus, elf_backend_grok_prstatus,
elf_backend_grok_psinfo, elf_backend_grok_psinfo,
elf_backend_write_core_note, elf_backend_write_core_note,