[Bug middle-end/29166] broken unwind information for many life variables resulting in register corruption

2006-09-21 Thread matz at gcc dot gnu dot org


--- Comment #1 from matz at gcc dot gnu dot org  2006-09-21 13:35 ---
Created an attachment (id=12303)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=12303action=view)
Breaking testcase.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29166



[Bug middle-end/29166] broken unwind information for many life variables resulting in register corruption

2006-09-21 Thread matz at gcc dot gnu dot org


--- Comment #2 from matz at gcc dot gnu dot org  2006-09-21 13:39 ---
Some more analysis of the original bugreport (
https://bugzilla.novell.com/show_bug.cgi?id=201157 ) :

For gcc version 4.1.2 20060731 (prerelease) (SUSE Linux),
r4-r7 contain before the call:
  86, 87, 88, 89
and after the call:
  87, 88, 89, 4611686018427403552
(gdb) p/x $r7
$2 = 0x40003d20
(gdb) info symbol $r7
test() + 64 in section .text
(gdb) b *$r7
Breakpoint 4 at 0x40003d20: file unw.cc, line 85.
(gdb) l 85
80  }
81
82  void test()
83  {
84  try {
85   doIt();
86  } catch( Ex ) { }
87  }
88
89  int main(char** argv, int argc)

The address in r7 is the return address of the call.  I googled a bit for
unwind ia64 r4 and found e.g. this:
  http://www.gelato.unsw.edu.au/archives/linux-ia64/0506/14430.html
This is a patch for the kernel, but it's about using some wrong code
in it's own unwinder leading to clobber r4-7, so perhaps similar code is
used in libunwind?

Looks like the unwind information is broken, the addresses for the register
contents for r4-r7 is off-by-8.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29166



[Bug middle-end/29166] broken unwind information for many life variables resulting in register corruption

2006-09-21 Thread matz at gcc dot gnu dot org


--- Comment #3 from matz at gcc dot gnu dot org  2006-09-21 13:40 ---
Hmpf.  I wonder if there's any tool to really inspect the unwind info, like
it is possible for dwarf.  But readelf doesn't help very much:

% readelf -wf a.out
nothing, no wonder, it's no dwarf
% readelf -u a.out
...
_Z4doItv: [0x4b00-0x40003ce0], info at +0x87b0
  v1, flags=0x0 (), len=40 bytes
R2:prologue_gr(mask=[psp],grsave=r119,rlen=49)

P5:frgr_mem(grmask=[r4,r5,r6,r7],frmask=[f2,f3,f4,f5,f16,f17,f18,f19,f20,f21,f22,f23,f24,f25,f26,f27,f28,f29,f30,f31])

P4:spill_mask(imask=[---,---,---,---,rr-,rr-,-f-,ff-,ff-,ff-,ff-,ff-,ff-,ff-,ff-,ff-,f])
P7:mem_stack_v(t=3)
P7:unat_when(t=7)
P7:unat_psprel(pspoff=0x10-0x180)
P7:pfs_when(t=9)
P7:pfs_psprel(pspoff=0x10-0x178)
P7:rp_when(t=18)
P7:rp_psprel(pspoff=0x10-0x148)
R3:body(rlen=2345)
R1:prologue(rlen=0)
R1:prologue(rlen=0)

_Z4testv: [0x40003ce0-0x40003db0], info at +0x87e0
  v1, flags=0x3 ( ehandler uhandler), len=16 bytes
R2:prologue_gr(mask=[rp,ar.pfs,psp],grsave=r32,rlen=5)
P7:pfs_when(t=0)
P7:mem_stack_v(t=1)
P7:rp_when(t=4)
R3:body(rlen=34)
B2:epilogue(t=2,ecount=0)
R1:prologue(rlen=0)
R1:prologue(rlen=0)
R1:prologue(rlen=0)

I traced the things in libunwind a bit, and know that the one writing the
wrong location of R4-7 into context-loc is the IA64_INSN_ADD_PSP_NAT
unwind script instruction, interpreted in _ULia64_find_save_locs (in
run_script actually).  And it happens while context still is set to the
doIt() function.  But I have no idea, how that script is generated,
or how it relates to the assembler file.  For instance, the start of doIt()
has this code:

.save.g 0x1
.mem.offset 344, 0  //
st8.spill [r18] = r4, 16//,
;;
.save.g 0x2
.mem.offset 336, 0  //
st8.spill [r17] = r5, 16//,
.save.g 0x4
.mem.offset 328, 0  //
st8.spill [r18] = r6, 16//,
;;
.save.g 0x8
.mem.offset 320, 0  //
st8.spill [r17] = r7, 16//,

I assume (because there are no explicit unwind sections in the assembler
source) that these .save.g and .mem.offset somehow are pseudo instructions
which somehow produce unwind info.  But I'm at a loss here.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29166