http://sourceware.org/bugzilla/show_bug.cgi?id=13909
Bug #: 13909 Summary: PR ld/12570 causes eh_frame_hdr section to be sometimes too large Product: binutils Version: 2.22 Status: NEW Severity: normal Priority: P2 Component: ld AssignedTo: unassig...@sourceware.org ReportedBy: deve...@kristov.de Classification: Unclassified Created attachment 6304 --> http://sourceware.org/bugzilla/attachment.cgi?id=6304 corrects size of .eh_frame_hdr section when there are no entries under certain circumstances Hello, PR ld/12570 added unwind information for PLT. However, there is a small problem when the automatically generated .eh_frame is the only one: There is no binary_search table generated in the .eh_frame_hdr section, at least when targetting elf32-i386. Check the following example kristov@peacock ~/tmp/eh $ gcc -o test.so -shared -lc test.c -nostartfiles -nodefaultlibs with test.c being empty (and binutils-2.22 or HEAD). The result is: kristov@peacock ~/tmp/eh $ objdump -s -j .eh_frame_hdr -j .eh_frame test.so test.so: file format elf32-i386 Contents of section .eh_frame_hdr: 015c 011bffff 08000000 00000000 ............ Contents of section .eh_frame: 0168 14000000 00000000 017a5200 017c0801 .........zR..|.. 0178 1b0c0404 88010000 24000000 1c000000 ........$....... 0188 00000000 00000000 000e0846 0e0c4a0f ...........F..J. 0198 0b740478 003f1a3b 2a322422 00000000 .t.x.?.;*2$".... We have a eh_frame_hdr with no binary_search table. Additionally, the section is too long (8 bytes would suffice); the last four bytes in the section are essentially undefined and can differ from build to build. I tried to analyse this but was not able to completely understand the code. What I found out is the following: BEFORE ALLOCATION: bfd_elf_size_dynamic_sections(elflink.c) =========================================================== - When _bfd_elf_maybe_strip_eh_frame_hdr(elf-eh-frame.c) gets called, it finds that there is a .eh_frame section in libc.so with a CIE/FDE > 8 bytes and sets hdr_info->table to TRUE. AFTER ALLOCATION: bfd_elf_discard_info(elflink.c) ================================================= - The autogenerated section (created by elf_i386_create_dynamic_sections(elf32-i386.c)) is neither parsed by _bfd_elf_parse_eh_frame(elf-eh-frame.c) (called by bfd_elf_discard_info(elflink.c)), as it is marked as DYNAMIC (belonging to dynamic libc.so). Thus, sec_info_type is not set to ELF_INFO_TYPE_EH_FRAME. Furthermore, _bfd_elf_discard_section_eh_frame(elf-eh-frame.c) is never called on this section, such that hdr_info->fde_count remains zero. Even if it was called, it would return immediately because sec_info_type != ELF_INFO_TYPE_EH_FRAME. - _bfd_elf_discard_section_eh_frame_hdr(elf-eh.frame.c) is always called at the end. Because hdr_info->table == TRUE, the size is computed to EH_FRAME_HDR_SIZE + 4 + hdr_info->fde_count == 12, as hdr_info->fde_count == 0. FINAL LINK ========== - As the autogenerated section has not been built by bfd_elf_write_section_eh_frame(elf-eh-frame.c), hdr_info->array remains empty (and hdr_info->array_count remains zero). - Finally, when _bfd_elf_write_section_eh_frame_hdr(elf-eh-frame.c) is called by bld_elf_final_link(elflink.c), we have hdr_info->table == TRUE, hdr_info->array == NULL, hdr_info->array_count == 0 and hdr_info->fde_count == 0. This results in a section of size EH_FRAME_HDR_SIZE (8 bytes) with contents[2] == contents[3] == DW_EH_PE_omit ALTHOUGH the section size previously set by _bfd_elf_discard_section_eh_frame_hdr is four bytes larger. That means that the last four bytes are possibly random, resulting in irreproducible binaries. WORKAROUND ========== I "solved" this problem by the patch attached. Basically, in _bfd_elf_discard_section_eh_frame_hdr(elf-eh.frame.c), I changed the line if (hdr_info->table) to if (hdr_info->table && hdr_info->fde_count > 0) in order to account for the situation described above. This does not put a binary_search table into the .eh_frame_hdr section (which is not needed, I think, because there is only one CIE/FDE in .eh_frame anyway), but it does reduce the section size and avoids random bytes in the section. The patched linker produces the following result kristov@peacock ~/tmp/eh $ objdump -s -j .eh_frame_hdr -j .eh_frame test.so test.so: file format elf32-i386 Contents of section .eh_frame_hdr: 015c 011bffff 04000000 ........ Contents of section .eh_frame: 0164 14000000 00000000 017a5200 017c0801 .........zR..|.. 0174 1b0c0404 88010000 24000000 1c000000 ........$....... 0184 00000000 00000000 000e0846 0e0c4a0f ...........F..J. 0194 0b740478 003f1a3b 2a322422 00000000 .t.x.?.;*2$".... which is IMHO better. Regards, Christoph Schulz -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils