1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is really horrible.  It checks that the
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stack unwinder understands DW_CFA_def_cfa_expression.  It is
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the result of compiling this:
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid bbb ( long x )
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  __asm__ __volatile__(
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "cmp %0,%0\n\t"
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "jz .Lxyzzy\n"
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ".Lxyzzy:\n\t"
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      : : "r"(x) : "cc"
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid aaa ( long x ) {
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bbb(x);
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void )
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long *p = malloc(8);
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  aaa( *p );
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownand bracketing the cmp/jz insns with a move down/up by 256 of %rsp.
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownThe .jz causes memcheck to complain, hence unwind the stack, but
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthat cannot be successfully done unless the return address can
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbe found.  Hence the handwritten CFI below uses
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownDW_CFA_def_cfa_expression to make that possible.
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownThe CFI below isn't really right in that aaa appears twice
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownin the backtrace
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown==12868== Conditional jump or move depends on uninitialised value(s)
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown==12868==    at 0x400512: bbb (in /home/sewardj/VgTRUNK/trunk/mad0)
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown==12868==    by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0)
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown==12868==    by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0)
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown==12868==    by 0x400538: main (in /home/sewardj/VgTRUNK/trunk/mad0)
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbut GDB behaves the same, so I'm not too concerned - indicates
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthe problem is with the handwritten CFI and not with
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownV's interpretation of it.
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.file	"bad0.c"
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.text
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.globl bbb
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.type	bbb, @function
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbbb:
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFB2:
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lbbb1:
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	subq $256,%rsp
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lbbb2:
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp %rdi,%rdi
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jz .Lxyzzy
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lxyzzy:
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	addq $256,%rsp
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lbbb3:
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lbbb4:
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFE2:
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.size	bbb, .-bbb
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.globl aaa
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.type	aaa, @function
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownaaa:
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFB3:
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	bbb
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	rep ; ret
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFE3:
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.size	aaa, .-aaa
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.globl main
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.type	main, @function
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmain:
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFB4:
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	subq	$8, %rsp
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LCFI0:
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	movl	$8, %edi
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	malloc
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	movq	(%rax), %rdi
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	aaa
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	movl	$0, %eax
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	addq	$8, %rsp
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LFE4:
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.size	main, .-main
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.section	.eh_frame,"a",@progbits
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lframe1:
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LECIE1-.LSCIE1
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LSCIE1:
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	0x0
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x1
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.string	"zR"
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x1
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.sleb128 -8
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x10
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x1
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x3
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0xc
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x7
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x8
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x90
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x1
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.align 8
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LECIE1:
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* start of the FDE for bbb */
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LSFDE1:
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LEFDE1-.LASFDE1	/* length of FDE */
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LASFDE1:
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LASFDE1-.Lframe1	/* CIE pointer */
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFB2			/* & bbb */
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFE2-.LFB2		/* sizeof(bbb) */
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0			/* augmentation length */
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x40 + .Lbbb2 - .Lbbb1	/* _advance_loc to .Lbbb2 */
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* For the section in between .Lbbb2 and .Lbbb3, set the
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	CFA to be %rsp+256, and set the return address (dwarf r16)
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	to be *(CFA+0). */
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte     0x0f	/* _def_cfa_expression */
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128  .Lexpr1e-.Lexpr1s /* length of expression */
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lexpr1s:
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x77	/* DW_OP_breg7 == %rsp + sleb128(0) */
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.sleb128 0
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x40	/* DW_OP_lit16 */
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x40	/* DW_OP_lit16 */
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x1e	/* DW_OP_mul */
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x22	/* DW_OP_plus */
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lexpr1e:
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte 0x90	/* _cfa_offset:	r16 = *(cfa+0) */
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x40 + .Lbbb3 - .Lbbb2	/* _advance_loc to .Lbbb3 */
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* For the section .Lbbb3 to .Lbbb4, should set CFA back to
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	something sensible.  This tries to do it but still causes
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	GDB to show an extraneous aaa frame on the stack.  Oh well. */
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Now set CFA back to %rsp+0 */
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte     0x0f	/* _def_cfa_expression */
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128  .Lexpr2e-.Lexpr2s /* length of expression */
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lexpr2s:
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x77	/* DW_OP_breg7 == %rsp + sleb128(0) */
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.sleb128 0
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x30	/* DW_OP_lit0 */
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x1c	/* DW_OP_minus */
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.Lexpr2e:
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte 0x90	/* _cfa_offset:	r16 = *(cfa+0) */
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x40 + .Lbbb4 - .Lbbb3	/* _advance_loc to .Lbbb4 */
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x0			/* ??? */
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.align 8
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LEFDE1:
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* end of the FDE for bbb */
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LSFDE3:
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LEFDE3-.LASFDE3
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LASFDE3:
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LASFDE3-.Lframe1
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFB3
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFE3-.LFB3
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x0
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.align 8
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LEFDE3:
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LSFDE5:
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LEFDE5-.LASFDE5
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LASFDE5:
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LASFDE5-.Lframe1
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFB4
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LFE4-.LFB4
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x0
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0x4
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.long	.LCFI0-.LFB4
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte	0xe
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.uleb128 0x10
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.align 8
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.LEFDE5:
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.ident	"GCC: (GNU) 4.1.2 20061115 (prerelease) (SUSE Linux)"
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.section	.note.GNU-stack,"",@progbits
187