Bug 115881 - ld mangles eh_frame (is too relaxed, causing bad fill)
Summary: ld mangles eh_frame (is too relaxed, causing bad fill)
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: binutils
Version: 3.0
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2004-02-16 20:44 UTC by Todd Allen
Modified: 2007-11-30 22:07 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2004-05-12 03:50:04 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
too_relaxed (546 bytes, text/plain)
2004-02-16 20:45 UTC, Todd Allen
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2004:140 0 normal SHIPPED_LIVE binutils bug fix and enhancement update 2004-05-11 04:00:00 UTC

Description Todd Allen 2004-02-16 20:44:41 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; Galeon)
Gecko/20031114 Galeon/1.3.10

Description of problem:
New versions of ld appear to have code which compresses .eh_frame
information by coalescing identical CIE's.  Good idea.  However,
sometimes when it does this, it takes an .eh_frame section which was
padded out to the appropriate alignment (e.g. 4) and removes material
from it which leaves it improperly padded.  When this happens, ld
inserts *fill* bytes.  But that's a problem in .eh_frame, because each
.eh_frame entry (CIE or FDE) knows its own length, and that length is
used to compute the address or offset of the next entry.  Those
lengths know nothing about any *fill* bytes, are are not adjusted by
the code which coalesces CIE's.  So, Dwarf consumers try to interpret
those *fill* bytes as the start of a CIE or FDE and get very confused.

gcc appears to be very careful always to pad its .eh_frame sections
out to a multiple of the alignment, so that no *fill* bytes can
interfere with the lengths in the FDE's.  However, it seems to do this
on a per-object-file basis.  That is, it doesn't make any effort to
pad out individual CIE's or FDE's.  This is how the removal of a CIE
can cause the pad for a section which was correct to become incorrect.

This bug was found with a real-world example, but it was quite large.
 So, I generated a tiny example that's just an ld invocation with no
object files required beyond what's in glibc.  It creates a degenerate
program that probably wouldn't even run, but it's not meant to run,
only to illustrate this bug.


Version-Release number of selected component (if applicable):
binutils-2.14.90.0.4-26

How reproducible:
Always

Steps to Reproduce:
1. Execute "too_relaxed" script (included as attachment)
2.
3.
    

Actual Results:  The MAP file produced by the link shows *fill* bytes
in the .eh_frame.
The readelf -wf invocation dies with a Memory Fault.

Expected Results:  The MAP file should have no *fill* bytes in the
.eh_frame section.
The readelf -wf invocation should not die.


Additional info:

This problem also is present in Fedora Core 1.  I have found no
workaround as yet.  

A quick & dirty fix in the binutils source would be, in
_bfd_elf_discard_section_eh_frame, after calling cie_compare(), simply
determine if the size of the CIE is a multiple of the alignment of the
.eh_frame section, and refuse to coalesce CIE's if their size is not a
multiple of the section's alignment.

A better fix would be, after removal of the CIE, to correct the pad,
using DW_CFA_nop's, and update the FDE lengths appropriately.

Comment 1 Todd Allen 2004-02-16 20:45:44 UTC
Created attachment 97716 [details]
too_relaxed

Comment 2 John Flanagan 2004-05-12 03:50:05 UTC
An errata has been issued which should help the problem described in this bug report. 
This report is therefore being closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files, please follow the link below. You may reopen 
this bug report if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2004-140.html



Note You need to log in before you can comment on or make changes to this bug.