bug-binutils
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]