[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/13909] New: PR ld/12570 causes eh_frame_hdr section to be someti
From: |
develop at kristov dot de |
Subject: |
[Bug ld/13909] New: PR ld/12570 causes eh_frame_hdr section to be sometimes too large |
Date: |
Tue, 27 Mar 2012 21:47:54 +0000 |
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: address@hidden
ReportedBy: address@hidden
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
address@hidden ~/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:
address@hidden ~/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
address@hidden ~/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 ld/13909] New: PR ld/12570 causes eh_frame_hdr section to be sometimes too large,
develop at kristov dot de <=