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