From 5025eb7c0d87b01507116353b5d63b163d7add3d Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Fri, 23 Sep 2016 16:32:04 +0100 Subject: [PATCH] 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. --- bfd/ChangeLog | 21 +++ bfd/elf-bfd.h | 8 + bfd/elf32-arm.c | 303 ++++++++++++++++++++++++++------- bfd/elflink.c | 47 +++-- bfd/elfxx-target.h | 4 + ld/ChangeLog | 7 + ld/testsuite/ld-arm/unwind-4.d | 18 +- 7 files changed, 328 insertions(+), 80 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 36624ee457..4e1d20926e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,24 @@ +2016-09-23 Akihiko Odaki + + PR ld/20595 + * 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. + 2016-09-19 Jose E. Marchesi * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Allow diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d18df17e2f..c58bd4f902 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1183,6 +1183,11 @@ struct elf_backend_data unsigned int (*elf_backend_count_additional_relocs) (asection *); + /* Count relocations to be output. The result may be different if the + input relocations are expected to be modified by the backend. */ + unsigned int (* elf_backend_count_output_relocs) + (struct bfd_link_info *, asection *, bfd_boolean is_rela); + /* Say whether to sort relocs output by ld -r and ld --emit-relocs, by r_offset. If NULL, default to true. */ bfd_boolean (*sort_relocs_p) @@ -2152,6 +2157,9 @@ extern bfd_boolean _bfd_elf_link_output_relocs (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, struct elf_link_hash_entry **); +extern unsigned int _bfd_elf_default_count_output_relocs + (struct bfd_link_info * ATTRIBUTE_UNUSED, asection *, bfd_boolean); + extern bfd_boolean _bfd_elf_adjust_dynamic_copy (struct bfd_link_info *, struct elf_link_hash_entry *, asection *); diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 6e68be1c09..c58b65d046 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -8592,8 +8592,8 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd, if the instruction is not the last instruction of an IT block, we cannot create a jump there, so we bail out. */ - if ((is_ldm || is_vldm) && - stm32l4xx_need_create_replacing_stub + if ((is_ldm || is_vldm) + && stm32l4xx_need_create_replacing_stub (insn, globals->stm32l4xx_fix)) { if (is_not_last_in_it_block) @@ -8641,8 +8641,8 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd, There can be no nested IT blocks so an IT block is naturally a new one for which it is worth computing its size. */ - bfd_boolean is_newitblock = ((insn & 0xff00) == 0xbf00) && - ((insn & 0x000f) != 0x0000); + bfd_boolean is_newitblock = ((insn & 0xff00) == 0xbf00) + && ((insn & 0x000f) != 0x0000); /* If we have a new IT block we compute its size. */ if (is_newitblock) { @@ -11066,9 +11066,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, { if (dynreloc_st_type == STT_GNU_IFUNC) outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE); - else if (bfd_link_pic (info) && - (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) + else if (bfd_link_pic (info) + && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE); else outrel.r_info = 0; @@ -11100,8 +11100,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, { bfd_vma off; - BFD_ASSERT (local_got_offsets != NULL && - local_got_offsets[r_symndx] != (bfd_vma) -1); + BFD_ASSERT (local_got_offsets != NULL + && local_got_offsets[r_symndx] != (bfd_vma) -1); off = local_got_offsets[r_symndx]; @@ -14906,8 +14906,8 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info, if (ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal)) { cmse_sec = cmse_hash->root.root.u.def.section; - if (!cmse_sec->gc_mark && - !_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook)) + if (!cmse_sec->gc_mark + && !_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook)) return FALSE; } } @@ -15950,9 +15950,9 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, || !add_dynamic_entry (DT_JMPREL, 0)) return FALSE; - if (htab->dt_tlsdesc_plt && - (!add_dynamic_entry (DT_TLSDESC_PLT,0) - || !add_dynamic_entry (DT_TLSDESC_GOT,0))) + if (htab->dt_tlsdesc_plt + && (!add_dynamic_entry (DT_TLSDESC_PLT,0) + || !add_dynamic_entry (DT_TLSDESC_GOT,0))) return FALSE; } @@ -18243,39 +18243,6 @@ stm32l4xx_create_replacing_stub (struct elf32_arm_link_hash_table * htab, /* End of stm32l4xx work-around. */ -static void -elf32_arm_add_relocation (bfd *output_bfd, struct bfd_link_info *info, - asection *output_sec, Elf_Internal_Rela *rel) -{ - BFD_ASSERT (output_sec && rel); - struct bfd_elf_section_reloc_data *output_reldata; - struct elf32_arm_link_hash_table *htab; - struct bfd_elf_section_data *oesd = elf_section_data (output_sec); - Elf_Internal_Shdr *rel_hdr; - - - if (oesd->rel.hdr) - { - rel_hdr = oesd->rel.hdr; - output_reldata = &(oesd->rel); - } - else if (oesd->rela.hdr) - { - rel_hdr = oesd->rela.hdr; - output_reldata = &(oesd->rela); - } - else - { - abort (); - } - - bfd_byte *erel = rel_hdr->contents; - erel += output_reldata->count * rel_hdr->sh_entsize; - htab = elf32_arm_hash_table (info); - SWAP_RELOC_OUT (htab) (output_bfd, rel, erel); - output_reldata->count++; -} - /* Do code byteswapping. Return FALSE afterwards so that the section is written out as normal. */ @@ -18527,18 +18494,6 @@ elf32_arm_write_section (bfd *output_bfd, adjust offset by hand. */ prel31_offset = text_sec->output_offset + text_sec->size; - - /* New relocation entity. */ - asection *text_out = text_sec->output_section; - Elf_Internal_Rela rel; - rel.r_addend = 0; - rel.r_offset = exidx_offset; - rel.r_info = ELF32_R_INFO (text_out->target_index, - R_ARM_PREL31); - - elf32_arm_add_relocation (output_bfd, link_info, - sec->output_section, - &rel); } /* First address we can't unwind. */ @@ -19060,9 +19015,84 @@ elf32_arm_count_additional_relocs (asection *sec) { struct _arm_elf_section_data *arm_data; arm_data = get_arm_elf_section_data (sec); + return arm_data == NULL ? 0 : arm_data->additional_reloc_count; } +static unsigned int +elf32_arm_count_output_relocs (struct bfd_link_info * info, + asection * o, + bfd_boolean rela) +{ + struct bfd_elf_section_data *esdo; + struct bfd_link_order *p; + bfd_size_type count; + + esdo = elf_section_data (o->output_section); + if (esdo->this_hdr.sh_type != SHT_ARM_EXIDX) + return _bfd_elf_default_count_output_relocs (info, o, rela); + + /* PR 20595: Skip relocations for deleted exidx entries. */ + count = 0; + for (p = o->map_head.link_order; p != NULL; p = p->next) + { + struct _arm_elf_section_data *arm_data; + struct bfd_elf_section_data *esd; + arm_unwind_table_edit *edit_list; + Elf_Internal_Rela *relocs; + asection *sec; + bfd_size_type num_rel; + bfd_size_type num_rela; + unsigned int i; + + if (p->type == bfd_section_reloc_link_order + || p->type == bfd_symbol_reloc_link_order) + { + count++; + continue; + } + + sec = p->u.indirect.section; + arm_data = get_arm_elf_section_data (sec); + esd = &arm_data->elf; + + if (arm_data->additional_reloc_count) + count += arm_data->additional_reloc_count; + + edit_list = arm_data->u.exidx.unwind_edit_list; + if (!edit_list) + { + count += sec->reloc_count; + continue; + } + + relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, + info->keep_memory); + num_rel = esd->rel.hdr ? NUM_SHDR_ENTRIES (esd->rel.hdr) : 0; + num_rela = esd->rela.hdr ? NUM_SHDR_ENTRIES (esd->rela.hdr) : 0; + if (rela) + relocs += num_rel; + + for (i = 0; i < (rela ? num_rela : num_rel); i++) + { + arm_unwind_table_edit *edit_node; + unsigned int index; + + index = (relocs[i].r_offset - sec->vma) / 8; + + for (edit_node = edit_list; + edit_node->next && edit_node->next->index > index; + edit_node++); + + if (edit_node->type != DELETE_EXIDX_ENTRY + || edit_node->index != index) + count++; + } + } + + return count; +} + /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which has a type >= SHT_LOOS. Returns TRUE if these fields were initialised FALSE otherwise. ISECTION is the best guess matching section from the @@ -19191,6 +19221,139 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) sym->flags |= BSF_KEEP; } +static bfd_boolean +emit_relocs (bfd * output_bfd, + asection * input_section, + Elf_Internal_Shdr * input_rel_hdr, + Elf_Internal_Rela * internal_relocs, + struct elf_link_hash_entry ** rel_hash, + bfd_boolean (* fallback) (bfd *, asection *, + Elf_Internal_Shdr *, + Elf_Internal_Rela *, + struct elf_link_hash_entry **)) +{ + _arm_elf_section_data *arm_data; + struct bfd_elf_section_reloc_data *output_reldata; + Elf_Internal_Shdr *output_rel_hdr; + Elf_Internal_Rela *irela; + Elf_Internal_Rela *irelaend; + asection *output_section; + const struct elf_backend_data *bed; + void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); + struct bfd_elf_section_data *esdo; + arm_unwind_table_edit *edit_list, *edit_tail; + bfd_byte *erel; + bfd_vma offset; + + arm_data = get_arm_elf_section_data (input_section); + + if (!arm_data || arm_data->elf.this_hdr.sh_type != SHT_ARM_EXIDX) + goto fallback_label; + + edit_list = arm_data->u.exidx.unwind_edit_list; + edit_tail = arm_data->u.exidx.unwind_edit_tail; + + if (!edit_list) + goto fallback_label; + + output_section = input_section->output_section; + offset = output_section->vma + input_section->output_offset; + + 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_reldata = &esdo->rel; + swap_out = bed->s->swap_reloc_out; + } + else if (esdo->rela.hdr + && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize) + { + output_reldata = &esdo->rela; + swap_out = bed->s->swap_reloca_out; + } + else + { + (*_bfd_error_handler) + (_("%B: relocation size mismatch in %B section %A"), + output_bfd, input_section->owner, input_section); + bfd_set_error (bfd_error_wrong_format); + return FALSE; + } + + output_rel_hdr = output_reldata->hdr; + erel = output_rel_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); + while (irela < irelaend) + { + arm_unwind_table_edit *edit_node, *edit_next; + Elf_Internal_Rela rel; + bfd_vma bias; + bfd_vma index; + + index = (irela->r_offset - offset) / 8; + + bias = 0; + edit_node = edit_list; + for (edit_next = edit_list; + edit_next && edit_next->index <= index; + edit_next = edit_node->next) + { + bias++; + edit_node = edit_next; + } + + if (edit_node->type != DELETE_EXIDX_ENTRY || edit_node->index != index) + { + rel.r_offset = irela->r_offset - bias * 8; + rel.r_info = irela->r_info; + rel.r_addend = irela->r_addend; + + (*swap_out) (output_bfd, &rel, erel); + erel += output_rel_hdr->sh_entsize; + output_reldata->count++; + } + + irela += bed->s->int_rels_per_ext_rel; + } + + if (edit_tail->type == INSERT_EXIDX_CANTUNWIND_AT_END) + { + /* New relocation entity. */ + asection *text_sec = edit_tail->linked_section; + asection *text_out = text_sec->output_section; + bfd_vma exidx_offset = offset + input_section->size - 8; + Elf_Internal_Rela rel; + + rel.r_addend = 0; + rel.r_offset = exidx_offset; + rel.r_info = ELF32_R_INFO (text_out->target_index, R_ARM_PREL31); + (*swap_out) (output_bfd, &rel, erel); + output_reldata->count++; + } + + return TRUE; + +fallback_label: + return fallback (output_bfd, input_section, input_rel_hdr, + internal_relocs, rel_hash); +} + +static bfd_boolean +elf32_arm_emit_relocs (bfd * output_bfd, + asection * input_section, + Elf_Internal_Shdr * input_rel_hdr, + Elf_Internal_Rela * internal_relocs, + struct elf_link_hash_entry ** rel_hash) +{ + return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs, + rel_hash, _bfd_elf_link_output_relocs); +} + #undef elf_backend_copy_special_section_fields #define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields @@ -19221,6 +19384,7 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #define bfd_elf32_bfd_final_link elf32_arm_final_link #define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab +#define elf_backend_emit_relocs elf32_arm_emit_relocs #define elf_backend_get_symbol_type elf32_arm_get_symbol_type #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook #define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections @@ -19250,6 +19414,7 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #define elf_backend_begin_write_processing elf32_arm_begin_write_processing #define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook #define elf_backend_count_additional_relocs elf32_arm_count_additional_relocs +#define elf_backend_count_output_relocs elf32_arm_count_output_relocs #define elf_backend_symbol_processing elf32_arm_backend_symbol_processing #define elf_backend_can_refcount 1 @@ -19275,9 +19440,9 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #define elf_backend_obj_attrs_order elf32_arm_obj_attrs_order #define elf_backend_obj_attrs_handle_unknown elf32_arm_obj_attrs_handle_unknown -#undef elf_backend_section_flags +#undef elf_backend_section_flags #define elf_backend_section_flags elf32_arm_section_flags -#undef elf_backend_lookup_section_flags_hook +#undef elf_backend_lookup_section_flags_hook #define elf_backend_lookup_section_flags_hook elf32_arm_lookup_section_flags #include "elf32-target.h" @@ -19416,6 +19581,17 @@ elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker) elf_vxworks_final_write_processing (abfd, linker); } +static bfd_boolean +elf32_arm_vxworks_emit_relocs (bfd * output_bfd, + asection * input_section, + Elf_Internal_Shdr * input_rel_hdr, + Elf_Internal_Rela * internal_relocs, + struct elf_link_hash_entry ** rel_hash) +{ + return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs, + rel_hash, elf_vxworks_emit_relocs); +} + #undef elf32_bed #define elf32_bed elf32_arm_vxworks_bed @@ -19424,7 +19600,7 @@ elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker) #undef elf_backend_final_write_processing #define elf_backend_final_write_processing elf32_arm_vxworks_final_write_processing #undef elf_backend_emit_relocs -#define elf_backend_emit_relocs elf_vxworks_emit_relocs +#define elf_backend_emit_relocs elf32_arm_vxworks_emit_relocs #undef elf_backend_may_use_rel_p #define elf_backend_may_use_rel_p 0 @@ -19787,7 +19963,8 @@ elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt, #define ELF_DYNAMIC_SEC_FLAGS \ (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED) -#undef elf_backend_emit_relocs +#undef elf_backend_emit_relocs +#define elf_backend_emit_relocs elf32_arm_emit_relocs #undef bfd_elf32_bfd_link_hash_table_create #define bfd_elf32_bfd_link_hash_table_create elf32_arm_symbian_link_hash_table_create diff --git a/bfd/elflink.c b/bfd/elflink.c index 9e9a33cb35..e35ce02129 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; } diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 364bddf741..0f6f5c5e3d 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -554,6 +554,9 @@ #ifndef elf_backend_count_additional_relocs #define elf_backend_count_additional_relocs NULL #endif +#ifndef elf_backend_count_output_relocs +#define elf_backend_count_output_relocs _bfd_elf_default_count_output_relocs +#endif #ifndef elf_backend_sort_relocs_p #define elf_backend_sort_relocs_p NULL #endif @@ -777,6 +780,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_emit_relocs, elf_backend_count_relocs, elf_backend_count_additional_relocs, + elf_backend_count_output_relocs, elf_backend_sort_relocs_p, elf_backend_grok_prstatus, elf_backend_grok_psinfo, diff --git a/ld/ChangeLog b/ld/ChangeLog index ee43d40484..56e6133e9e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2016-09-23 Akihiko Odaki + + PR ld/20595 + * 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. + 2016-09-23 Andreas Krebbel * emulparams/elf64_s390.sh: Change TEXT_START_ADDR to 256MB. diff --git a/ld/testsuite/ld-arm/unwind-4.d b/ld/testsuite/ld-arm/unwind-4.d index 0a4427aafd..0bed0dc692 100644 --- a/ld/testsuite/ld-arm/unwind-4.d +++ b/ld/testsuite/ld-arm/unwind-4.d @@ -1,8 +1,22 @@ -#ld: -T arm.ld -#objdump: -s +#ld: -q -T arm.ld +#objdump: -sr .*: file format.* +#... +RELOCATION RECORDS FOR \[\.ARM\.exidx\]: +OFFSET TYPE VALUE +00000000 R_ARM_PREL31 \.text +00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0 +00000008 R_ARM_PREL31 \.text +00000008 R_ARM_NONE __aeabi_unwind_cpp_pr1 +0000000c R_ARM_PREL31 \.text +00000010 R_ARM_PREL31 \.text +00000010 R_ARM_NONE __aeabi_unwind_cpp_pr0 +00000018 R_ARM_PREL31 \.text + + +Contents of section .text: #... Contents of section .ARM.exidx: 8020 (e0ffff7f b0b0a880 dcffff7f e8ffff7f|7fffffe0 80a8b0b0 7fffffdc 7fffffe8) .*