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