/* This is really horrible. It checks that the stack unwinder understands DW_CFA_def_cfa_expression. It is the result of compiling this: void bbb ( long x ) { __asm__ __volatile__( "cmp %0,%0\n\t" "jz .Lxyzzy\n" ".Lxyzzy:\n\t" : : "r"(x) : "cc" ); } void aaa ( long x ) { bbb(x); } int main ( void ) { long *p = malloc(8); aaa( *p ); return 0; } and bracketing the cmp/jz insns with a move down/up by 256 of %rsp. The .jz causes memcheck to complain, hence unwind the stack, but that cannot be successfully done unless the return address can be found. Hence the handwritten CFI below uses DW_CFA_def_cfa_expression to make that possible. The CFI below isn't really right in that aaa appears twice in the backtrace ==12868== Conditional jump or move depends on uninitialised value(s) ==12868== at 0x400512: bbb (in /home/sewardj/VgTRUNK/trunk/mad0) ==12868== by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0) ==12868== by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0) ==12868== by 0x400538: main (in /home/sewardj/VgTRUNK/trunk/mad0) but GDB behaves the same, so I'm not too concerned - indicates the problem is with the handwritten CFI and not with V's interpretation of it. */ .file "bad0.c" .text .globl bbb .type bbb, @function bbb: .LFB2: .Lbbb1: subq $256,%rsp .Lbbb2: cmp %rdi,%rdi jz .Lxyzzy .Lxyzzy: addq $256,%rsp .Lbbb3: ret .Lbbb4: .LFE2: .size bbb, .-bbb .globl aaa .type aaa, @function aaa: .LFB3: call bbb rep ; ret .LFE3: .size aaa, .-aaa .globl main .type main, @function main: .LFB4: subq $8, %rsp .LCFI0: movl $8, %edi call malloc movq (%rax), %rdi call aaa movl $0, %eax addq $8, %rsp ret .LFE4: .size main, .-main .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .byte 0x1 .string "zR" .uleb128 0x1 .sleb128 -8 .byte 0x10 .uleb128 0x1 .byte 0x3 .byte 0xc .uleb128 0x7 .uleb128 0x8 .byte 0x90 .uleb128 0x1 .align 8 .LECIE1: /* start of the FDE for bbb */ .LSFDE1: .long .LEFDE1-.LASFDE1 /* length of FDE */ .LASFDE1: .long .LASFDE1-.Lframe1 /* CIE pointer */ .long .LFB2 /* & bbb */ .long .LFE2-.LFB2 /* sizeof(bbb) */ .uleb128 0 /* augmentation length */ .byte 0x40 + .Lbbb2 - .Lbbb1 /* _advance_loc to .Lbbb2 */ /* For the section in between .Lbbb2 and .Lbbb3, set the CFA to be %rsp+256, and set the return address (dwarf r16) to be *(CFA+0). */ .byte 0x0f /* _def_cfa_expression */ .uleb128 .Lexpr1e-.Lexpr1s /* length of expression */ .Lexpr1s: .byte 0x77 /* DW_OP_breg7 == %rsp + sleb128(0) */ .sleb128 0 .byte 0x40 /* DW_OP_lit16 */ .byte 0x40 /* DW_OP_lit16 */ .byte 0x1e /* DW_OP_mul */ .byte 0x22 /* DW_OP_plus */ .Lexpr1e: .byte 0x90 /* _cfa_offset: r16 = *(cfa+0) */ .uleb128 0 .byte 0x40 + .Lbbb3 - .Lbbb2 /* _advance_loc to .Lbbb3 */ /* For the section .Lbbb3 to .Lbbb4, should set CFA back to something sensible. This tries to do it but still causes GDB to show an extraneous aaa frame on the stack. Oh well. */ /* Now set CFA back to %rsp+0 */ .byte 0x0f /* _def_cfa_expression */ .uleb128 .Lexpr2e-.Lexpr2s /* length of expression */ .Lexpr2s: .byte 0x77 /* DW_OP_breg7 == %rsp + sleb128(0) */ .sleb128 0 .byte 0x30 /* DW_OP_lit0 */ .byte 0x1c /* DW_OP_minus */ .Lexpr2e: .byte 0x90 /* _cfa_offset: r16 = *(cfa+0) */ .uleb128 0 .byte 0x40 + .Lbbb4 - .Lbbb3 /* _advance_loc to .Lbbb4 */ .uleb128 0x0 /* ??? */ .align 8 .LEFDE1: /* end of the FDE for bbb */ .LSFDE3: .long .LEFDE3-.LASFDE3 .LASFDE3: .long .LASFDE3-.Lframe1 .long .LFB3 .long .LFE3-.LFB3 .uleb128 0x0 .align 8 .LEFDE3: .LSFDE5: .long .LEFDE5-.LASFDE5 .LASFDE5: .long .LASFDE5-.Lframe1 .long .LFB4 .long .LFE4-.LFB4 .uleb128 0x0 .byte 0x4 .long .LCFI0-.LFB4 .byte 0xe .uleb128 0x10 .align 8 .LEFDE5: .ident "GCC: (GNU) 4.1.2 20061115 (prerelease) (SUSE Linux)" .section .note.GNU-stack,"",@progbits