aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>2016-09-23 16:32:04 +0100
committerNick Clifton <nickc@redhat.com>2016-09-23 16:32:04 +0100
commit5025eb7c0d87b01507116353b5d63b163d7add3d (patch)
tree5ee96f3e2ad11fe3c7c2fd3959bd2cd6f2c7c1c9 /bfd/elflink.c
parent7c4236c3505d8dca3c6d9c2bc61145fa759bf4ce (diff)
downloadgdb-5025eb7c0d87b01507116353b5d63b163d7add3d.zip
gdb-5025eb7c0d87b01507116353b5d63b163d7add3d.tar.gz
gdb-5025eb7c0d87b01507116353b5d63b163d7add3d.tar.bz2
Delete relocations associatesd with deleted exidx entries.
PR ld/20595 ld * testsuite/ld-arm/unwind-4.d: Add -q option to linker command line and -r option to objdump command line. Match emitted relocs to make sure that superflous relocs are not generated. bfd * elf-bfd.h (struct elf_backend_data): Add elf_backend_count_output_relocs callback to count relocations in the final output. * elf-arm.c (elf32_arm_add_relocation): Deleted. (elf32_arm_write_section): Move additional relocation to emit_relocs. (elf32_arm_count_output_relocs): New function. (emit_relocs): New function. (elf32_arm_emit_relocs): New function. (elf32_arm_vxworks_emit_relocs): New function. (elf_backend_emit_relocs): Updated to use the new functions. (elf_backend_count_output_relocs): New define. * bfd/elflink.c (bfd_elf_final_link): Do not add additional_reloc_count to the relocation count. (_bfd_elf_link_size_reloc_section): Use callback to count the relocations which will be in output. (_bfd_elf_default_count_output_relocs): New function. * bfd/elfxx-target.h (elf_backend_count_output_relocs): New define.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9e9a33c..e35ce02 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2449,13 +2449,23 @@ _bfd_elf_link_read_relocs (bfd *abfd,
section header for a section containing relocations for O. */
static bfd_boolean
-_bfd_elf_link_size_reloc_section (bfd *abfd,
- struct bfd_elf_section_reloc_data *reldata)
+_bfd_elf_link_size_reloc_section (bfd *abfd, struct bfd_link_info *info,
+ asection *o, bfd_boolean rela)
{
- Elf_Internal_Shdr *rel_hdr = reldata->hdr;
+ struct bfd_elf_section_data *esdo;
+ const struct elf_backend_data *bed;
+ struct bfd_elf_section_reloc_data *reldata;
+ Elf_Internal_Shdr *rel_hdr;
+ unsigned int count;
+
+ esdo = elf_section_data (o);
+ reldata = rela ? &esdo->rela : &esdo->rel;
+ rel_hdr = reldata->hdr;
/* That allows us to calculate the size of the section. */
- rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count;
+ bed = get_elf_backend_data (abfd);
+ count = (*bed->elf_backend_count_output_relocs) (info, o, rela);
+ rel_hdr->sh_size = count * rel_hdr->sh_entsize;
/* The contents field must last into write_object_contents, so we
allocate it with bfd_alloc rather than malloc. Also since we
@@ -2543,6 +2553,20 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
return TRUE;
}
+
+unsigned int
+_bfd_elf_default_count_output_relocs (struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ asection * o,
+ bfd_boolean rela)
+{
+ struct bfd_elf_section_data *esdo;
+ struct bfd_elf_section_reloc_data *reldata;
+
+ esdo = elf_section_data (o);
+ reldata = rela ? &esdo->rela : &esdo->rel;
+
+ return reldata->count;
+}
/* Make weak undefined symbols in PIE dynamic. */
@@ -11286,12 +11310,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
for (o = abfd->sections; o != NULL; o = o->next)
{
struct bfd_elf_section_data *esdo = elf_section_data (o);
+ unsigned int additional_reloc_count = 0;
o->reloc_count = 0;
for (p = o->map_head.link_order; p != NULL; p = p->next)
{
unsigned int reloc_count = 0;
- unsigned int additional_reloc_count = 0;
struct bfd_elf_section_data *esdi = NULL;
if (p->type == bfd_section_reloc_link_order
@@ -11377,21 +11401,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
if (reloc_count == 0)
continue;
- reloc_count += additional_reloc_count;
o->reloc_count += reloc_count;
if (p->type == bfd_indirect_link_order && emit_relocs)
{
if (esdi->rel.hdr)
- {
esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
- esdo->rel.count += additional_reloc_count;
- }
if (esdi->rela.hdr)
- {
esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
- esdo->rela.count += additional_reloc_count;
- }
}
else
{
@@ -11402,7 +11419,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
}
}
- if (o->reloc_count > 0)
+ if (o->reloc_count > 0 || additional_reloc_count > 0)
o->flags |= SEC_RELOC;
else
{
@@ -11440,11 +11457,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
if ((o->flags & SEC_RELOC) != 0)
{
if (esdo->rel.hdr
- && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel)))
+ && !(_bfd_elf_link_size_reloc_section (abfd, info, o, FALSE)))
goto error_return;
if (esdo->rela.hdr
- && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela)))
+ && !(_bfd_elf_link_size_reloc_section (abfd, info, o, TRUE)))
goto error_return;
}