[PATCH][SH] CFI directives patch
Thomas Schwinge
thomas@codesourcery.com
Thu May 24 12:10:00 GMT 2012
Hi!
On Wed, 23 May 2012 19:57:20 +0800, Chung-Lin Tang <cltang@codesourcery.com> wrote:
> On 2012/5/23 07:35 PM, Thomas Schwinge wrote:
> > On Fri, 11 May 2012 17:15:52 +0800, Chung-Lin Tang <chunglin.tang@gmail.com> wrote:
> >>>> diff --git a/sysdeps/unix/sh/sysdep.S b/sysdeps/unix/sh/sysdep.S
> >>>> index e816575..939eb9a 100644
> >>>> --- a/sysdeps/unix/sh/sysdep.S
> >>>> +++ b/sysdeps/unix/sh/sysdep.S
> >>>> @@ -41,13 +41,15 @@ skip:
> >>>> sts.l pr, @-r15
> >>>> cfi_adjust_cfa_offset (4)
> >>>> cfi_rel_offset (pr, 0)
> >>>> + cfi_adjust_cfa_offset (4)
> >>>> jsr @r1
> >>>> mov.l r0, @-r15
> >>>> - cfi_adjust_cfa_offset (4)
> >>>
> >>> Hmm?
> >>
> >> I think this was to fix the case of a frame-insn in a call delay slot
> >> kind of problem. Imagine unwinding from inside the @r1 function (here
> >> it's errno); it will get the stack position one word off.
> >
> > Hmm, that doesn't match my understanding. The CFI of the caller is of no
> > interested to the callee: the CFI is purely a local thing for the
> > instructions with addresses between the .cfi_startproc and .cfi_endproc
> > directives (to compute the beginning of the frame based on SP's value in
> > this case). The callee will have its own CFI to compute the frame
> > address based on the value of the SP (which will have been decremented
> > before @r1 is executed) and its own CFI between .cfi_startproc and
> > .cfi_endproc.
> >
> >> But reviewing it, I think it's better to move the frame-insn (and CFI)
> >> above the call and just fill nop.
> >
> > With my reasoning above (and please someone tell me if I'm wrong), there
> > is no need to do that (and avoid the slight code pessimization).
>
> With a stack adjustment in the call delay slot, the unwinder will be
> 4-bytes off the correct adjustment when crossing that frame; this
> probably is an issue of how program counters map to FDEs (< vs <=).
I see. But -- with the following trivial example -- this does work fine
for me; GDB does get it right that the PC has advanced by two
instructions after an instruction with a delay slot has been
single-stepped. Am I perhaps doing something wrong, or is my example
wrong?
$ install/bin/*-gcc -Wall -o cfitest_main.o -c cfitest_main.c -O -g
$ install/bin/*-gcc -Wall -o cfitest.s.orig -S cfitest.c -O -funwind-tables
$ cp cfitest.s.orig cfitest.S
$ $EDITOR cfitest.S # add r0 push/pop and CFI; see attached cfitest.S
$ install/bin/*-gcc -Wall -o cfitest cfitest_main.o cfitest.S
With »#define CFI 1«: run cfitest through gdbserver, »break main«,
»continue«, repeat »si« until we're in »c«:
0x00400484 in c ()
(gdb) bt
#0 0x00400484 in c ()
#1 0x00400490 in b ()
#2 0x004004a4 in a ()
#3 0x00400478 in main () at cfitest_main.c:4
(gdb) disassemble
Dump of assembler code for function c:
=> 0x00400484 <+0>: rts
0x00400486 <+2>: mov #29,r0
End of assembler dump.
(gdb) frame 1
#1 0x00400490 in b ()
(gdb) disassemble
Dump of assembler code for function b:
0x00400488 <+0>: sts.l pr,@-r15
0x0040048a <+2>: mov.l 0x400498 <b+16>,r0 ! 0x400484 <c>
0x0040048c <+4>: jsr @r0
0x0040048e <+6>: mov.l r0,@-r15
=> 0x00400490 <+8>: mov.l @r15+,r0
0x00400492 <+10>: lds.l @r15+,pr
0x00400494 <+12>: rts
0x00400496 <+14>: nop
0x00400498 <+16>: mov.b r8,@(r0,r4)
0x0040049a <+18>: .word 0x0040
End of assembler dump.
(gdb) frame 2
#2 0x004004a4 in a ()
(gdb) disassemble
Dump of assembler code for function a:
0x0040049c <+0>: sts.l pr,@-r15
0x0040049e <+2>: mov.l 0x4004ac <a+16>,r0 ! 0x400488 <b>
0x004004a0 <+4>: jsr @r0
0x004004a2 <+6>: mov.l r0,@-r15
=> 0x004004a4 <+8>: mov.l @r15+,r0
0x004004a6 <+10>: lds.l @r15+,pr
0x004004a8 <+12>: rts
0x004004aa <+14>: nop
0x004004ac <+16>: .word 0x0488
0x004004ae <+18>: .word 0x0040
End of assembler dump.
(gdb) frame 3
#3 0x00400478 in main () at cfitest_main.c:4
4 return a();
(gdb) disassemble
Dump of assembler code for function main:
0x00400470 <+0>: sts.l pr,@-r15
0x00400472 <+2>: mov.l 0x400480 <main+16>,r0 ! 0x40049c <a>
0x00400474 <+4>: jsr @r0
0x00400476 <+6>: nop
=> 0x00400478 <+8>: lds.l @r15+,pr
0x0040047a <+10>: rts
0x0040047c <+12>: nop
0x0040047e <+14>: nop
0x00400480 <+16>: mov.b @(r0,r9),r4
0x00400482 <+18>: .word 0x0040
End of assembler dump.
The backtrace from c is fine, and when switching the frames manually, the
disassembly always points to the instruction after the delay slot.
> CCing Richard Henderson here, who's probably the one to answer this.
> Richard, I remember seeing related discussion in the archives on this
> issue, as well as comments in the current GCC dwarf2cfi.c:scan_trace()
> code, can you confirm?
Grüße,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cfitest_main.c
Type: text/x-csrc
Size: 51 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120524/4a9b4b9d/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cfitest.c
Type: text/x-csrc
Size: 91 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120524/4a9b4b9d/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cfitest.S
Type: text/x-csrc
Size: 1039 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120524/4a9b4b9d/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120524/4a9b4b9d/attachment.sig>
More information about the Libc-alpha
mailing list