forked from Imagelibrary/binutils-gdb
bfd/
* elf-bfd.h (struct bfd_elf_section_reloc_data): New structure. (struct bfd_elf_section_data): New members REL and RELA; delete members REL_HDR, REL_HDR2, REL_COUNT, REL_COUNT2, REL_IDX, REL_IDX2, REL_HASHES. (_bfd_elf_init_reloc_shdr): Adjust declaration. (_bfd_elf_single_rel_hdr): Declare. (RELOC_AGAINST_DISCARDED_SECTION): Use it. * elf.c (bfd_section_from_shdr): Adjusted to match changes in data structures. (_bfd_elf_init_reloc_shdr): New arg RELDATA. Remove arg REL_HDR. All callers changed. Allocate memory for the Elf_Internal_Shdr structure. (_bfd_elf_single_rel_hdr): New function. (struct fake_section_arg): New structure. (elf_fake_section): Expect to see a pointer to it in the third argument. If doing a relocatable link, allocate both REL and RELA sections as needed. (assign_section_numbers): Adjusted to match changes in data structures. (_bfd_elf_compute_section_file_positions): Call elf_fake_sections with a struct fake_section_args argument. * elfcode.h (elf_write_relocs): Adjusted to match changes in data structures. (elf_slurp_reloc_table): Likewise. * elflink.c (_bfd_elf_link_read_relocs): Likewise. (_bfd_elf_link_size_reloc_section): Remove arg REL_HDR, replace with RELDATA. Remove argument O. All callers changed. Remove code to discover the right rel_hdr and count. (_bfd_elf_link_output_relocs): Adjusted to match changes in data structures. (elf_link_adjust_relocs): Remove args REL_HDR, COUNT and REL_HASH; replace with RELDATA. All callers changed. (elf_link_input_bfd): Correctly generate rel_hash data when both REL and RELA sections are present. (elf_reloc_link_order): Adjusted to match changes in data structures. (bfd_elf_final_link): Simplify code to count relocs. Free the hashes array for both REL and RELA. (get_dynamic_reloc_section_name): Use _bfd_elf_single_reloc_hdr * elf32-m32r.c (m32r_elf_fake_sections, elf_backend_fake_sections): Delete. * elf32-tic6x.c (elf32_tic6x_fake_sections, elf_backend_fake_sections): Delete. (elf32_tic6x_rel_relocation_p): Adjusted to match changes in data structures. * elf32-microblaze.c (microblaze_elf_check_relocs): Use _bfd_elf_single_rel_hdr. * elf32-ppc.c (ppc_elf_relax_section): Likewise. * elf32-spu.c (spu_elf_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_relocate_section): Likewise. * elf64-hppa.c (get_reloc_section): Likewise. * elf64-mips.c (mips_elf64_slurp_reloc_table): Adjusted to match changes in data structures. (mips_elf64_write_relocs): Use _bfd_elf_single_rel_hdr. * elf64-ppc.c (ppc64_elf_edit_opd): Likewise. (ppc64_elf_edit_toc): Likewise. (get_relocs): Adjusted to match changes in data structures. Allocate an Elf_Internal_Shdr structure if necessary. (ppc64_elf_finish_dynamic_sections): Use _bfd_elf_single_rel_hdr. * elf64-sparc.c (elf64_sparc_slurp_reloc_table): Adjusted to match changes in data structures. * elfxx-ia64.c (get_reloc_section): Use _bfd_elf_single_rel_hdr. * elfxx-mips.c (MIPS_RELOC_RELA_P): Remove macro. (mips_elf_rel_relocation_p): Adjusted to match changes in data structures. (_bfd_mips_elf_relocate_section): Use mips_elf_rel_relocation_p rather than MIPS_RELOC_RELOCA_P. * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Use _bfd_elf_single_rel_hdr. (_bfd_sparc_elf_relocate_section): Likewise. ld/ * emultempl/xtensaelf.em (replace_insn_sec_with_prop_sec): Use _bfd_elf_single_rel_hdr.
This commit is contained in:
327
bfd/elflink.c
327
bfd/elflink.c
@@ -2196,7 +2196,7 @@ elf_link_read_relocs_from_section (bfd *abfd,
|
||||
according to the KEEP_MEMORY argument. If O has two relocation
|
||||
sections (both REL and RELA relocations), then the REL_HDR
|
||||
relocations will appear first in INTERNAL_RELOCS, followed by the
|
||||
REL_HDR2 relocations. */
|
||||
RELA_HDR relocations. */
|
||||
|
||||
Elf_Internal_Rela *
|
||||
_bfd_elf_link_read_relocs (bfd *abfd,
|
||||
@@ -2205,19 +2205,18 @@ _bfd_elf_link_read_relocs (bfd *abfd,
|
||||
Elf_Internal_Rela *internal_relocs,
|
||||
bfd_boolean keep_memory)
|
||||
{
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
void *alloc1 = NULL;
|
||||
Elf_Internal_Rela *alloc2 = NULL;
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||
Elf_Internal_Rela *internal_rela_relocs;
|
||||
|
||||
if (elf_section_data (o)->relocs != NULL)
|
||||
return elf_section_data (o)->relocs;
|
||||
if (esdo->relocs != NULL)
|
||||
return esdo->relocs;
|
||||
|
||||
if (o->reloc_count == 0)
|
||||
return NULL;
|
||||
|
||||
rel_hdr = &elf_section_data (o)->rel_hdr;
|
||||
|
||||
if (internal_relocs == NULL)
|
||||
{
|
||||
bfd_size_type size;
|
||||
@@ -2234,32 +2233,41 @@ _bfd_elf_link_read_relocs (bfd *abfd,
|
||||
|
||||
if (external_relocs == NULL)
|
||||
{
|
||||
bfd_size_type size = rel_hdr->sh_size;
|
||||
bfd_size_type size = 0;
|
||||
|
||||
if (esdo->rel.hdr)
|
||||
size += esdo->rel.hdr->sh_size;
|
||||
if (esdo->rela.hdr)
|
||||
size += esdo->rela.hdr->sh_size;
|
||||
|
||||
if (elf_section_data (o)->rel_hdr2)
|
||||
size += elf_section_data (o)->rel_hdr2->sh_size;
|
||||
alloc1 = bfd_malloc (size);
|
||||
if (alloc1 == NULL)
|
||||
goto error_return;
|
||||
external_relocs = alloc1;
|
||||
}
|
||||
|
||||
if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr,
|
||||
external_relocs,
|
||||
internal_relocs))
|
||||
goto error_return;
|
||||
if (elf_section_data (o)->rel_hdr2
|
||||
&& (!elf_link_read_relocs_from_section
|
||||
(abfd, o,
|
||||
elf_section_data (o)->rel_hdr2,
|
||||
((bfd_byte *) external_relocs) + rel_hdr->sh_size,
|
||||
internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr)
|
||||
* bed->s->int_rels_per_ext_rel))))
|
||||
internal_rela_relocs = internal_relocs;
|
||||
if (esdo->rel.hdr)
|
||||
{
|
||||
if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr,
|
||||
external_relocs,
|
||||
internal_relocs))
|
||||
goto error_return;
|
||||
external_relocs = (((bfd_byte *) external_relocs)
|
||||
+ esdo->rel.hdr->sh_size);
|
||||
internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr)
|
||||
* bed->s->int_rels_per_ext_rel);
|
||||
}
|
||||
|
||||
if (esdo->rela.hdr
|
||||
&& (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr,
|
||||
external_relocs,
|
||||
internal_rela_relocs)))
|
||||
goto error_return;
|
||||
|
||||
/* Cache the results for next time, if we can. */
|
||||
if (keep_memory)
|
||||
elf_section_data (o)->relocs = internal_relocs;
|
||||
esdo->relocs = internal_relocs;
|
||||
|
||||
if (alloc1 != NULL)
|
||||
free (alloc1);
|
||||
@@ -2287,24 +2295,12 @@ _bfd_elf_link_read_relocs (bfd *abfd,
|
||||
|
||||
static bfd_boolean
|
||||
_bfd_elf_link_size_reloc_section (bfd *abfd,
|
||||
Elf_Internal_Shdr *rel_hdr,
|
||||
asection *o)
|
||||
struct bfd_elf_section_reloc_data *reldata)
|
||||
{
|
||||
bfd_size_type reloc_count;
|
||||
bfd_size_type num_rel_hashes;
|
||||
|
||||
/* Figure out how many relocations there will be. */
|
||||
if (rel_hdr == &elf_section_data (o)->rel_hdr)
|
||||
reloc_count = elf_section_data (o)->rel_count;
|
||||
else
|
||||
reloc_count = elf_section_data (o)->rel_count2;
|
||||
|
||||
num_rel_hashes = o->reloc_count;
|
||||
if (num_rel_hashes < reloc_count)
|
||||
num_rel_hashes = reloc_count;
|
||||
Elf_Internal_Shdr *rel_hdr = reldata->hdr;
|
||||
|
||||
/* That allows us to calculate the size of the section. */
|
||||
rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
|
||||
rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count;
|
||||
|
||||
/* The contents field must last into write_object_contents, so we
|
||||
allocate it with bfd_alloc rather than malloc. Also since we
|
||||
@@ -2314,19 +2310,16 @@ _bfd_elf_link_size_reloc_section (bfd *abfd,
|
||||
if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
|
||||
return FALSE;
|
||||
|
||||
/* We only allocate one set of hash entries, so we only do it the
|
||||
first time we are called. */
|
||||
if (elf_section_data (o)->rel_hashes == NULL
|
||||
&& num_rel_hashes)
|
||||
if (reldata->hashes == NULL && reldata->count)
|
||||
{
|
||||
struct elf_link_hash_entry **p;
|
||||
|
||||
p = (struct elf_link_hash_entry **)
|
||||
bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
|
||||
bfd_zmalloc (reldata->count * sizeof (struct elf_link_hash_entry *));
|
||||
if (p == NULL)
|
||||
return FALSE;
|
||||
|
||||
elf_section_data (o)->rel_hashes = p;
|
||||
reldata->hashes = p;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -2347,27 +2340,28 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
|
||||
Elf_Internal_Rela *irela;
|
||||
Elf_Internal_Rela *irelaend;
|
||||
bfd_byte *erel;
|
||||
struct bfd_elf_section_reloc_data *output_reldata;
|
||||
Elf_Internal_Shdr *output_rel_hdr;
|
||||
asection *output_section;
|
||||
unsigned int *rel_countp = NULL;
|
||||
const struct elf_backend_data *bed;
|
||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||
struct bfd_elf_section_data *esdo;
|
||||
|
||||
output_section = input_section->output_section;
|
||||
output_rel_hdr = NULL;
|
||||
|
||||
if (elf_section_data (output_section)->rel_hdr.sh_entsize
|
||||
== input_rel_hdr->sh_entsize)
|
||||
bed = get_elf_backend_data (output_bfd);
|
||||
esdo = elf_section_data (output_section);
|
||||
if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize)
|
||||
{
|
||||
output_rel_hdr = &elf_section_data (output_section)->rel_hdr;
|
||||
rel_countp = &elf_section_data (output_section)->rel_count;
|
||||
output_reldata = &esdo->rel;
|
||||
swap_out = bed->s->swap_reloc_out;
|
||||
}
|
||||
else if (elf_section_data (output_section)->rel_hdr2
|
||||
&& (elf_section_data (output_section)->rel_hdr2->sh_entsize
|
||||
== input_rel_hdr->sh_entsize))
|
||||
else if (esdo->rela.hdr
|
||||
&& esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize)
|
||||
{
|
||||
output_rel_hdr = elf_section_data (output_section)->rel_hdr2;
|
||||
rel_countp = &elf_section_data (output_section)->rel_count2;
|
||||
output_reldata = &esdo->rela;
|
||||
swap_out = bed->s->swap_reloca_out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2378,16 +2372,8 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bed = get_elf_backend_data (output_bfd);
|
||||
if (input_rel_hdr->sh_entsize == bed->s->sizeof_rel)
|
||||
swap_out = bed->s->swap_reloc_out;
|
||||
else if (input_rel_hdr->sh_entsize == bed->s->sizeof_rela)
|
||||
swap_out = bed->s->swap_reloca_out;
|
||||
else
|
||||
abort ();
|
||||
|
||||
erel = output_rel_hdr->contents;
|
||||
erel += *rel_countp * input_rel_hdr->sh_entsize;
|
||||
erel = output_reldata->hdr->contents;
|
||||
erel += output_reldata->count * input_rel_hdr->sh_entsize;
|
||||
irela = internal_relocs;
|
||||
irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
|
||||
* bed->s->int_rels_per_ext_rel);
|
||||
@@ -2400,7 +2386,7 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
|
||||
|
||||
/* Bump the counter, so that we know where to add the next set of
|
||||
relocations. */
|
||||
*rel_countp += NUM_SHDR_ENTRIES (input_rel_hdr);
|
||||
output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -7928,14 +7914,12 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
|
||||
|
||||
/* When performing a relocatable link, the input relocations are
|
||||
preserved. But, if they reference global symbols, the indices
|
||||
referenced must be updated. Update all the relocations in
|
||||
REL_HDR (there are COUNT of them), using the data in REL_HASH. */
|
||||
referenced must be updated. Update all the relocations found in
|
||||
RELDATA. */
|
||||
|
||||
static void
|
||||
elf_link_adjust_relocs (bfd *abfd,
|
||||
Elf_Internal_Shdr *rel_hdr,
|
||||
unsigned int count,
|
||||
struct elf_link_hash_entry **rel_hash)
|
||||
struct bfd_elf_section_reloc_data *reldata)
|
||||
{
|
||||
unsigned int i;
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
@@ -7944,13 +7928,15 @@ elf_link_adjust_relocs (bfd *abfd,
|
||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||
bfd_vma r_type_mask;
|
||||
int r_sym_shift;
|
||||
unsigned int count = reldata->count;
|
||||
struct elf_link_hash_entry **rel_hash = reldata->hashes;
|
||||
|
||||
if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
|
||||
if (reldata->hdr->sh_entsize == bed->s->sizeof_rel)
|
||||
{
|
||||
swap_in = bed->s->swap_reloc_in;
|
||||
swap_out = bed->s->swap_reloc_out;
|
||||
}
|
||||
else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
|
||||
else if (reldata->hdr->sh_entsize == bed->s->sizeof_rela)
|
||||
{
|
||||
swap_in = bed->s->swap_reloca_in;
|
||||
swap_out = bed->s->swap_reloca_out;
|
||||
@@ -7972,8 +7958,8 @@ elf_link_adjust_relocs (bfd *abfd,
|
||||
r_sym_shift = 32;
|
||||
}
|
||||
|
||||
erela = rel_hdr->contents;
|
||||
for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
|
||||
erela = reldata->hdr->contents;
|
||||
for (i = 0; i < count; i++, rel_hash++, erela += reldata->hdr->sh_entsize)
|
||||
{
|
||||
Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL];
|
||||
unsigned int j;
|
||||
@@ -9563,27 +9549,32 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
|| finfo->info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *irela;
|
||||
Elf_Internal_Rela *irelaend;
|
||||
Elf_Internal_Rela *irelaend, *irelamid;
|
||||
bfd_vma last_offset;
|
||||
struct elf_link_hash_entry **rel_hash;
|
||||
struct elf_link_hash_entry **rel_hash_list;
|
||||
Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
|
||||
struct elf_link_hash_entry **rel_hash_list, **rela_hash_list;
|
||||
Elf_Internal_Shdr *input_rel_hdr, *input_rela_hdr;
|
||||
unsigned int next_erel;
|
||||
bfd_boolean rela_normal;
|
||||
struct bfd_elf_section_data *esdi, *esdo;
|
||||
|
||||
input_rel_hdr = &elf_section_data (o)->rel_hdr;
|
||||
rela_normal = (bed->rela_normal
|
||||
&& (input_rel_hdr->sh_entsize
|
||||
== bed->s->sizeof_rela));
|
||||
esdi = elf_section_data (o);
|
||||
esdo = elf_section_data (o->output_section);
|
||||
rela_normal = FALSE;
|
||||
|
||||
/* Adjust the reloc addresses and symbol indices. */
|
||||
|
||||
irela = internal_relocs;
|
||||
irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||
rel_hash = (elf_section_data (o->output_section)->rel_hashes
|
||||
+ elf_section_data (o->output_section)->rel_count
|
||||
+ elf_section_data (o->output_section)->rel_count2);
|
||||
rel_hash = esdo->rel.hashes + esdo->rel.count;
|
||||
/* We start processing the REL relocs, if any. When we reach
|
||||
IRELAMID in the loop, we switch to the RELA relocs. */
|
||||
irelamid = irela;
|
||||
if (esdi->rel.hdr != NULL)
|
||||
irelamid += (NUM_SHDR_ENTRIES (esdi->rel.hdr)
|
||||
* bed->s->int_rels_per_ext_rel);
|
||||
rel_hash_list = rel_hash;
|
||||
rela_hash_list = NULL;
|
||||
last_offset = o->output_offset;
|
||||
if (!finfo->info->relocatable)
|
||||
last_offset += o->output_section->vma;
|
||||
@@ -9599,6 +9590,13 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
next_erel = 0;
|
||||
}
|
||||
|
||||
if (irela == irelamid)
|
||||
{
|
||||
rel_hash = esdo->rela.hashes + esdo->rela.count;
|
||||
rela_hash_list = rel_hash;
|
||||
rela_normal = bed->rela_normal;
|
||||
}
|
||||
|
||||
irela->r_offset = _bfd_elf_section_offset (output_bfd,
|
||||
finfo->info, o,
|
||||
irela->r_offset);
|
||||
@@ -9790,23 +9788,26 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
}
|
||||
|
||||
/* Swap out the relocs. */
|
||||
if (input_rel_hdr->sh_size != 0
|
||||
&& !bed->elf_backend_emit_relocs (output_bfd, o,
|
||||
input_rel_hdr,
|
||||
internal_relocs,
|
||||
rel_hash_list))
|
||||
return FALSE;
|
||||
|
||||
input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
|
||||
if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0)
|
||||
input_rel_hdr = esdi->rel.hdr;
|
||||
if (input_rel_hdr && input_rel_hdr->sh_size != 0)
|
||||
{
|
||||
if (!bed->elf_backend_emit_relocs (output_bfd, o,
|
||||
input_rel_hdr,
|
||||
internal_relocs,
|
||||
rel_hash_list))
|
||||
return FALSE;
|
||||
internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
|
||||
* bed->s->int_rels_per_ext_rel);
|
||||
rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
|
||||
}
|
||||
|
||||
input_rela_hdr = esdi->rela.hdr;
|
||||
if (input_rela_hdr && input_rela_hdr->sh_size != 0)
|
||||
{
|
||||
if (!bed->elf_backend_emit_relocs (output_bfd, o,
|
||||
input_rel_hdr2,
|
||||
input_rela_hdr,
|
||||
internal_relocs,
|
||||
rel_hash_list))
|
||||
rela_hash_list))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -9872,12 +9873,14 @@ elf_reloc_link_order (bfd *output_bfd,
|
||||
long indx;
|
||||
bfd_vma offset;
|
||||
bfd_vma addend;
|
||||
struct bfd_elf_section_reloc_data *reldata;
|
||||
struct elf_link_hash_entry **rel_hash_ptr;
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
|
||||
Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL];
|
||||
bfd_byte *erel;
|
||||
unsigned int i;
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (output_section);
|
||||
|
||||
howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
|
||||
if (howto == NULL)
|
||||
@@ -9888,10 +9891,18 @@ elf_reloc_link_order (bfd *output_bfd,
|
||||
|
||||
addend = link_order->u.reloc.p->addend;
|
||||
|
||||
if (esdo->rel.hdr)
|
||||
reldata = &esdo->rel;
|
||||
else if (esdo->rela.hdr)
|
||||
reldata = &esdo->rela;
|
||||
else
|
||||
{
|
||||
reldata = NULL;
|
||||
BFD_ASSERT (0);
|
||||
}
|
||||
|
||||
/* Figure out the symbol index. */
|
||||
rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
|
||||
+ elf_section_data (output_section)->rel_count
|
||||
+ elf_section_data (output_section)->rel_count2);
|
||||
rel_hash_ptr = reldata->hashes + reldata->count;
|
||||
if (link_order->type == bfd_section_reloc_link_order)
|
||||
{
|
||||
indx = link_order->u.reloc.p->u.section->target_index;
|
||||
@@ -10003,23 +10014,21 @@ elf_reloc_link_order (bfd *output_bfd,
|
||||
else
|
||||
irel[0].r_info = ELF64_R_INFO (indx, howto->type);
|
||||
|
||||
rel_hdr = &elf_section_data (output_section)->rel_hdr;
|
||||
rel_hdr = reldata->hdr;
|
||||
erel = rel_hdr->contents;
|
||||
if (rel_hdr->sh_type == SHT_REL)
|
||||
{
|
||||
erel += (elf_section_data (output_section)->rel_count
|
||||
* bed->s->sizeof_rel);
|
||||
erel += reldata->count * bed->s->sizeof_rel;
|
||||
(*bed->s->swap_reloc_out) (output_bfd, irel, erel);
|
||||
}
|
||||
else
|
||||
{
|
||||
irel[0].r_addend = addend;
|
||||
erel += (elf_section_data (output_section)->rel_count
|
||||
* bed->s->sizeof_rela);
|
||||
erel += reldata->count * bed->s->sizeof_rela;
|
||||
(*bed->s->swap_reloca_out) (output_bfd, irel, erel);
|
||||
}
|
||||
|
||||
++elf_section_data (output_section)->rel_count;
|
||||
++reldata->count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -10305,7 +10314,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
{
|
||||
unsigned int reloc_count = 0;
|
||||
struct bfd_elf_section_data *esdi = NULL;
|
||||
unsigned int *rel_count1;
|
||||
|
||||
if (p->type == bfd_section_reloc_link_order
|
||||
|| p->type == bfd_symbol_reloc_link_order)
|
||||
@@ -10358,11 +10366,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
|
||||
if ((sec->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
size_t ext_size;
|
||||
size_t ext_size = 0;
|
||||
|
||||
ext_size = esdi->rel_hdr.sh_size;
|
||||
if (esdi->rel_hdr2 != NULL)
|
||||
ext_size += esdi->rel_hdr2->sh_size;
|
||||
if (esdi->rel.hdr != NULL)
|
||||
ext_size = esdi->rel.hdr->sh_size;
|
||||
if (esdi->rela.hdr != NULL)
|
||||
ext_size += esdi->rela.hdr->sh_size;
|
||||
|
||||
if (ext_size > max_external_reloc_size)
|
||||
max_external_reloc_size = ext_size;
|
||||
@@ -10377,54 +10386,21 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
|
||||
o->reloc_count += reloc_count;
|
||||
|
||||
/* MIPS may have a mix of REL and RELA relocs on sections.
|
||||
To support this curious ABI we keep reloc counts in
|
||||
elf_section_data too. We must be careful to add the
|
||||
relocations from the input section to the right output
|
||||
count. FIXME: Get rid of one count. We have
|
||||
o->reloc_count == esdo->rel_count + esdo->rel_count2. */
|
||||
rel_count1 = &esdo->rel_count;
|
||||
if (esdi != NULL)
|
||||
if (p->type == bfd_indirect_link_order
|
||||
&& (info->relocatable || info->emitrelocations))
|
||||
{
|
||||
bfd_boolean same_size;
|
||||
bfd_size_type entsize1;
|
||||
|
||||
entsize1 = esdi->rel_hdr.sh_entsize;
|
||||
/* PR 9827: If the header size has not been set yet then
|
||||
assume that it will match the output section's reloc type. */
|
||||
if (entsize1 == 0)
|
||||
entsize1 = o->use_rela_p ? bed->s->sizeof_rela : bed->s->sizeof_rel;
|
||||
else
|
||||
BFD_ASSERT (entsize1 == bed->s->sizeof_rel
|
||||
|| entsize1 == bed->s->sizeof_rela);
|
||||
same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel);
|
||||
|
||||
if (!same_size)
|
||||
rel_count1 = &esdo->rel_count2;
|
||||
|
||||
if (esdi->rel_hdr2 != NULL)
|
||||
{
|
||||
bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize;
|
||||
unsigned int alt_count;
|
||||
unsigned int *rel_count2;
|
||||
|
||||
BFD_ASSERT (entsize2 != entsize1
|
||||
&& (entsize2 == bed->s->sizeof_rel
|
||||
|| entsize2 == bed->s->sizeof_rela));
|
||||
|
||||
rel_count2 = &esdo->rel_count2;
|
||||
if (!same_size)
|
||||
rel_count2 = &esdo->rel_count;
|
||||
|
||||
/* The following is probably too simplistic if the
|
||||
backend counts output relocs unusually. */
|
||||
BFD_ASSERT (bed->elf_backend_count_relocs == NULL);
|
||||
alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2);
|
||||
*rel_count2 += alt_count;
|
||||
reloc_count -= alt_count;
|
||||
}
|
||||
if (esdi->rel.hdr)
|
||||
esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
|
||||
if (esdi->rela.hdr)
|
||||
esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (o->use_rela_p)
|
||||
esdo->rela.count += reloc_count;
|
||||
else
|
||||
esdo->rel.count += reloc_count;
|
||||
}
|
||||
*rel_count1 += reloc_count;
|
||||
}
|
||||
|
||||
if (o->reloc_count > 0)
|
||||
@@ -10461,22 +10437,22 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
/* Set sizes, and assign file positions for reloc sections. */
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||
if ((o->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
if (!(_bfd_elf_link_size_reloc_section
|
||||
(abfd, &elf_section_data (o)->rel_hdr, o)))
|
||||
if (esdo->rel.hdr
|
||||
&& !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel)))
|
||||
goto error_return;
|
||||
|
||||
if (elf_section_data (o)->rel_hdr2
|
||||
&& !(_bfd_elf_link_size_reloc_section
|
||||
(abfd, elf_section_data (o)->rel_hdr2, o)))
|
||||
if (esdo->rela.hdr
|
||||
&& !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela)))
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
|
||||
to count upwards while actually outputting the relocations. */
|
||||
elf_section_data (o)->rel_count = 0;
|
||||
elf_section_data (o)->rel_count2 = 0;
|
||||
esdo->rel.count = 0;
|
||||
esdo->rela.count = 0;
|
||||
}
|
||||
|
||||
_bfd_elf_assign_file_positions_for_relocs (abfd);
|
||||
@@ -10908,17 +10884,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
/* Adjust the relocs to have the correct symbol indices. */
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||
if ((o->flags & SEC_RELOC) == 0)
|
||||
continue;
|
||||
|
||||
elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr,
|
||||
elf_section_data (o)->rel_count,
|
||||
elf_section_data (o)->rel_hashes);
|
||||
if (elf_section_data (o)->rel_hdr2 != NULL)
|
||||
elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2,
|
||||
elf_section_data (o)->rel_count2,
|
||||
(elf_section_data (o)->rel_hashes
|
||||
+ elf_section_data (o)->rel_count));
|
||||
if (esdo->rel.hdr != NULL)
|
||||
elf_link_adjust_relocs (abfd, &esdo->rel);
|
||||
if (esdo->rela.hdr != NULL)
|
||||
elf_link_adjust_relocs (abfd, &esdo->rela);
|
||||
|
||||
/* Set the reloc_count field to 0 to prevent write_relocs from
|
||||
trying to swap the relocs out itself. */
|
||||
@@ -11213,9 +11186,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
free (finfo.symshndxbuf);
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
if ((o->flags & SEC_RELOC) != 0
|
||||
&& elf_section_data (o)->rel_hashes != NULL)
|
||||
free (elf_section_data (o)->rel_hashes);
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||
if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
|
||||
free (esdo->rel.hashes);
|
||||
if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
|
||||
free (esdo->rela.hashes);
|
||||
}
|
||||
|
||||
elf_tdata (abfd)->linker = TRUE;
|
||||
@@ -11257,9 +11232,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
free (finfo.symshndxbuf);
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
if ((o->flags & SEC_RELOC) != 0
|
||||
&& elf_section_data (o)->rel_hashes != NULL)
|
||||
free (elf_section_data (o)->rel_hashes);
|
||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||
if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
|
||||
free (esdo->rel.hashes);
|
||||
if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
|
||||
free (esdo->rela.hashes);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -12603,7 +12580,7 @@ get_dynamic_reloc_section_name (bfd * abfd,
|
||||
{
|
||||
const char * name;
|
||||
unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
|
||||
unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
|
||||
unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
|
||||
|
||||
name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
|
||||
if (name == NULL)
|
||||
|
||||
Reference in New Issue
Block a user