From da44f4e5464f82dec79eb5885961c6466dd3bf6a Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 22 Aug 2014 09:07:35 +0930 Subject: Index PowerPC64 linker generated .eh_frame in .eh_frame_hdr I noticed recently that .eh_frame FDEs generated by the linker for call stubs and .glink weren't being indexed in .eh_frame_hdr, due to bfd_elf_discard_info being run before the linker generated .eh_frame sections were available for parsing. This patch moves code around in elf64-ppc.c and ppc64elf.em to avoid that problem. Another problem fixed here is that --gc-sections parses .eh_frame early, and the existing machinery allows only one go at parsing the .eh_frame sections. That resulted in the linker generated .eh_frame CIEs not being merged and no .eh_frame_hdr index entries for those FDEs. It turns out that all the info from parsing .eh_frame is attached to the section, so order of parsing isn't important, and after parsing sec_info_type being set will prevent a section being parsed again. At least, when parsing doesn't hit an error. So there isn't really any need for "parsed_eh_frame". "merge_cies" is also redundant, which means _bfd_elf_{begin,end}_eh_frame_parsing can also disappear. bfd/ * elf-bfd.h (struct eh_frame_hdr_info): Delete merge_cies and parsed_eh_frames. (_bfd_elf_begin_eh_frame_parsing): Delete. (_bfd_elf_end_eh_frame_parsing): Delete. * elf-eh-frame.c (_bfd_elf_begin_eh_frame_parsing): Delete. (_bfd_elf_end_eh_frame_parsing): Delete. (_bfd_elf_parse_eh_frame): Don't test parsed_eh_frame. Test !info->relocatable in place of merge_cies. * elflink.c (bfd_elf_gc_sections, bfd_elf_discard_info): Adjust. * elf64-ppc.c (glink_eh_frame_cie): Pad to multiple of 8. (ppc64_elf_size_stubs): Likewise pad stub FDE. (ppc64_elf_build_stubs): Move code setting glink .eh_frame to.. (ppc64_elf_size_stubs): ..here and.. (ppc64_elf_finish_dynamic_sections): ..here. ld/ * emultempl/ppc64elf.em (gld${EMULATION_NAME}_after_allocation): Call bfd_elf_discard_info after generating glink .eh_frame. Delete redundant test on ppc64_elf_setup_section_lists status. --- bfd/elf-eh-frame.c | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) (limited to 'bfd/elf-eh-frame.c') diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 0f0a563..7783b08 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -452,18 +452,6 @@ make_pc_relative (unsigned char encoding, unsigned int ptr_size) return encoding | DW_EH_PE_pcrel; } -/* Called before calling _bfd_elf_parse_eh_frame on every input bfd's - .eh_frame section. */ - -void -_bfd_elf_begin_eh_frame_parsing (struct bfd_link_info *info) -{ - struct eh_frame_hdr_info *hdr_info; - - hdr_info = &elf_hash_table (info)->eh_info; - hdr_info->merge_cies = !info->relocatable; -} - /* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the information in the section's sec_info field on success. COOKIE describes the relocations in SEC. */ @@ -494,8 +482,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, htab = elf_hash_table (info); hdr_info = &htab->eh_info; - if (hdr_info->parsed_eh_frames) - return; if (sec->size == 0 || sec->sec_info_type != SEC_INFO_TYPE_NONE) @@ -777,7 +763,8 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, buf += initial_insn_length; ENSURE_NO_RELOCS (buf); - if (hdr_info->merge_cies) + if (!info->relocatable) + /* Keep info for merging cies. */ this_inf->u.cie.u.full_cie = cie; this_inf->u.cie.per_encoding_relative = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel; @@ -911,8 +898,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, elf_section_data (sec)->sec_info = sec_info; sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME; - if (hdr_info->merge_cies) + if (!info->relocatable) { + /* Keep info for merging cies. */ sec_info->cies = local_cies; local_cies = NULL; } @@ -933,17 +921,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, #undef REQUIRE } -/* Finish a pass over all .eh_frame sections. */ - -void -_bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info) -{ - struct eh_frame_hdr_info *hdr_info; - - hdr_info = &elf_hash_table (info)->eh_info; - hdr_info->parsed_eh_frames = TRUE; -} - /* Mark all relocations against CIE or FDE ENT, which occurs in .eh_frame section SEC. COOKIE describes the relocations in SEC; its "rel" field can be changed freely. */ -- cgit v1.1