* 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:
Bernd Schmidt 2010-10-04 14:13:10 +00:00
parent 83e3a93c83
commit d4730f921a
20 changed files with 456 additions and 414 deletions

View File

@ -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

View File

@ -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
View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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. */

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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)
{