RFH: MIPS ld breaking .eh_frame data ...
Jakub Jelinek
jakub@redhat.com
Tue Sep 26 08:20:00 GMT 2006
On Mon, Sep 18, 2006 at 04:38:22PM -0400, Daniel Jacobowitz wrote:
> On Fri, Sep 15, 2006 at 05:56:38PM -0700, David Daney wrote:
> > The FDE data is unchanged, however its interpretation has changed due to
> > the added PC relative augmentation data in the CIE. Note that the
> > DW_CFA_set_loc in the first instruction pushes the PC out of the range
> > of the function so that the unwinder completly ignores the rest of the
> > FDE program causing a crash at runtime.
> >
> > I used to be able to build (and run) libgcj with slightly older versions
> > of binutils, and gcc.
> >
> > Does this seem like a problem with ld? Or is gcc creating something
> > inconsistent here?
>
> I think that:
> - What GCC is doing is legitimate.
Well, it is not.
a) all the advance_loc*/set_loc in a FDE can never decrease the current
location, only increase it
b) even if a) happened to be the case, you really shouldn't describe PC
ranges outside of the FDE_init_loc...FDE_init_loc+FDE_addr_range,
as the unwinder won't find them anyway
c) using DW_CFA_set_loc unconditionally at the start of each FDE is a
serious space wastage in .eh_frame - while gas can optimize
DW_CFA_advance_loc4 into DW_CFA_advance_loc{1,2}, it doesn't do the
same with DW_CFA_set_loc
The only sane fix is to create 2 FDEs in GCC, one for the hot and one
for the cold part of the function.
> - The linker is at fault for ignoring that some operations would
> need to be changed.
Yes, .eh_frame optimization shouldn't break DW_CFA_set_loc in any case,
looking into it now.
> - You can restore GCC to a less broken state by supressing this
> change for the very first instruction in an FDE, and then the
> linker bug will only trigger with hot/cold sections.
That is really needed as a first step. The 4.1/4.2 change not only
broke MIPS, but all other ELF arches as well, glibc is broken by
this and dozens of other libraries.
Jakub
More information about the Binutils
mailing list