diff options
author | Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp> | 2016-09-23 16:32:04 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-09-23 16:32:04 +0100 |
commit | 5025eb7c0d87b01507116353b5d63b163d7add3d (patch) | |
tree | 5ee96f3e2ad11fe3c7c2fd3959bd2cd6f2c7c1c9 /bfd/elflink.c | |
parent | 7c4236c3505d8dca3c6d9c2bc61145fa759bf4ce (diff) | |
download | gdb-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.c | 47 |
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; } |