[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