]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a regression test for unwind handling of DW_CFA_def_cfa_expression.
authorJulian Seward <jseward@acm.org>
Wed, 28 Feb 2007 13:27:37 +0000 (13:27 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 28 Feb 2007 13:27:37 +0000 (13:27 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6628

memcheck/tests/amd64/Makefile.am
memcheck/tests/amd64/defcfaexpr.S [new file with mode: 0644]
memcheck/tests/amd64/defcfaexpr.stderr.exp [new file with mode: 0644]
memcheck/tests/amd64/defcfaexpr.vgtest [new file with mode: 0644]

index b11dfc34da43701da6f2abb90d1bbb4ce23886de..2a5b5bc61e6fb27240e2476b7ba3a953c2dda589 100644 (file)
@@ -11,13 +11,14 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        bt_everything.stderr.exp bt_everything.stdout.exp \
                bt_everything.vgtest \
        bug132146.vgtest bug132146.stderr.exp bug132146.stdout.exp \
+       defcfaexpr.vgtest defcfaexpr.stderr.exp \
        fxsave-amd64.vgtest fxsave-amd64.stdout.exp fxsave-amd64.stderr.exp \
        more_x87_fp.stderr.exp more_x87_fp.stdout.exp more_x87_fp.vgtest \
        sse_memory.stderr.exp sse_memory.stdout.exp sse_memory.vgtest \
        xor-undef-amd64.stderr.exp xor-undef-amd64.stdout.exp \
        xor-undef-amd64.vgtest
 
-check_PROGRAMS = bt_everything bug132146 fxsave-amd64 \
+check_PROGRAMS = bt_everything bug132146 defcfaexpr fxsave-amd64 \
                more_x87_fp sse_memory xor-undef-amd64
 
 AM_CPPFLAGS = -I$(top_srcdir)/include
@@ -28,3 +29,5 @@ AM_CXXFLAGS = $(AM_CFLAGS)
 more_x87_fp_CFLAGS     = $(AM_CFLAGS) -O -ffast-math -mfpmath=387 \
                                -mfancy-math-387
 more_x87_fp_LDADD      = -lm
+
+defcfaexpr_SOURCES     = defcfaexpr.S
diff --git a/memcheck/tests/amd64/defcfaexpr.S b/memcheck/tests/amd64/defcfaexpr.S
new file mode 100644 (file)
index 0000000..23306b2
--- /dev/null
@@ -0,0 +1,186 @@
+
+/* 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
diff --git a/memcheck/tests/amd64/defcfaexpr.stderr.exp b/memcheck/tests/amd64/defcfaexpr.stderr.exp
new file mode 100644 (file)
index 0000000..7a24ccd
--- /dev/null
@@ -0,0 +1,5 @@
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: bbb (in ...)
+   by 0x........: aaa (in ...)
+   by 0x........: aaa (in ...)
+   by 0x........: main (in ...)
diff --git a/memcheck/tests/amd64/defcfaexpr.vgtest b/memcheck/tests/amd64/defcfaexpr.vgtest
new file mode 100644 (file)
index 0000000..1e1008c
--- /dev/null
@@ -0,0 +1,2 @@
+prog: defcfaexpr
+vgopts: -q