From e41b3a13792f24506443962d82207466bf9b9e39 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 20 Jun 2011 13:18:52 +0000 Subject: PR ld/12570 include/ * bfdlink.h (struct bfd_link_info): Add no_ld_generated_unwind_info option. ld/ * emultempl/elf32.em (OPTION_LD_GENERATED_UNWIND_INFO, OPTION_NO_LD_GENERATED_UNWIND_INFO): Define. (gld${EMULATION_NAME}_handle_option): Handle --ld-generated-unwind-info and --no-ld-generated-unwind-info. * ld.texinfo (--ld-generated-unwind-info, --no-ld-generated-unwind-info): Document. bfd/ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Allow no relocations at all for linker created .eh_frame sections. (_bfd_elf_discard_section_eh_frame): Handle linker created .eh_frame sections with no relocations. * elf64-x86-64.c: Include dwarf2.h. (elf_x86_64_eh_frame_plt): New variable. (PLT_CIE_LENGTH, PLT_FDE_LENGTH, PLT_FDE_START_OFFSET, PLT_FDE_LEN_OFFSET): Define. (struct elf_x86_64_link_hash_table): Add plt_eh_frame field. (elf_x86_64_create_dynamic_sections): Create and fill in .eh_frame section for .plt section. (elf_x86_64_size_dynamic_sections): Write .plt section size into .eh_frame FDE covering .plt section. (elf_x86_64_finish_dynamic_sections): Write .plt section start into .eh_frame FDE covering .plt section. Call _bfd_elf_write_section_eh_frame on htab->plt_eh_frame section. (elf_backend_plt_alignment): Define to 4. * elf32-i386.c: Include dwarf2.h. (elf_i386_eh_frame_plt): New variable. (PLT_CIE_LENGTH, PLT_FDE_LENGTH, PLT_FDE_START_OFFSET, PLT_FDE_LEN_OFFSET): Define. (struct elf_i386_link_hash_table): Add plt_eh_frame field. (elf_i386_create_dynamic_sections): Create and fill in .eh_frame section for .plt section. (elf_i386_size_dynamic_sections): Write .plt section size into .eh_frame FDE covering .plt section. (elf_i386_finish_dynamic_sections): Write .plt section start into .eh_frame FDE covering .plt section. Call _bfd_elf_write_section_eh_frame on htab->plt_eh_frame section. (elf_backend_plt_alignment): Define to 4. ld/testsuite/ * ld-x86-64/x86-64.exp: Link some testcases with --no-ld-generated-unwind-info. * ld-x86-64/tlsbin.rd: Add --no-ld-generated-unwind-info to ld comment. * ld-x86-64/tlsdesc.dd: Likewise. * ld-x86-64/tlspic.dd: Likewise. * ld-x86-64/tlsdesc.sd: Likewise. * ld-x86-64/tlspic.rd: Likewise. * ld-x86-64/tlsbindesc.rd: Likewise. * ld-x86-64/tlsbindesc.sd: Likewise. * ld-x86-64/tlsbin.td: Likewise. * ld-x86-64/tlsdesc.pd: Likewise. * ld-x86-64/tlsdesc.td: Likewise. * ld-x86-64/tlsbindesc.dd: Likewise. * ld-x86-64/tlsbin.dd: Likewise. * ld-x86-64/tlsgdesc.rd: Likewise. * ld-x86-64/tlspic.sd: Likewise. * ld-x86-64/tlsbindesc.td: Likewise. * ld-x86-64/tlspic.td: Likewise. * ld-x86-64/tlsbin.sd: Likewise. * ld-x86-64/ilp32-4.d: Likewise. * ld-x86-64/tlsgdesc.dd: Add --no-ld-generated-unwind-info to ld comment. Adjust. * ld-x86-64/tlsdesc.rd: Likewise. * ld-x86-64/tlsgd6.dd: Adjust. * ld-x86-64/tlsgd5.dd: Likewise. * ld-i386/i386.exp: Link some testcases with --no-ld-generated-unwind-info. * ld-i386/tlsbin.rd: Add --no-ld-generated-unwind-info to ld comment.. * ld-i386/tlsdesc.dd: Likewise. * ld-i386/tlspic.dd: Likewise. * ld-i386/tlsdesc.sd: Likewise. * ld-i386/tlsgdesc.dd: Likewise. * ld-i386/tlsnopic.sd: Likewise. * ld-i386/tlspic.rd: Likewise. * ld-i386/tlsdesc.rd: Likewise. * ld-i386/tlsbindesc.rd: Likewise. * ld-i386/tlsbindesc.sd: Likewise. * ld-i386/tlsbin.td: Likewise. * ld-i386/tlsdesc.td: Likewise. * ld-i386/tlsnopic.dd: Likewise. * ld-i386/tlsbindesc.dd: Likewise. * ld-i386/tlsbin.dd: Likewise. * ld-i386/tlsgdesc.rd: Likewise. * ld-i386/tlspic.sd: Likewise. * ld-i386/tlsnopic.rd: Likewise. * ld-i386/tlsbindesc.td: Likewise. * ld-i386/tlspic.td: Likewise. * ld-i386/tlsbin.sd: Likewise. --- bfd/elf-eh-frame.c | 56 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 19 deletions(-) (limited to 'bfd/elf-eh-frame.c') diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 21041a5..54142b2 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -778,8 +778,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, } else { - asection *rsec; - /* Find the corresponding CIE. */ unsigned int cie_offset = this_inf->offset + 4 - hdr_id; for (cie = local_cies; cie < local_cies + cie_count; cie++) @@ -795,17 +793,22 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, = cie->cie_inf->add_augmentation_size; ENSURE_NO_RELOCS (buf); - REQUIRE (GET_RELOC (buf)); - - /* Chain together the FDEs for each section. */ - rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie); - /* RSEC will be NULL if FDE was cleared out as it was belonging to - a discarded SHT_GROUP. */ - if (rsec) + if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL) { - REQUIRE (rsec->owner == abfd); - this_inf->u.fde.next_for_section = elf_fde_list (rsec); - elf_fde_list (rsec) = this_inf; + asection *rsec; + + REQUIRE (GET_RELOC (buf)); + + /* Chain together the FDEs for each section. */ + rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie); + /* RSEC will be NULL if FDE was cleared out as it was belonging to + a discarded SHT_GROUP. */ + if (rsec) + { + REQUIRE (rsec->owner == abfd); + this_inf->u.fde.next_for_section = elf_fde_list (rsec); + elf_fde_list (rsec) = this_inf; + } } /* Skip the initial location and address range. */ @@ -1141,6 +1144,9 @@ _bfd_elf_discard_section_eh_frame if (sec_info == NULL) return FALSE; + ptr_size = (get_elf_backend_data (sec->owner) + ->elf_backend_eh_frame_address_size (sec->owner, sec)); + hdr_info = &elf_hash_table (info)->eh_info; for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) if (ent->size == 4) @@ -1149,11 +1155,25 @@ _bfd_elf_discard_section_eh_frame ent->removed = sec->map_head.s != NULL; else if (!ent->cie) { - cookie->rel = cookie->rels + ent->reloc_index; - /* FIXME: octets_per_byte. */ - BFD_ASSERT (cookie->rel < cookie->relend - && cookie->rel->r_offset == ent->offset + 8); - if (!(*reloc_symbol_deleted_p) (ent->offset + 8, cookie)) + bfd_boolean keep; + if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL) + { + unsigned int width + = get_DW_EH_PE_width (ent->fde_encoding, ptr_size); + bfd_vma value + = read_value (abfd, sec->contents + ent->offset + 8 + width, + width, get_DW_EH_PE_signed (ent->fde_encoding)); + keep = value != 0; + } + else + { + cookie->rel = cookie->rels + ent->reloc_index; + /* FIXME: octets_per_byte. */ + BFD_ASSERT (cookie->rel < cookie->relend + && cookie->rel->r_offset == ent->offset + 8); + keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie); + } + if (keep) { if (info->shared && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr @@ -1182,8 +1202,6 @@ _bfd_elf_discard_section_eh_frame sec_info->cies = NULL; } - ptr_size = (get_elf_backend_data (sec->owner) - ->elf_backend_eh_frame_address_size (sec->owner, sec)); offset = 0; for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) if (!ent->removed) -- cgit v1.1