relaxation segv

Richard Henderson rth@redhat.com
Sun Mar 11 01:08:00 GMT 2001


The attached test case will segfault on i386.

The direct cause for the segv is that when local symbols are
finalized, their fragment is nulled.

The deeper reason is that the section containing the .uleb128
was relaxed before the section containing the labels.  Which
meant that the .uleb128 got incorrect values for the symbols,
since their fr_address were all still zero.  Also, when
cvt_frag_to_fill ran for the leb128, it finalized the symbols,
which resulted in them being fixed to incorrect values.  And
also happens to cause a segv here:

relax_frag (segment=0x8108940, fragP=0x810eab8, stretch=11)
    at ../../../src/gas/write.c:2062
2062          target += S_GET_VALUE (symbolP) + sym_frag->fr_address;

Now, what I'm most concerned about is how this ever worked.
My guess is "by accident".  It's currently dependant on what
order the sections exist in the bfd.

If a relaxation expresion involves differences between symbols
in a different section, then we need to relax the sections in
the proper order.  Moreover, there can be loops in the dependancy
graph that require us to re-run relaxation on a section.

However, this is somewhat difficult, and is not aided by the
fact that it currently doesn't work to re-run relax_section
(you'll get aborts in cvt_frag_to_fill for unknown reasons).

Something that does work for this test case is to relax all the
code sections before all the data sections.  I have a feeling
this catches the bulk of the interesting cases, as happens with
EH data and Dwarf2 frame data.  Thus the attached patch.

Anyone got any better ideas?


r~


More information about the Binutils mailing list