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:
parent
83e3a93c83
commit
d4730f921a
|
@ -1,3 +1,76 @@
|
|||
2010-10-04 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2010-10-01 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_size_stubs): Don't choke on local symbols in
|
||||
|
|
|
@ -1319,6 +1319,23 @@ struct elf_backend_data
|
|||
unsigned default_execstack : 1;
|
||||
};
|
||||
|
||||
/* Information about reloc sections associated with a bfd_elf_section_data
|
||||
structure. */
|
||||
struct bfd_elf_section_reloc_data
|
||||
{
|
||||
/* The ELF header for the reloc section associated with this
|
||||
section, if any. */
|
||||
Elf_Internal_Shdr *hdr;
|
||||
/* The number of relocations currently assigned to HDR. */
|
||||
unsigned int count;
|
||||
/* The ELF section number of the reloc section. Only used for an
|
||||
output file. */
|
||||
int idx;
|
||||
/* Used by the backend linker to store the symbol hash table entries
|
||||
associated with relocs against global symbols. */
|
||||
struct elf_link_hash_entry **hashes;
|
||||
};
|
||||
|
||||
/* Information stored for each BFD section in an ELF file. This
|
||||
structure is allocated by elf_new_section_hook. */
|
||||
|
||||
|
@ -1327,31 +1344,13 @@ struct bfd_elf_section_data
|
|||
/* The ELF header for this section. */
|
||||
Elf_Internal_Shdr this_hdr;
|
||||
|
||||
/* The ELF header for the reloc section associated with this
|
||||
section, if any. */
|
||||
Elf_Internal_Shdr rel_hdr;
|
||||
|
||||
/* If there is a second reloc section associated with this section,
|
||||
as can happen on Irix 6, this field points to the header. */
|
||||
Elf_Internal_Shdr *rel_hdr2;
|
||||
|
||||
/* The number of relocations currently assigned to REL_HDR. */
|
||||
unsigned int rel_count;
|
||||
|
||||
/* The number of relocations currently assigned to REL_HDR2. */
|
||||
unsigned int rel_count2;
|
||||
/* Information about the REL and RELA reloc sections associated
|
||||
with this section, if any. */
|
||||
struct bfd_elf_section_reloc_data rel, rela;
|
||||
|
||||
/* The ELF section number of this section. */
|
||||
int this_idx;
|
||||
|
||||
/* The ELF section number of the reloc section indicated by
|
||||
REL_HDR if any. Only used for an output file. */
|
||||
int rel_idx;
|
||||
|
||||
/* The ELF section number of the reloc section indicated by
|
||||
REL_HDR2 if any. Only used for an output file. */
|
||||
int rel_idx2;
|
||||
|
||||
/* Used by the backend linker when generating a shared library to
|
||||
record the dynamic symbol index for a section symbol
|
||||
corresponding to this section. A value of 0 means that there is
|
||||
|
@ -1361,10 +1360,6 @@ struct bfd_elf_section_data
|
|||
/* A pointer to the linked-to section for SHF_LINK_ORDER. */
|
||||
asection *linked_to;
|
||||
|
||||
/* Used by the backend linker to store the symbol hash table entries
|
||||
associated with relocs against global symbols. */
|
||||
struct elf_link_hash_entry **rel_hashes;
|
||||
|
||||
/* A pointer to the swapped relocs. If the section uses REL relocs,
|
||||
rather than RELA, all the r_addend fields will be zero. This
|
||||
pointer may be NULL. It is used by the backend linker. */
|
||||
|
@ -1852,7 +1847,7 @@ extern int _bfd_elf_sizeof_headers
|
|||
extern bfd_boolean _bfd_elf_new_section_hook
|
||||
(bfd *, asection *);
|
||||
extern bfd_boolean _bfd_elf_init_reloc_shdr
|
||||
(bfd *, Elf_Internal_Shdr *, asection *, bfd_boolean);
|
||||
(bfd *, struct bfd_elf_section_reloc_data *, asection *, bfd_boolean);
|
||||
extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
|
||||
(const char *, const struct bfd_elf_special_section *, unsigned int);
|
||||
extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
|
||||
|
@ -2237,6 +2232,7 @@ extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
|
|||
extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
|
||||
extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
|
||||
extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
|
||||
extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
|
||||
|
||||
/* The linker may needs to keep track of the number of relocs that it
|
||||
decides to copy as dynamic relocs in check_relocs for each symbol.
|
||||
|
@ -2363,13 +2359,13 @@ extern asection _bfd_elf_large_com_section;
|
|||
sections may require relocations. */ \
|
||||
Elf_Internal_Shdr *rel_hdr; \
|
||||
\
|
||||
rel_hdr = &elf_section_data (input_section->output_section)->rel_hdr; \
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
|
||||
\
|
||||
/* Avoid empty output section. */ \
|
||||
if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
|
||||
{ \
|
||||
rel_hdr->sh_size -= rel_hdr->sh_entsize; \
|
||||
rel_hdr = &elf_section_data (input_section)->rel_hdr; \
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
|
||||
rel_hdr->sh_size -= rel_hdr->sh_entsize; \
|
||||
\
|
||||
memmove (rel, rel + 1, (relend - rel) * sizeof (*rel)); \
|
||||
|
|
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);
|
||||
|
|
|
@ -4034,39 +4034,6 @@ static const struct bfd_elf_special_section m32r_elf_special_sections[] =
|
|||
{ NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static bfd_boolean
|
||||
m32r_elf_fake_sections (bfd *abfd,
|
||||
Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
|
||||
asection *sec)
|
||||
{
|
||||
/* The generic elf_fake_sections will set up REL_HDR using the
|
||||
default kind of relocations. But, we may actually need both
|
||||
kinds of relocations, so we set up the second header here.
|
||||
|
||||
This is not necessary for the O32 ABI since that only uses Elf32_Rel
|
||||
relocations (cf. System V ABI, MIPS RISC Processor Supplement,
|
||||
3rd Edition, p. 4-17). It breaks the IRIX 5/6 32-bit ld, since one
|
||||
of the resulting empty .rela.<section> sections starts with
|
||||
sh_offset == object size, and ld doesn't allow that. While the check
|
||||
is arguably bogus for empty or SHT_NOBITS sections, it can easily be
|
||||
avoided by not emitting those useless sections in the first place. */
|
||||
if ((sec->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
struct bfd_elf_section_data *esd;
|
||||
bfd_size_type amt = sizeof (Elf_Internal_Shdr);
|
||||
|
||||
esd = elf_section_data (sec);
|
||||
BFD_ASSERT (esd->rel_hdr2 == NULL);
|
||||
esd->rel_hdr2 = bfd_zalloc (abfd, amt);
|
||||
if (!esd->rel_hdr2)
|
||||
return FALSE;
|
||||
_bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
|
||||
!sec->use_rela_p);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static enum elf_reloc_type_class
|
||||
m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
|
||||
{
|
||||
|
@ -4128,7 +4095,6 @@ m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
|
|||
#else
|
||||
#define elf_backend_default_use_rela_p 1
|
||||
#define elf_backend_may_use_rela_p 1
|
||||
#define elf_backend_fake_sections m32r_elf_fake_sections
|
||||
#endif
|
||||
|
||||
#define elf_backend_object_p m32r_elf_object_p
|
||||
|
|
|
@ -2060,7 +2060,7 @@ microblaze_elf_check_relocs (bfd * abfd,
|
|||
const char *name;
|
||||
bfd *dynobj;
|
||||
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)
|
||||
|
|
|
@ -6391,6 +6391,7 @@ ppc_elf_relax_section (bfd *abfd,
|
|||
{
|
||||
/* Append sufficient NOP relocs so we can write out relocation
|
||||
information for the trampolines. */
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
|
||||
* sizeof (*new_relocs));
|
||||
unsigned ix;
|
||||
|
@ -6409,8 +6410,8 @@ ppc_elf_relax_section (bfd *abfd,
|
|||
free (internal_relocs);
|
||||
elf_section_data (isec)->relocs = new_relocs;
|
||||
isec->reloc_count += changes;
|
||||
elf_section_data (isec)->rel_hdr.sh_size
|
||||
+= changes * elf_section_data (isec)->rel_hdr.sh_entsize;
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (isec);
|
||||
rel_hdr->sh_size += changes * rel_hdr->sh_entsize;
|
||||
}
|
||||
else if (elf_section_data (isec)->relocs != internal_relocs)
|
||||
free (internal_relocs);
|
||||
|
|
|
@ -5091,7 +5091,7 @@ spu_elf_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
input_section->reloc_count = wrel - relocs;
|
||||
/* Backflips for _bfd_elf_link_output_relocs. */
|
||||
rel_hdr = &elf_section_data (input_section)->rel_hdr;
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (input_section);
|
||||
rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
|
||||
ret = 2;
|
||||
}
|
||||
|
|
|
@ -1347,31 +1347,6 @@ elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p)
|
|||
elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
elf32_tic6x_fake_sections (bfd *abfd,
|
||||
Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
|
||||
asection *sec)
|
||||
{
|
||||
/* The generic elf_fake_sections will set up REL_HDR using the
|
||||
default kind of relocations. But, we may actually need both
|
||||
kinds of relocations, so we set up the second header here. */
|
||||
if ((sec->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
struct bfd_elf_section_data *esd;
|
||||
bfd_size_type amt = sizeof (Elf_Internal_Shdr);
|
||||
|
||||
esd = elf_section_data (sec);
|
||||
BFD_ASSERT (esd->rel_hdr2 == NULL);
|
||||
esd->rel_hdr2 = bfd_zalloc (abfd, amt);
|
||||
if (!esd->rel_hdr2)
|
||||
return FALSE;
|
||||
_bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
|
||||
!sec->use_rela_p);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
elf32_tic6x_mkobject (bfd *abfd)
|
||||
{
|
||||
|
@ -1408,14 +1383,13 @@ elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec,
|
|||
const struct elf_backend_data *bed;
|
||||
|
||||
/* To determine which flavor of relocation this is, we depend on the
|
||||
fact that the INPUT_SECTION's REL_HDR is read before its
|
||||
REL_HDR2. */
|
||||
rel_hdr = &elf_section_data (sec)->rel_hdr;
|
||||
fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR. */
|
||||
rel_hdr = elf_section_data (sec)->rel.hdr;
|
||||
if (rel_hdr == NULL)
|
||||
return FALSE;
|
||||
bed = get_elf_backend_data (abfd);
|
||||
if ((size_t) (rel - relocs)
|
||||
>= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
|
||||
rel_hdr = elf_section_data (sec)->rel_hdr2;
|
||||
return rel_hdr->sh_entsize == bed->s->sizeof_rel;
|
||||
return ((size_t) (rel - relocs)
|
||||
< NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
|
@ -1790,7 +1764,6 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|||
#define elf_backend_default_use_rela_p 1
|
||||
#define elf_backend_may_use_rel_p 1
|
||||
#define elf_backend_may_use_rela_p 1
|
||||
#define elf_backend_fake_sections elf32_tic6x_fake_sections
|
||||
#define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type
|
||||
#define elf_backend_obj_attrs_section "__TI_build_attributes"
|
||||
#define elf_backend_obj_attrs_section_type SHT_C6000_ATTRIBUTES
|
||||
|
|
|
@ -4086,7 +4086,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||
const char *section_name;
|
||||
section_name = (bfd_elf_string_from_elf_section
|
||||
(input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
|
||||
elf_section_data(input_section)->rel_hdr.sh_name));
|
||||
_bfd_elf_single_rel_hdr (input_section)->sh_name));
|
||||
BFD_ASSERT(section_name != NULL);
|
||||
srel = bfd_get_section_by_name (dynobj, section_name);
|
||||
}
|
||||
|
|
|
@ -407,7 +407,7 @@ get_reloc_section (bfd *abfd,
|
|||
|
||||
srel_name = (bfd_elf_string_from_elf_section
|
||||
(abfd, elf_elfheader(abfd)->e_shstrndx,
|
||||
elf_section_data(sec)->rel_hdr.sh_name));
|
||||
_bfd_elf_single_rel_hdr(sec)->sh_name));
|
||||
if (srel_name == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -2722,13 +2722,13 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
|
|||
|| asect->reloc_count == 0)
|
||||
return TRUE;
|
||||
|
||||
rel_hdr = &d->rel_hdr;
|
||||
reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
|
||||
rel_hdr2 = d->rel_hdr2;
|
||||
rel_hdr = d->rel.hdr;
|
||||
reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
|
||||
rel_hdr2 = d->rela.hdr;
|
||||
reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
|
||||
|
||||
BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
|
||||
BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
|
||||
BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
|
||||
|| (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
|
||||
|
||||
}
|
||||
|
@ -2756,19 +2756,18 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
|
|||
/* The slurp_one_reloc_table routine increments reloc_count. */
|
||||
asect->reloc_count = 0;
|
||||
|
||||
if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
|
||||
rel_hdr, reloc_count,
|
||||
relents,
|
||||
symbols, dynamic))
|
||||
if (rel_hdr != NULL
|
||||
&& ! mips_elf64_slurp_one_reloc_table (abfd, asect,
|
||||
rel_hdr, reloc_count,
|
||||
relents,
|
||||
symbols, dynamic))
|
||||
return FALSE;
|
||||
if (rel_hdr2 != NULL
|
||||
&& ! mips_elf64_slurp_one_reloc_table (abfd, asect,
|
||||
rel_hdr2, reloc_count2,
|
||||
relents + reloc_count * 3,
|
||||
symbols, dynamic))
|
||||
return FALSE;
|
||||
if (d->rel_hdr2 != NULL)
|
||||
{
|
||||
if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
|
||||
rel_hdr2, reloc_count2,
|
||||
relents + reloc_count * 3,
|
||||
symbols, dynamic))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
asect->relocation = relents;
|
||||
return TRUE;
|
||||
|
@ -2827,7 +2826,7 @@ mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
rel_hdr = &elf_section_data (sec)->rel_hdr;
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (sec);
|
||||
|
||||
/* Do the actual relocation. */
|
||||
|
||||
|
|
|
@ -7073,6 +7073,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
|
|||
if (need_edit || add_aux_fields)
|
||||
{
|
||||
Elf_Internal_Rela *write_rel;
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
bfd_byte *rptr, *wptr;
|
||||
bfd_byte *new_contents;
|
||||
bfd_boolean skip;
|
||||
|
@ -7252,9 +7253,8 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
|
|||
|
||||
/* Fudge the header size too, as this is used later in
|
||||
elf_bfd_final_link if we are emitting relocs. */
|
||||
elf_section_data (sec)->rel_hdr.sh_size
|
||||
= sec->reloc_count * elf_section_data (sec)->rel_hdr.sh_entsize;
|
||||
BFD_ASSERT (elf_section_data (sec)->rel_hdr2 == NULL);
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (sec);
|
||||
rel_hdr->sh_size = sec->reloc_count * rel_hdr->sh_entsize;
|
||||
some_edited = TRUE;
|
||||
}
|
||||
else if (elf_section_data (sec)->relocs != relstart)
|
||||
|
@ -8413,6 +8413,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
|
|||
|
||||
if (toc->reloc_count != 0)
|
||||
{
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
Elf_Internal_Rela *wrel;
|
||||
bfd_size_type sz;
|
||||
|
||||
|
@ -8438,9 +8439,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
|
|||
goto error_ret;
|
||||
|
||||
toc->reloc_count = wrel - relstart;
|
||||
sz = elf_section_data (toc)->rel_hdr.sh_entsize;
|
||||
elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;
|
||||
BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (toc);
|
||||
sz = rel_hdr->sh_entsize;
|
||||
rel_hdr->sh_size = toc->reloc_count * sz;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9376,9 +9377,13 @@ get_relocs (asection *sec, int count)
|
|||
if (relocs == NULL)
|
||||
return NULL;
|
||||
elfsec_data->relocs = relocs;
|
||||
elfsec_data->rel_hdr.sh_size = (sec->reloc_count
|
||||
* sizeof (Elf64_External_Rela));
|
||||
elfsec_data->rel_hdr.sh_entsize = sizeof (Elf64_External_Rela);
|
||||
elfsec_data->rela.hdr = bfd_zalloc (sec->owner,
|
||||
sizeof (Elf_Internal_Shdr));
|
||||
if (elfsec_data->rela.hdr == NULL)
|
||||
return NULL;
|
||||
elfsec_data->rela.hdr->sh_size = (sec->reloc_count
|
||||
* sizeof (Elf64_External_Rela));
|
||||
elfsec_data->rela.hdr->sh_entsize = sizeof (Elf64_External_Rela);
|
||||
sec->reloc_count = 0;
|
||||
}
|
||||
relocs += sec->reloc_count;
|
||||
|
@ -13472,7 +13477,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|||
&& htab->brlt->reloc_count != 0
|
||||
&& !_bfd_elf_link_output_relocs (output_bfd,
|
||||
htab->brlt,
|
||||
&elf_section_data (htab->brlt)->rel_hdr,
|
||||
elf_section_data (htab->brlt)->rela.hdr,
|
||||
elf_section_data (htab->brlt)->relocs,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
@ -13481,7 +13486,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|||
&& htab->glink->reloc_count != 0
|
||||
&& !_bfd_elf_link_output_relocs (output_bfd,
|
||||
htab->glink,
|
||||
&elf_section_data (htab->glink)->rel_hdr,
|
||||
elf_section_data (htab->glink)->rela.hdr,
|
||||
elf_section_data (htab->glink)->relocs,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
|
|
@ -163,10 +163,10 @@ elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
|
|||
|| asect->reloc_count == 0)
|
||||
return TRUE;
|
||||
|
||||
rel_hdr = &d->rel_hdr;
|
||||
rel_hdr2 = d->rel_hdr2;
|
||||
rel_hdr = d->rel.hdr;
|
||||
rel_hdr2 = d->rela.hdr;
|
||||
|
||||
BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
|
||||
BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
|
||||
|| (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
|
||||
}
|
||||
else
|
||||
|
@ -193,8 +193,9 @@ elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
|
|||
canon_reloc_count. */
|
||||
canon_reloc_count (asect) = 0;
|
||||
|
||||
if (!elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
|
||||
dynamic))
|
||||
if (rel_hdr
|
||||
&& !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
|
||||
dynamic))
|
||||
return FALSE;
|
||||
|
||||
if (rel_hdr2
|
||||
|
@ -325,7 +326,7 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
|
|||
}
|
||||
}
|
||||
|
||||
rela_hdr = &elf_section_data (sec)->rel_hdr;
|
||||
rela_hdr = elf_section_data (sec)->rela.hdr;
|
||||
|
||||
rela_hdr->sh_size = rela_hdr->sh_entsize * count;
|
||||
rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
|
||||
|
|
|
@ -959,7 +959,9 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
|
|||
if (sec->orelocation == NULL)
|
||||
return;
|
||||
|
||||
rela_hdr = &elf_section_data (sec)->rel_hdr;
|
||||
rela_hdr = elf_section_data (sec)->rela.hdr;
|
||||
if (rela_hdr == NULL)
|
||||
rela_hdr = elf_section_data (sec)->rel.hdr;
|
||||
|
||||
rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
|
||||
rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size);
|
||||
|
@ -1530,13 +1532,13 @@ elf_slurp_reloc_table (bfd *abfd,
|
|||
|| asect->reloc_count == 0)
|
||||
return TRUE;
|
||||
|
||||
rel_hdr = &d->rel_hdr;
|
||||
reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
|
||||
rel_hdr2 = d->rel_hdr2;
|
||||
reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
|
||||
rel_hdr = d->rel.hdr;
|
||||
reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
|
||||
rel_hdr2 = d->rela.hdr;
|
||||
reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0;
|
||||
|
||||
BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
|
||||
BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
|
||||
BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
|
||||
|| (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
|
||||
|
||||
}
|
||||
|
@ -1560,10 +1562,11 @@ elf_slurp_reloc_table (bfd *abfd,
|
|||
if (relents == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!elf_slurp_reloc_table_from_section (abfd, asect,
|
||||
rel_hdr, reloc_count,
|
||||
relents,
|
||||
symbols, dynamic))
|
||||
if (rel_hdr
|
||||
&& !elf_slurp_reloc_table_from_section (abfd, asect,
|
||||
rel_hdr, reloc_count,
|
||||
relents,
|
||||
symbols, dynamic))
|
||||
return FALSE;
|
||||
|
||||
if (rel_hdr2
|
||||
|
|
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)
|
||||
|
|
|
@ -2598,7 +2598,7 @@ get_reloc_section (bfd *abfd,
|
|||
|
||||
srel_name = (bfd_elf_string_from_elf_section
|
||||
(abfd, elf_elfheader(abfd)->e_shstrndx,
|
||||
elf_section_data(sec)->rel_hdr.sh_name));
|
||||
_bfd_elf_single_rel_hdr (sec)->sh_name));
|
||||
if (srel_name == NULL)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -783,23 +783,6 @@ static bfd *reldyn_sorting_bfd;
|
|||
#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \
|
||||
(get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
|
||||
|
||||
/* Determine whether the internal relocation of index REL_IDX is REL
|
||||
(zero) or RELA (non-zero). The assumption is that, if there are
|
||||
two relocation sections for this section, one of them is REL and
|
||||
the other is RELA. If the index of the relocation we're testing is
|
||||
in range for the first relocation section, check that the external
|
||||
relocation size is that for RELA. It is also assumed that, if
|
||||
rel_idx is not in range for the first section, and this first
|
||||
section contains REL relocs, then the relocation is in the second
|
||||
section, that is RELA. */
|
||||
#define MIPS_RELOC_RELA_P(abfd, sec, rel_idx) \
|
||||
((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr) \
|
||||
* get_elf_backend_data (abfd)->s->int_rels_per_ext_rel \
|
||||
> (bfd_vma)(rel_idx)) \
|
||||
== (elf_section_data (sec)->rel_hdr.sh_entsize \
|
||||
== (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela) \
|
||||
: sizeof (Elf32_External_Rela))))
|
||||
|
||||
/* The name of the dynamic relocation section. */
|
||||
#define MIPS_ELF_REL_DYN_NAME(INFO) \
|
||||
(mips_elf_hash_table (INFO)->is_vxworks ? ".rela.dyn" : ".rel.dyn")
|
||||
|
@ -7110,14 +7093,14 @@ mips_elf_rel_relocation_p (bfd *abfd, asection *sec,
|
|||
Elf_Internal_Shdr *rel_hdr;
|
||||
const struct elf_backend_data *bed;
|
||||
|
||||
/* To determine which flavor or relocation this is, we depend on the
|
||||
fact that the INPUT_SECTION's REL_HDR is read before its REL_HDR2. */
|
||||
rel_hdr = &elf_section_data (sec)->rel_hdr;
|
||||
/* To determine which flavor of relocation this is, we depend on the
|
||||
fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR. */
|
||||
rel_hdr = elf_section_data (sec)->rel.hdr;
|
||||
if (rel_hdr == NULL)
|
||||
return FALSE;
|
||||
bed = get_elf_backend_data (abfd);
|
||||
if ((size_t) (rel - relocs)
|
||||
>= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
|
||||
rel_hdr = elf_section_data (sec)->rel_hdr2;
|
||||
return rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (abfd);
|
||||
return ((size_t) (rel - relocs)
|
||||
< NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
|
||||
}
|
||||
|
||||
/* Read the addend for REL relocation REL, which belongs to bfd ABFD.
|
||||
|
@ -8983,13 +8966,13 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||
asection *sec;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry *h;
|
||||
bfd_boolean rel_reloc;
|
||||
|
||||
rel_reloc = (NEWABI_P (input_bfd)
|
||||
&& mips_elf_rel_relocation_p (input_bfd, input_section,
|
||||
relocs, rel));
|
||||
/* Find the relocation howto for this relocation. */
|
||||
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type,
|
||||
NEWABI_P (input_bfd)
|
||||
&& (MIPS_RELOC_RELA_P
|
||||
(input_bfd, input_section,
|
||||
rel - relocs)));
|
||||
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc);
|
||||
|
||||
r_symndx = ELF_R_SYM (input_bfd, rel->r_info);
|
||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||
|
|
|
@ -1343,7 +1343,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
sreloc = NULL;
|
||||
|
||||
if (ABI_64_P (abfd))
|
||||
num_relocs = NUM_SHDR_ENTRIES (& elf_section_data (sec)->rel_hdr);
|
||||
num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (sec));
|
||||
else
|
||||
num_relocs = sec->reloc_count;
|
||||
|
||||
|
@ -2884,7 +2884,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
|
|||
|
||||
rel = relocs;
|
||||
if (ABI_64_P (output_bfd))
|
||||
num_relocs = NUM_SHDR_ENTRIES (& elf_section_data (input_section)->rel_hdr);
|
||||
num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (input_section));
|
||||
else
|
||||
num_relocs = input_section->reloc_count;
|
||||
relend = relocs + num_relocs;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2010-10-04 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* emultempl/xtensaelf.em (replace_insn_sec_with_prop_sec): Use
|
||||
_bfd_elf_single_rel_hdr.
|
||||
|
||||
2010-10-01 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/12066
|
||||
|
|
|
@ -98,6 +98,7 @@ replace_insn_sec_with_prop_sec (bfd *abfd,
|
|||
bfd_byte *insn_contents = NULL;
|
||||
unsigned entry_count;
|
||||
unsigned entry;
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
Elf_Internal_Rela *internal_relocs = NULL;
|
||||
unsigned reloc_count;
|
||||
|
||||
|
@ -147,10 +148,9 @@ replace_insn_sec_with_prop_sec (bfd *abfd,
|
|||
|
||||
/* The entry size and size must be set to allow the linker to compute
|
||||
the number of relocations since it does not use reloc_count. */
|
||||
elf_section_data (prop_sec)->rel_hdr.sh_entsize =
|
||||
sizeof (Elf32_External_Rela);
|
||||
elf_section_data (prop_sec)->rel_hdr.sh_size =
|
||||
elf_section_data (insn_sec)->rel_hdr.sh_size;
|
||||
rel_hdr = _bfd_elf_single_rel_hdr (prop_sec);
|
||||
rel_hdr->sh_entsize = sizeof (Elf32_External_Rela);
|
||||
rel_hdr->sh_size = _bfd_elf_single_rel_hdr (insn_sec)->sh_size;
|
||||
|
||||
if (prop_contents == NULL && prop_sec->size != 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue