diff options
author | Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp> | 2016-09-28 11:50:41 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-09-28 11:50:41 +0100 |
commit | 9eaff8613893f063400fdae95bc382ab33685e3b (patch) | |
tree | 707a22d63ab5811257bfa8b97ab498952d1b2915 /bfd/elflink.c | |
parent | de7fb42b57b132ca65746ca4a9ff17c902d9cc62 (diff) | |
download | gdb-9eaff8613893f063400fdae95bc382ab33685e3b.zip gdb-9eaff8613893f063400fdae95bc382ab33685e3b.tar.gz gdb-9eaff8613893f063400fdae95bc382ab33685e3b.tar.bz2 |
Fix seg-fault in the linker introduced by the previous delta.
PR ld/20636
* elf-bfd.h (struct elf_backend_data): Delete
elf_backend_count_output_relocs callback and add
elf_backend_update_relocs.
* elf32-arm.c (elf32_arm_count_output_relocs): Deleted.
(emit_relocs): Deleted.
(elf32_arm_emit_relocs): Deleted.
(elf_backend_emit_relocs): Updated not to use the old functions.
(elf32_arm_update_relocs): New function.
(elf_backend_update_relocs): New define.
* elflink.c (bfd_elf_final_link): Add additional_reloc_count to the
relocation count. Call elf_backend_emit_relocs.
(_bfd_elf_size_reloc_section): Do not call
elf_backend_count_output_relocs.
* elfxx-target.h (elf_backend_count_output_relocs): Deleted.
(elf_backend_update_relocs): New define.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index e35ce02..fbf8c00 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2449,23 +2449,13 @@ _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_link_info *info, - asection *o, bfd_boolean rela) +_bfd_elf_link_size_reloc_section (bfd *abfd, + struct bfd_elf_section_reloc_data *reldata) { - 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; + Elf_Internal_Shdr *rel_hdr = reldata->hdr; /* That allows us to calculate the size of the section. */ - 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; + 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 @@ -2553,20 +2543,6 @@ _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. */ @@ -8354,6 +8330,7 @@ ext64b_r_offset (const void *p) static bfd_boolean elf_link_adjust_relocs (bfd *abfd, + asection *sec, struct bfd_elf_section_reloc_data *reldata, bfd_boolean sort) { @@ -8412,6 +8389,9 @@ elf_link_adjust_relocs (bfd *abfd, (*swap_out) (abfd, irela, erela); } + if (bed->elf_backend_update_relocs) + (*bed->elf_backend_update_relocs) (sec, reldata); + if (sort && count != 0) { bfd_vma (*ext_r_off) (const void *); @@ -11310,12 +11290,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 @@ -11401,14 +11381,21 @@ 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 { @@ -11419,7 +11406,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) } } - if (o->reloc_count > 0 || additional_reloc_count > 0) + if (o->reloc_count > 0) o->flags |= SEC_RELOC; else { @@ -11457,11 +11444,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, info, o, FALSE))) + && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel))) goto error_return; if (esdo->rela.hdr - && !(_bfd_elf_link_size_reloc_section (abfd, info, o, TRUE))) + && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela))) goto error_return; } @@ -11963,10 +11950,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o); if (esdo->rel.hdr != NULL - && !elf_link_adjust_relocs (abfd, &esdo->rel, sort)) + && !elf_link_adjust_relocs (abfd, o, &esdo->rel, sort)) return FALSE; if (esdo->rela.hdr != NULL - && !elf_link_adjust_relocs (abfd, &esdo->rela, sort)) + && !elf_link_adjust_relocs (abfd, o, &esdo->rela, sort)) return FALSE; /* Set the reloc_count field to 0 to prevent write_relocs from |