mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-01 09:49:43 +08:00
ld -z combreloc elf_link_sort_relocs
A linker script may put .rela.plt in with other .rela.dyn relocs. The change to elf_reloc_type_class puts any PLT relocs last. This patch makes the input section layout better match the sorted relocs. * elflink.c (elf_link_sort_relocs): Wrap overlong lines. Fix octets_per_byte. Put dynamic .rela.plt last in link orders. Assign output_offset for reloc sections rather than writing sorted relocs from block corresponding to output_offset.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2016-05-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elflink.c (elf_link_sort_relocs): Wrap overlong lines. Fix
|
||||||
|
octets_per_byte. Put dynamic .rela.plt last in link orders.
|
||||||
|
Assign output_offset for reloc sections rather than writing
|
||||||
|
sorted relocs from block corresponding to output_offset.
|
||||||
|
|
||||||
2016-05-12 Alan Modra <amodra@gmail.com>
|
2016-05-12 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf-bfd.h (elf_reloc_type_class): Put reloc_class_plt last.
|
* elf-bfd.h (elf_reloc_type_class): Put reloc_class_plt last.
|
||||||
|
@ -8526,6 +8526,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
struct elf_link_sort_rela *sq;
|
struct elf_link_sort_rela *sq;
|
||||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
int i2e = bed->s->int_rels_per_ext_rel;
|
int i2e = bed->s->int_rels_per_ext_rel;
|
||||||
|
unsigned int opb = bfd_octets_per_byte (abfd);
|
||||||
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
||||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||||
struct bfd_link_order *lo;
|
struct bfd_link_order *lo;
|
||||||
@ -8541,7 +8542,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
bfd_boolean use_rela_initialised = FALSE;
|
bfd_boolean use_rela_initialised = FALSE;
|
||||||
|
|
||||||
/* This is just here to stop gcc from complaining.
|
/* This is just here to stop gcc from complaining.
|
||||||
It's initialization checking code is not perfect. */
|
Its initialization checking code is not perfect. */
|
||||||
use_rela = TRUE;
|
use_rela = TRUE;
|
||||||
|
|
||||||
/* Both sections are present. Examine the sizes
|
/* Both sections are present. Examine the sizes
|
||||||
@ -8562,8 +8563,9 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
/* Section size is only divisible by rela. */
|
/* Section size is only divisible by rela. */
|
||||||
if (use_rela_initialised && (use_rela == FALSE))
|
if (use_rela_initialised && (use_rela == FALSE))
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
(_("%B: Unable to sort relocs - they are in more than one size"), abfd);
|
"they are in more than one size"),
|
||||||
|
abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8579,8 +8581,9 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
/* Section size is only divisible by rel. */
|
/* Section size is only divisible by rel. */
|
||||||
if (use_rela_initialised && (use_rela == TRUE))
|
if (use_rela_initialised && (use_rela == TRUE))
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
(_("%B: Unable to sort relocs - they are in more than one size"), abfd);
|
"they are in more than one size"),
|
||||||
|
abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8592,9 +8595,10 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The section size is not divisible by either - something is wrong. */
|
/* The section size is not divisible by either -
|
||||||
_bfd_error_handler
|
something is wrong. */
|
||||||
(_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
|
"they are of an unknown size"), abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8616,8 +8620,9 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
/* Section size is only divisible by rela. */
|
/* Section size is only divisible by rela. */
|
||||||
if (use_rela_initialised && (use_rela == FALSE))
|
if (use_rela_initialised && (use_rela == FALSE))
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
(_("%B: Unable to sort relocs - they are in more than one size"), abfd);
|
"they are in more than one size"),
|
||||||
|
abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8633,8 +8638,9 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
/* Section size is only divisible by rel. */
|
/* Section size is only divisible by rel. */
|
||||||
if (use_rela_initialised && (use_rela == TRUE))
|
if (use_rela_initialised && (use_rela == TRUE))
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
(_("%B: Unable to sort relocs - they are in more than one size"), abfd);
|
"they are in more than one size"),
|
||||||
|
abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8646,9 +8652,10 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The section size is not divisible by either - something is wrong. */
|
/* The section size is not divisible by either -
|
||||||
_bfd_error_handler
|
something is wrong. */
|
||||||
(_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
|
_bfd_error_handler (_("%B: Unable to sort relocs - "
|
||||||
|
"they are of an unknown size"), abfd);
|
||||||
bfd_set_error (bfd_error_invalid_operation);
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8724,8 +8731,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
}
|
}
|
||||||
erel = o->contents;
|
erel = o->contents;
|
||||||
erelend = o->contents + o->size;
|
erelend = o->contents + o->size;
|
||||||
/* FIXME: octets_per_byte. */
|
p = sort + o->output_offset * opb / ext_size * sort_elt;
|
||||||
p = sort + o->output_offset / ext_size * sort_elt;
|
|
||||||
|
|
||||||
while (erel < erelend)
|
while (erel < erelend)
|
||||||
{
|
{
|
||||||
@ -8761,6 +8767,35 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
|
|
||||||
qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
|
qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
|
||||||
|
|
||||||
|
struct elf_link_hash_table *htab = elf_hash_table (info);
|
||||||
|
if (htab->srelplt && htab->srelplt->output_section == dynamic_relocs)
|
||||||
|
{
|
||||||
|
/* We have plt relocs in .rela.dyn. */
|
||||||
|
sq = (struct elf_link_sort_rela *) sort;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
if (sq[count - i - 1].type != reloc_class_plt)
|
||||||
|
break;
|
||||||
|
if (i != 0 && htab->srelplt->size == i * ext_size)
|
||||||
|
{
|
||||||
|
struct bfd_link_order **plo;
|
||||||
|
/* Put srelplt link_order last. This is so the output_offset
|
||||||
|
set in the next loop is correct for DT_JMPREL. */
|
||||||
|
for (plo = &dynamic_relocs->map_head.link_order; *plo != NULL; )
|
||||||
|
if ((*plo)->type == bfd_indirect_link_order
|
||||||
|
&& (*plo)->u.indirect.section == htab->srelplt)
|
||||||
|
{
|
||||||
|
lo = *plo;
|
||||||
|
*plo = lo->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
plo = &(*plo)->next;
|
||||||
|
*plo = lo;
|
||||||
|
lo->next = NULL;
|
||||||
|
dynamic_relocs->map_tail.link_order = lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = sort;
|
||||||
for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
|
for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
|
||||||
if (lo->type == bfd_indirect_link_order)
|
if (lo->type == bfd_indirect_link_order)
|
||||||
{
|
{
|
||||||
@ -8769,8 +8804,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
|
|
||||||
erel = o->contents;
|
erel = o->contents;
|
||||||
erelend = o->contents + o->size;
|
erelend = o->contents + o->size;
|
||||||
/* FIXME: octets_per_byte. */
|
o->output_offset = (p - sort) / sort_elt * ext_size / opb;
|
||||||
p = sort + o->output_offset / ext_size * sort_elt;
|
|
||||||
while (erel < erelend)
|
while (erel < erelend)
|
||||||
{
|
{
|
||||||
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
|
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
|
||||||
|
Reference in New Issue
Block a user