Bug 115881 - ld mangles eh_frame (is too relaxed, causing bad fill)
Summary: ld mangles eh_frame (is too relaxed, causing bad fill)
Alias: None
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: binutils   
(Show other bugs)
Version: 3.0
Hardware: i386
OS: Linux
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
Depends On:
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:
Story Points: ---
Clone Of:
Last Closed: 2004-05-12 03:50:04 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

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

External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2004:140 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):

How reproducible:

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

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]

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.


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