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. --- ld/ChangeLog | 6 ++++++ ld/emultempl/ppc64elf.em | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index 54c2755..d065c3a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2014-08-22 Alan Modra + + * 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. + 2014-08-20 Maciej W. Rozycki * emultempl/armelf.em (OPTION_STUBGROUP_SIZE): Fix formatting. diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index 3e316af..914fc52 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -460,19 +460,6 @@ gld${EMULATION_NAME}_after_allocation (void) { int ret; - /* bfd_elf_discard_info just plays with data and debugging sections, - ie. doesn't affect code size, so we can delay resizing the - sections. It's likely we'll resize everything in the process of - adding stubs. */ - ret = bfd_elf_discard_info (link_info.output_bfd, &link_info); - if (ret < 0) - { - einfo ("%X%P: .eh_frame/.stab edit: %E\n"); - return; - } - else if (ret > 0) - need_laying_out = 1; - /* If generating a relocatable output file, then we don't have any stubs. */ if (stub_file != NULL && !link_info.relocatable) @@ -480,7 +467,7 @@ gld${EMULATION_NAME}_after_allocation (void) ret = ppc64_elf_setup_section_lists (&link_info); if (ret < 0) einfo ("%X%P: can not size stub section: %E\n"); - else if (ret > 0) + else { ppc64_elf_start_multitoc_partition (&link_info); @@ -510,6 +497,19 @@ gld${EMULATION_NAME}_after_allocation (void) } } + /* We can't parse and merge .eh_frame until the glink .eh_frame has + been generated. Otherwise the glink .eh_frame CIE won't be + merged with other CIEs, and worse, the glink .eh_frame FDEs won't + be listed in .eh_frame_hdr. */ + ret = bfd_elf_discard_info (link_info.output_bfd, &link_info); + if (ret < 0) + { + einfo ("%X%P: .eh_frame/.stab edit: %E\n"); + return; + } + else if (ret > 0) + need_laying_out = 1; + if (need_laying_out != -1) { gld${EMULATION_NAME}_map_segments (need_laying_out); -- cgit v1.1