mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 10:12:21 +08:00
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:
176
bfd/elf.c
176
bfd/elf.c
@ -1710,8 +1710,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
||||
/* *These* do a lot of work -- but build no sections! */
|
||||
{
|
||||
asection *target_sect;
|
||||
Elf_Internal_Shdr *hdr2;
|
||||
Elf_Internal_Shdr *hdr2, **p_hdr;
|
||||
unsigned int num_sec = elf_numsections (abfd);
|
||||
struct bfd_elf_section_data *esdt;
|
||||
bfd_size_type amt;
|
||||
|
||||
if (hdr->sh_entsize
|
||||
!= (bfd_size_type) (hdr->sh_type == SHT_REL
|
||||
@ -1790,20 +1792,19 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
||||
if (target_sect == NULL)
|
||||
return FALSE;
|
||||
|
||||
if ((target_sect->flags & SEC_RELOC) == 0
|
||||
|| target_sect->reloc_count == 0)
|
||||
hdr2 = &elf_section_data (target_sect)->rel_hdr;
|
||||
esdt = elf_section_data (target_sect);
|
||||
if (hdr->sh_type == SHT_RELA)
|
||||
p_hdr = &esdt->rela.hdr;
|
||||
else
|
||||
{
|
||||
bfd_size_type amt;
|
||||
BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
|
||||
amt = sizeof (*hdr2);
|
||||
hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
|
||||
if (hdr2 == NULL)
|
||||
return FALSE;
|
||||
elf_section_data (target_sect)->rel_hdr2 = hdr2;
|
||||
}
|
||||
p_hdr = &esdt->rel.hdr;
|
||||
|
||||
BFD_ASSERT (*p_hdr == NULL);
|
||||
amt = sizeof (*hdr2);
|
||||
hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
|
||||
if (hdr2 == NULL)
|
||||
return FALSE;
|
||||
*hdr2 = *hdr;
|
||||
*p_hdr = hdr2;
|
||||
elf_elfsections (abfd)[shindex] = hdr2;
|
||||
target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
|
||||
target_sect->flags |= SEC_RELOC;
|
||||
@ -1812,7 +1813,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
||||
/* In the section to which the relocations apply, mark whether
|
||||
its relocations are of the REL or RELA variety. */
|
||||
if (hdr->sh_size != 0)
|
||||
target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
|
||||
{
|
||||
if (hdr->sh_type == SHT_RELA)
|
||||
target_sect->use_rela_p = 1;
|
||||
}
|
||||
abfd->flags |= HAS_RELOC;
|
||||
return TRUE;
|
||||
}
|
||||
@ -2410,20 +2414,43 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize REL_HDR, the section-header for new section, containing
|
||||
relocations against ASECT. If USE_RELA_P is TRUE, we use RELA
|
||||
relocations; otherwise, we use REL relocations. */
|
||||
/* Return the REL_HDR for SEC, assuming there is only a single one, either
|
||||
REL or RELA. */
|
||||
|
||||
Elf_Internal_Shdr *
|
||||
_bfd_elf_single_rel_hdr (asection *sec)
|
||||
{
|
||||
if (elf_section_data (sec)->rel.hdr)
|
||||
{
|
||||
BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
|
||||
return elf_section_data (sec)->rel.hdr;
|
||||
}
|
||||
else
|
||||
return elf_section_data (sec)->rela.hdr;
|
||||
}
|
||||
|
||||
/* Allocate and initialize a section-header for a new reloc section,
|
||||
containing relocations against ASECT. It is stored in RELDATA. If
|
||||
USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
|
||||
relocations. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_elf_init_reloc_shdr (bfd *abfd,
|
||||
Elf_Internal_Shdr *rel_hdr,
|
||||
struct bfd_elf_section_reloc_data *reldata,
|
||||
asection *asect,
|
||||
bfd_boolean use_rela_p)
|
||||
{
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
char *name;
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
|
||||
bfd_size_type amt;
|
||||
|
||||
amt = sizeof (Elf_Internal_Shdr);
|
||||
BFD_ASSERT (reldata->hdr == NULL);
|
||||
rel_hdr = bfd_zalloc (abfd, amt);
|
||||
reldata->hdr = rel_hdr;
|
||||
|
||||
amt = sizeof ".rela" + strlen (asect->name);
|
||||
name = (char *) bfd_alloc (abfd, amt);
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
@ -2457,30 +2484,37 @@ bfd_elf_get_default_section_type (flagword flags)
|
||||
return SHT_PROGBITS;
|
||||
}
|
||||
|
||||
struct fake_section_arg
|
||||
{
|
||||
struct bfd_link_info *link_info;
|
||||
bfd_boolean failed;
|
||||
};
|
||||
|
||||
/* Set up an ELF internal section header for a section. */
|
||||
|
||||
static void
|
||||
elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
|
||||
elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
|
||||
{
|
||||
struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
|
||||
struct bfd_elf_section_data *esd = elf_section_data (asect);
|
||||
Elf_Internal_Shdr *this_hdr;
|
||||
unsigned int sh_type;
|
||||
|
||||
if (*failedptr)
|
||||
if (arg->failed)
|
||||
{
|
||||
/* We already failed; just get out of the bfd_map_over_sections
|
||||
loop. */
|
||||
return;
|
||||
}
|
||||
|
||||
this_hdr = &elf_section_data (asect)->this_hdr;
|
||||
this_hdr = &esd->this_hdr;
|
||||
|
||||
this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
|
||||
asect->name, FALSE);
|
||||
if (this_hdr->sh_name == (unsigned int) -1)
|
||||
{
|
||||
*failedptr = TRUE;
|
||||
arg->failed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2632,11 +2666,45 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
|
||||
if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
|
||||
this_hdr->sh_flags |= SHF_EXCLUDE;
|
||||
|
||||
/* If the section has relocs, set up a section header for the
|
||||
SHT_REL[A] section. If two relocation sections are required for
|
||||
this section, it is up to the processor-specific back-end to
|
||||
create the other. */
|
||||
if ((asect->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
/* When doing a relocatable link, create both REL and RELA sections if
|
||||
needed. */
|
||||
if (arg->link_info
|
||||
/* Do the normal setup if we wouldn't create any sections here. */
|
||||
&& esd->rel.count + esd->rela.count > 0
|
||||
&& (arg->link_info->relocatable || arg->link_info->emitrelocations))
|
||||
{
|
||||
if (esd->rel.count && esd->rel.hdr == NULL
|
||||
&& !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
|
||||
{
|
||||
arg->failed = TRUE;
|
||||
return;
|
||||
}
|
||||
if (esd->rela.count && esd->rela.hdr == NULL
|
||||
&& !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
|
||||
{
|
||||
arg->failed = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!_bfd_elf_init_reloc_shdr (abfd,
|
||||
(asect->use_rela_p
|
||||
? &esd->rela : &esd->rel),
|
||||
asect,
|
||||
asect->use_rela_p))
|
||||
arg->failed = TRUE;
|
||||
}
|
||||
|
||||
/* Check for processor-specific section types. */
|
||||
sh_type = this_hdr->sh_type;
|
||||
if (bed->elf_backend_fake_sections
|
||||
&& !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
|
||||
*failedptr = TRUE;
|
||||
arg->failed = TRUE;
|
||||
|
||||
if (sh_type == SHT_NOBITS && asect->size != 0)
|
||||
{
|
||||
@ -2644,17 +2712,6 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
|
||||
called for objcopy --only-keep-debug. */
|
||||
this_hdr->sh_type = sh_type;
|
||||
}
|
||||
|
||||
/* If the section has relocs, set up a section header for the
|
||||
SHT_REL[A] section. If two relocation sections are required for
|
||||
this section, it is up to the processor-specific back-end to
|
||||
create the other. */
|
||||
if ((asect->flags & SEC_RELOC) != 0
|
||||
&& !_bfd_elf_init_reloc_shdr (abfd,
|
||||
&elf_section_data (asect)->rel_hdr,
|
||||
asect,
|
||||
asect->use_rela_p))
|
||||
*failedptr = TRUE;
|
||||
}
|
||||
|
||||
/* Fill in the contents of a SHT_GROUP section. Called from
|
||||
@ -2820,21 +2877,21 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
|
||||
if (d->this_hdr.sh_type != SHT_GROUP)
|
||||
d->this_idx = section_number++;
|
||||
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
|
||||
if ((sec->flags & SEC_RELOC) == 0)
|
||||
d->rel_idx = 0;
|
||||
else
|
||||
if (d->rel.hdr)
|
||||
{
|
||||
d->rel_idx = section_number++;
|
||||
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
|
||||
d->rel.idx = section_number++;
|
||||
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
|
||||
}
|
||||
else
|
||||
d->rel.idx = 0;
|
||||
|
||||
if (d->rel_hdr2)
|
||||
if (d->rela.hdr)
|
||||
{
|
||||
d->rel_idx2 = section_number++;
|
||||
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
|
||||
d->rela.idx = section_number++;
|
||||
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
|
||||
}
|
||||
else
|
||||
d->rel_idx2 = 0;
|
||||
d->rela.idx = 0;
|
||||
}
|
||||
|
||||
t->shstrtab_section = section_number++;
|
||||
@ -2906,25 +2963,25 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
|
||||
d = elf_section_data (sec);
|
||||
|
||||
i_shdrp[d->this_idx] = &d->this_hdr;
|
||||
if (d->rel_idx != 0)
|
||||
i_shdrp[d->rel_idx] = &d->rel_hdr;
|
||||
if (d->rel_idx2 != 0)
|
||||
i_shdrp[d->rel_idx2] = d->rel_hdr2;
|
||||
if (d->rel.idx != 0)
|
||||
i_shdrp[d->rel.idx] = d->rel.hdr;
|
||||
if (d->rela.idx != 0)
|
||||
i_shdrp[d->rela.idx] = d->rela.hdr;
|
||||
|
||||
/* Fill in the sh_link and sh_info fields while we're at it. */
|
||||
|
||||
/* sh_link of a reloc section is the section index of the symbol
|
||||
table. sh_info is the section index of the section to which
|
||||
the relocation entries apply. */
|
||||
if (d->rel_idx != 0)
|
||||
if (d->rel.idx != 0)
|
||||
{
|
||||
d->rel_hdr.sh_link = t->symtab_section;
|
||||
d->rel_hdr.sh_info = d->this_idx;
|
||||
d->rel.hdr->sh_link = t->symtab_section;
|
||||
d->rel.hdr->sh_info = d->this_idx;
|
||||
}
|
||||
if (d->rel_idx2 != 0)
|
||||
if (d->rela.idx != 0)
|
||||
{
|
||||
d->rel_hdr2->sh_link = t->symtab_section;
|
||||
d->rel_hdr2->sh_info = d->this_idx;
|
||||
d->rela.hdr->sh_link = t->symtab_section;
|
||||
d->rela.hdr->sh_info = d->this_idx;
|
||||
}
|
||||
|
||||
/* We need to set up sh_link for SHF_LINK_ORDER. */
|
||||
@ -3278,6 +3335,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
|
||||
struct bfd_link_info *link_info)
|
||||
{
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
struct fake_section_arg fsargs;
|
||||
bfd_boolean failed;
|
||||
struct bfd_strtab_hash *strtab = NULL;
|
||||
Elf_Internal_Shdr *shstrtab_hdr;
|
||||
@ -3297,9 +3355,10 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
|
||||
if (bed->elf_backend_post_process_headers)
|
||||
(*bed->elf_backend_post_process_headers) (abfd, link_info);
|
||||
|
||||
failed = FALSE;
|
||||
bfd_map_over_sections (abfd, elf_fake_sections, &failed);
|
||||
if (failed)
|
||||
fsargs.failed = FALSE;
|
||||
fsargs.link_info = link_info;
|
||||
bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
|
||||
if (fsargs.failed)
|
||||
return FALSE;
|
||||
|
||||
if (!assign_section_numbers (abfd, link_info))
|
||||
@ -3319,6 +3378,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
failed = FALSE;
|
||||
if (link_info == NULL)
|
||||
{
|
||||
bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
|
||||
|
Reference in New Issue
Block a user