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] | |
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] |