This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/13158] New: bad unwind info as a result of sibcall
- From: "davidm at hpl dot hp dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 22 Nov 2003 02:52:26 -0000
- Subject: [Bug c/13158] New: bad unwind info as a result of sibcall
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
I have a distinct feeling of deja vue here, but I can't find any previous
discussion around this, so maybe it was never reported. Anyhow, the problem is
that when GCC applies the sibcall optimization on ia64, it doesn't emit proper
unwind info. Example:
$ cat bug.c
extern int foo (int);
int main (int argc, char **argv) {
printf ("hello\n");
return foo (argc);
}
int foo (int arg) {
return 0;
}
$ gcc -v
Reading specs from /opt/gcc-pre3.4/lib/gcc/ia64-hp-linux/3.4/specs
Configured with: : (reconfigured) : (reconfigured) : (reconfigured) :
(reconfigured)
Thread model: posix
gcc version 3.4 20031121 (experimental)
$ gcc -O2 -c bug.c
$ readelf -u bug.o
Unwind section '.IA_64.unwind' at offset 0xd0 contains 1 entries:
<main>: [0x10-0x70], info at +0x0
v1, flags=0x0 (), len=8 bytes
R2:prologue_gr(mask=[rp,ar.pfs],grsave=r33,rlen=5)
P7:pfs_when(t=0)
P7:rp_when(t=2)
R1:body(rlen=13)
$ objdump -d bug.o | tail -19
0000000000000010 <main>:
10: 0c 10 15 08 80 05 [MFI] alloc r34=ar.pfs,5,4,0
16: 00 00 00 02 00 20 nop.f 0x0
1c: 04 00 c4 00 mov r33=b0
20: 02 20 01 02 00 24 [MII] addl r36=0,r1
26: 30 02 04 00 42 00 mov r35=r1;;
2c: 00 00 04 00 nop.i 0x0
30: 1d 20 01 48 18 10 [MFB] ld8 r36=[r36]
36: 00 00 00 02 00 00 nop.f 0x0
3c: 08 00 00 50 br.call.sptk.many b0=30;;
40: 01 08 00 46 00 21 [MII] mov r1=r35
46: 00 08 05 80 03 00 mov b0=r33
4c: 20 02 aa 00 mov.i ar.pfs=r34;;
50: 1d 10 04 00 80 05 [MFB] alloc r2=ar.pfs,1,0,0
56: 00 00 00 02 00 00 nop.f 0x0
5c: 08 00 00 40 br.many 50 <main+0x40>;;
60: 1d 00 00 00 01 00 [MFB] nop.m 0x0
66: 00 00 00 00 00 00 break.f 0x0
6c: 00 00 00 20 nop.b 0x0;;
The problem here is that the unwind info claims that even for the last six
instructions, ar.pfs is saved in r34 and rp in r33. But after the "alloc"
instruction, those registers are not really valid anymore. In particular, if
execution gets interrupted anywhere in the last six instructions, the contents
of those no-longer-allocated registers may get clobbered and at that point
unwinding may no longer be possible.
The best fix that I can think of would be to emit
.restore sp
right before the instruction that restores ar.pfs (i.e., before the 7th-last
instruction). That would tell the unwinder that for the last six instructions,
rp and ar.pfs can be found in the default location (and nothing else has been
saved). Of course, if a function has a memory stack frame, then the .restore sp
will be generated naturally for the instruction that restores the sp, so no such
dummy ".restore sp" directive would be needed.
--
Summary: bad unwind info as a result of sibcall
Product: gcc
Version: 3.4
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: davidm at hpl dot hp dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: ia64-hp-linux
GCC host triplet: ia64-hp-linux
GCC target triplet: ia64-hp-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13158