This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][SH] CFI directives patch


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

int main()
{
  extern int a(void);
  return a();
}
int c(void)
{
  return 29;
}

int b(void)
{
  return c();
}

int a(void)
{
  return b();
}
#define CFI 1

	.file	"cfitest.c"
	.text
	.little
	.text
	.align 1
	.global	c
	.type	c, @function
c:
.LFB0:
	.cfi_startproc
	rts	
	mov	#29,r0
	.cfi_endproc
.LFE0:
	.size	c, .-c
	.align 1
	.global	b
	.type	b, @function
b:
.LFB1:
	.cfi_startproc
	sts.l	pr,@-r15
	.cfi_def_cfa_offset 4
	.cfi_offset 17, -4
	mov.l	.L3,r0
	jsr	@r0
         mov.l r0, @-r15
#if CFI
        .cfi_adjust_cfa_offset 4
#endif
        mov.l @r15+, r0
#if CFI
        .cfi_adjust_cfa_offset -4
#endif
	lds.l	@r15+,pr
	rts	
	nop
.L4:
	.align 2
.L3:
	.long	c
	.cfi_endproc
.LFE1:
	.size	b, .-b
	.align 1
	.global	a
	.type	a, @function
a:
.LFB2:
	.cfi_startproc
	sts.l	pr,@-r15
	.cfi_def_cfa_offset 4
	.cfi_offset 17, -4
	mov.l	.L6,r0
	jsr	@r0
         mov.l r0, @-r15
#if CFI
        .cfi_adjust_cfa_offset 4
#endif
        mov.l @r15+, r0
#if CFI
        .cfi_adjust_cfa_offset -4
#endif
	lds.l	@r15+,pr
	rts	
	nop
.L7:
	.align 2
.L6:
	.long	b
	.cfi_endproc
.LFE2:
	.size	a, .-a
	.ident	"GCC: (GNU) 4.8.0 20120426 (experimental)"
	.section	.note.GNU-stack,"",@progbits

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]