blob: a4f950ca6634d0ec20ede53508bf4b9cb94465cc [file] [log] [blame]
sewardjb5f6f512005-03-10 23:59:00 +00001/* -*- c -*-
njn25e49d8e72002-09-23 09:36:25 +00002 ----------------------------------------------------------------
3
4 Notice that the following BSD-style license applies to this one
5 file (valgrind.h) only. The entire rest of Valgrind is licensed
6 under the terms of the GNU General Public License, version 2. See
7 the COPYING file in the source distribution for details.
8
9 ----------------------------------------------------------------
10
njnb9c427c2004-12-01 14:14:42 +000011 This file is part of Valgrind, a dynamic binary instrumentation
12 framework.
sewardjde4a1d02002-03-22 01:27:54 +000013
njn53612422005-03-12 16:22:54 +000014 Copyright (C) 2000-2005 Julian Seward. All rights reserved.
sewardjde4a1d02002-03-22 01:27:54 +000015
njn25e49d8e72002-09-23 09:36:25 +000016 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
18 are met:
sewardjde4a1d02002-03-22 01:27:54 +000019
njn25e49d8e72002-09-23 09:36:25 +000020 1. Redistributions of source code must retain the above copyright
21 notice, this list of conditions and the following disclaimer.
sewardjde4a1d02002-03-22 01:27:54 +000022
njn25e49d8e72002-09-23 09:36:25 +000023 2. The origin of this software must not be misrepresented; you must
24 not claim that you wrote the original software. If you use this
25 software in a product, an acknowledgment in the product
26 documentation would be appreciated but is not required.
sewardjde4a1d02002-03-22 01:27:54 +000027
njn25e49d8e72002-09-23 09:36:25 +000028 3. Altered source versions must be plainly marked as such, and must
29 not be misrepresented as being the original software.
30
31 4. The name of the author may not be used to endorse or promote
32 products derived from this software without specific prior written
33 permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
36 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
39 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46
47 ----------------------------------------------------------------
48
49 Notice that the above BSD-style license applies to this one file
50 (valgrind.h) only. The entire rest of Valgrind is licensed under
51 the terms of the GNU General Public License, version 2. See the
52 COPYING file in the source distribution for details.
53
54 ----------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +000055*/
56
57
njn30d76c62005-06-18 15:07:39 +000058/* This file is for inclusion into client (your!) code.
59
60 You can use these macros to manipulate and query Valgrind's
61 execution inside your own programs.
62
63 The resulting executables will still run without Valgrind, just a
64 little bit more slowly than they otherwise would, but otherwise
65 unchanged. When not running on valgrind, each client request
sewardj0ec07f32006-01-12 12:32:32 +000066 consumes very few (eg. 7) instructions, so the resulting performance
njn30d76c62005-06-18 15:07:39 +000067 loss is negligible unless you plan to execute client requests
68 millions of times per second. Nevertheless, if that is still a
69 problem, you can compile with the NVALGRIND symbol defined (gcc
70 -DNVALGRIND) so that client requests are not even compiled in. */
71
sewardjde4a1d02002-03-22 01:27:54 +000072#ifndef __VALGRIND_H
73#define __VALGRIND_H
74
fitzhardinge39de4b42003-10-31 07:12:21 +000075#include <stdarg.h>
76
njn3dd0a912005-06-28 19:44:10 +000077/* Nb: this file might be included in a file compiled with -ansi. So
78 we can't use C++ style "//" comments nor the "asm" keyword (instead
79 use "__asm__"). */
80
sewardj0ec07f32006-01-12 12:32:32 +000081/* Derive some tags indicating what the target architecture is. Note
82 that in this file we're using the compiler's CPP symbols for
83 identifying architectures, which are different to the ones we use
84 within the rest of Valgrind. Note, __powerpc__ is active for both
85 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
86 latter. */
87#undef ARCH_x86
88#undef ARCH_amd64
89#undef ARCH_ppc32
90#undef ARCH_ppc64
91
92#if defined(__i386__)
93# define ARCH_x86 1
94#elif defined(__x86_64__)
95# define ARCH_amd64 1
96#elif defined(__powerpc__) && !defined(__powerpc64__)
97# define ARCH_ppc32 1
98#elif defined(__powerpc__) && defined(__powerpc64__)
99# define ARCH_ppc64 1
sewardjb5f6f512005-03-10 23:59:00 +0000100#endif
101
sewardj0ec07f32006-01-12 12:32:32 +0000102/* If we're not compiling for our target architecture, don't generate
103 any inline asms. */
104#if !defined(ARCH_x86) && !defined(ARCH_amd64) \
105 && !defined(ARCH_ppc32) && !defined(ARCH_ppc64)
106# if !defined(NVALGRIND)
107# define NVALGRIND 1
108# endif
109#endif
110
111
njn30d76c62005-06-18 15:07:39 +0000112/* ------------------------------------------------------------------ */
sewardj0ec07f32006-01-12 12:32:32 +0000113/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
114/* in here of use to end-users -- skip to the next section. */
njn30d76c62005-06-18 15:07:39 +0000115/* ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000116
sewardj0ec07f32006-01-12 12:32:32 +0000117#if defined(NVALGRIND)
njn26aba4d2005-05-16 13:31:23 +0000118
119/* Define NVALGRIND to completely remove the Valgrind magic sequence
sewardj0ec07f32006-01-12 12:32:32 +0000120 from the compiled code (analogous to NDEBUG's effects on
121 assert()) */
122#define VALGRIND_DO_CLIENT_REQUEST( \
123 _zzq_rlval, _zzq_default, _zzq_request, \
sewardj9af10a12006-02-01 14:59:42 +0000124 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
sewardj0ec07f32006-01-12 12:32:32 +0000125 { \
126 (_zzq_rlval) = (_zzq_default); \
njn26aba4d2005-05-16 13:31:23 +0000127 }
128
sewardj0ec07f32006-01-12 12:32:32 +0000129#else /* ! NVALGRIND */
nethercotee90c6832004-10-18 18:07:49 +0000130
sewardj0ec07f32006-01-12 12:32:32 +0000131/* The following defines the magic code sequences which the JITter
132 spots and handles magically. Don't look too closely at them as
133 they will rot your brain.
134
135 The assembly code sequences for all architectures is in this one
136 file. This is because this file must be stand-alone, and we don't
137 want to have multiple files.
138
139 For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
140 value gets put in the return slot, so that everything works when
141 this is executed not under Valgrind. Args are passed in a memory
142 block, and so there's no intrinsic limit to the number that could
sewardj9af10a12006-02-01 14:59:42 +0000143 be passed, but it's currently five.
nethercotee90c6832004-10-18 18:07:49 +0000144
nethercote54265442004-10-26 12:56:58 +0000145 The macro args are:
146 _zzq_rlval result lvalue
147 _zzq_default default value (result returned when running on real CPU)
148 _zzq_request request code
sewardj9af10a12006-02-01 14:59:42 +0000149 _zzq_arg1..5 request params
nethercote54265442004-10-26 12:56:58 +0000150
sewardj0ec07f32006-01-12 12:32:32 +0000151 The other two macros are used to support function wrapping, and are
sewardjd68ac3e2006-01-20 14:31:57 +0000152 a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
153 guest's NRADDR pseudo-register and whatever other information is
154 needed to safely run the call original from the wrapper: on
155 ppc64-linux, the R2 value at the divert point is also needed. This
156 information is abstracted into a user-visible type, OrigFn.
157
158 VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
159 guest, but guarantees that the branch instruction will not be
160 redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
161 branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
162 complete inline asm, since it needs to be combined with more magic
163 inline asm stuff to be useful.
nethercotee90c6832004-10-18 18:07:49 +0000164*/
165
sewardj0ec07f32006-01-12 12:32:32 +0000166/* ---------------------------- x86 ---------------------------- */
sewardjde4a4ab2005-03-23 13:10:32 +0000167
sewardj0ec07f32006-01-12 12:32:32 +0000168#if defined(ARCH_x86)
sewardjc8858442006-01-20 15:17:20 +0000169
170typedef
171 struct {
172 unsigned int nraddr; /* where's the code? */
173 }
174 OrigFn;
175
sewardj0ec07f32006-01-12 12:32:32 +0000176#define __SPECIAL_INSTRUCTION_PREAMBLE \
177 "roll $3, %%edi ; roll $13, %%edi\n\t" \
sewardj1a85f4f2006-01-12 21:15:35 +0000178 "roll $29, %%edi ; roll $19, %%edi\n\t"
sewardjde4a4ab2005-03-23 13:10:32 +0000179
sewardj0ec07f32006-01-12 12:32:32 +0000180#define VALGRIND_DO_CLIENT_REQUEST( \
181 _zzq_rlval, _zzq_default, _zzq_request, \
sewardj9af10a12006-02-01 14:59:42 +0000182 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
183 { volatile unsigned int _zzq_args[6]; \
sewardj0ec07f32006-01-12 12:32:32 +0000184 volatile unsigned int _zzq_result; \
185 _zzq_args[0] = (unsigned int)(_zzq_request); \
186 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
187 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
188 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
189 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
sewardj9af10a12006-02-01 14:59:42 +0000190 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
sewardj0ec07f32006-01-12 12:32:32 +0000191 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
192 /* %EDX = client_request ( %EAX ) */ \
193 "xchgl %%ebx,%%ebx" \
194 : "=d" (_zzq_result) \
195 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
196 : "cc", "memory" \
197 ); \
198 _zzq_rlval = _zzq_result; \
cerion85665ca2005-06-20 15:51:07 +0000199 }
sewardj2c48c7b2005-11-29 13:05:56 +0000200
sewardjc8858442006-01-20 15:17:20 +0000201#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
202 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
203 volatile unsigned int __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000204 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
205 /* %EAX = guest_NRADDR */ \
206 "xchgl %%ecx,%%ecx" \
207 : "=a" (__addr) \
208 : \
209 : "cc", "memory" \
210 ); \
sewardjc8858442006-01-20 15:17:20 +0000211 _zzq_orig->nraddr = __addr; \
sewardj2c48c7b2005-11-29 13:05:56 +0000212 }
sewardj0ec07f32006-01-12 12:32:32 +0000213
214#define VALGRIND_CALL_NOREDIR_EAX \
215 __SPECIAL_INSTRUCTION_PREAMBLE \
216 /* call-noredir *%EAX */ \
217 "xchgl %%edx,%%edx\n\t"
218#endif /* ARCH_x86 */
219
220/* --------------------------- amd64 --------------------------- */
221
222#if defined(ARCH_amd64)
sewardjc8858442006-01-20 15:17:20 +0000223
224typedef
225 struct {
226 unsigned long long int nraddr; /* where's the code? */
227 }
228 OrigFn;
229
sewardj0ec07f32006-01-12 12:32:32 +0000230#define __SPECIAL_INSTRUCTION_PREAMBLE \
231 "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
sewardj1a85f4f2006-01-12 21:15:35 +0000232 "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
sewardj0ec07f32006-01-12 12:32:32 +0000233
234#define VALGRIND_DO_CLIENT_REQUEST( \
235 _zzq_rlval, _zzq_default, _zzq_request, \
sewardj9af10a12006-02-01 14:59:42 +0000236 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
237 { volatile unsigned long long int _zzq_args[6]; \
sewardj0ec07f32006-01-12 12:32:32 +0000238 volatile unsigned long long int _zzq_result; \
239 _zzq_args[0] = (unsigned long long int)(_zzq_request); \
240 _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
241 _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
242 _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
243 _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
sewardj9af10a12006-02-01 14:59:42 +0000244 _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
sewardj0ec07f32006-01-12 12:32:32 +0000245 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
246 /* %RDX = client_request ( %RAX ) */ \
247 "xchgq %%rbx,%%rbx" \
248 : "=d" (_zzq_result) \
249 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
250 : "cc", "memory" \
251 ); \
252 _zzq_rlval = _zzq_result; \
253 }
254
sewardjc8858442006-01-20 15:17:20 +0000255#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
256 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
257 volatile unsigned long long int __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000258 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
259 /* %RAX = guest_NRADDR */ \
260 "xchgq %%rcx,%%rcx" \
261 : "=a" (__addr) \
262 : \
263 : "cc", "memory" \
264 ); \
sewardjc8858442006-01-20 15:17:20 +0000265 _zzq_orig->nraddr = __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000266 }
267
268#define VALGRIND_CALL_NOREDIR_RAX \
269 __SPECIAL_INSTRUCTION_PREAMBLE \
270 /* call-noredir *%RAX */ \
271 "xchgq %%rdx,%%rdx\n\t"
272#endif /* ARCH_amd64 */
273
274/* --------------------------- ppc32 --------------------------- */
275
276#if defined(ARCH_ppc32)
sewardjd68ac3e2006-01-20 14:31:57 +0000277
278typedef
279 struct {
sewardjc8858442006-01-20 15:17:20 +0000280 unsigned int nraddr; /* where's the code? */
sewardjd68ac3e2006-01-20 14:31:57 +0000281 }
282 OrigFn;
283
sewardj0ec07f32006-01-12 12:32:32 +0000284#define __SPECIAL_INSTRUCTION_PREAMBLE \
285 "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
sewardj1a85f4f2006-01-12 21:15:35 +0000286 "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
sewardj0ec07f32006-01-12 12:32:32 +0000287
288#define VALGRIND_DO_CLIENT_REQUEST( \
289 _zzq_rlval, _zzq_default, _zzq_request, \
sewardj9af10a12006-02-01 14:59:42 +0000290 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
sewardj0ec07f32006-01-12 12:32:32 +0000291 \
sewardj9af10a12006-02-01 14:59:42 +0000292 { unsigned int _zzq_args[6]; \
sewardj1a85f4f2006-01-12 21:15:35 +0000293 register unsigned int _zzq_result __asm__("r3"); \
294 register unsigned int* _zzq_ptr __asm__("r4"); \
sewardj0ec07f32006-01-12 12:32:32 +0000295 _zzq_args[0] = (unsigned int)(_zzq_request); \
296 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
297 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
298 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
299 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
sewardj9af10a12006-02-01 14:59:42 +0000300 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
sewardj0ec07f32006-01-12 12:32:32 +0000301 _zzq_ptr = _zzq_args; \
302 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
303 /* %R3 = client_request ( %R4 ) */ \
304 "or 1,1,1" \
305 : "=r" (_zzq_result) \
306 : "0" (_zzq_default), "r" (_zzq_ptr) \
307 : "cc", "memory"); \
308 _zzq_rlval = _zzq_result; \
309 }
310
sewardjd68ac3e2006-01-20 14:31:57 +0000311#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
312 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
313 register unsigned int __addr __asm__("r3"); \
sewardj0ec07f32006-01-12 12:32:32 +0000314 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
315 /* %R3 = guest_NRADDR */ \
316 "or 2,2,2" \
317 : "=r" (__addr) \
318 : \
319 : "cc", "memory" \
320 ); \
sewardjd68ac3e2006-01-20 14:31:57 +0000321 _zzq_orig->nraddr = __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000322 }
323
324#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
325 __SPECIAL_INSTRUCTION_PREAMBLE \
326 /* branch-and-link-to-noredir *%R11 */ \
327 "or 3,3,3\n\t"
328#endif /* ARCH_ppc32 */
329
330/* --------------------------- ppc64 --------------------------- */
331
332#if defined(ARCH_ppc64)
sewardjd68ac3e2006-01-20 14:31:57 +0000333
334typedef
335 struct {
336 unsigned long long int nraddr; /* where's the code? */
337 unsigned long long int r2; /* what tocptr do we need? */
338 }
339 OrigFn;
340
sewardj1a85f4f2006-01-12 21:15:35 +0000341#define __SPECIAL_INSTRUCTION_PREAMBLE \
342 "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
343 "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
344
sewardj0ec07f32006-01-12 12:32:32 +0000345#define VALGRIND_DO_CLIENT_REQUEST( \
346 _zzq_rlval, _zzq_default, _zzq_request, \
sewardj9af10a12006-02-01 14:59:42 +0000347 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
sewardj0ec07f32006-01-12 12:32:32 +0000348 \
sewardj9af10a12006-02-01 14:59:42 +0000349 { unsigned long long int _zzq_args[6]; \
sewardj1a85f4f2006-01-12 21:15:35 +0000350 register unsigned long long int _zzq_result __asm__("r3"); \
351 register unsigned long long int* _zzq_ptr __asm__("r4"); \
352 _zzq_args[0] = (unsigned long long int)(_zzq_request); \
353 _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
354 _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
355 _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
356 _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
sewardj9af10a12006-02-01 14:59:42 +0000357 _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
sewardj0ec07f32006-01-12 12:32:32 +0000358 _zzq_ptr = _zzq_args; \
sewardj1a85f4f2006-01-12 21:15:35 +0000359 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
360 /* %R3 = client_request ( %R4 ) */ \
361 "or 1,1,1" \
362 : "=r" (_zzq_result) \
sewardj0ec07f32006-01-12 12:32:32 +0000363 : "0" (_zzq_default), "r" (_zzq_ptr) \
sewardj1a85f4f2006-01-12 21:15:35 +0000364 : "cc", "memory"); \
365 _zzq_rlval = _zzq_result; \
sewardj0ec07f32006-01-12 12:32:32 +0000366 }
sewardj1a85f4f2006-01-12 21:15:35 +0000367
sewardjd68ac3e2006-01-20 14:31:57 +0000368#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
369 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
370 register unsigned long long int __addr __asm__("r3"); \
sewardj1a85f4f2006-01-12 21:15:35 +0000371 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
372 /* %R3 = guest_NRADDR */ \
373 "or 2,2,2" \
374 : "=r" (__addr) \
375 : \
376 : "cc", "memory" \
377 ); \
sewardjd68ac3e2006-01-20 14:31:57 +0000378 _zzq_orig->nraddr = __addr; \
379 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
380 /* %R3 = guest_NRADDR_GPR2 */ \
381 "or 4,4,4" \
382 : "=r" (__addr) \
383 : \
384 : "cc", "memory" \
385 ); \
386 _zzq_orig->r2 = __addr; \
sewardj1a85f4f2006-01-12 21:15:35 +0000387 }
388
389#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
390 __SPECIAL_INSTRUCTION_PREAMBLE \
391 /* branch-and-link-to-noredir *%R11 */ \
392 "or 3,3,3\n\t"
393
sewardj0ec07f32006-01-12 12:32:32 +0000394#endif /* ARCH_ppc64 */
cerion85665ca2005-06-20 15:51:07 +0000395
njn3dd0a912005-06-28 19:44:10 +0000396/* Insert assembly code for other architectures here... */
njn26aba4d2005-05-16 13:31:23 +0000397
sewardj37091fb2002-11-16 11:06:50 +0000398#endif /* NVALGRIND */
sewardj2e93c502002-04-12 11:12:52 +0000399
nethercote69d9c462004-10-26 13:00:12 +0000400
njn30d76c62005-06-18 15:07:39 +0000401/* ------------------------------------------------------------------ */
sewardj0ec07f32006-01-12 12:32:32 +0000402/* ARCHITECTURE SPECIFICS for FUNCTION WRAPPING. This is all very */
403/* ugly. It's the least-worst tradeoff I can think of. */
404/* ------------------------------------------------------------------ */
405
406/* This section defines magic (a.k.a appalling-hack) macros for doing
407 guaranteed-no-redirection macros, so as to get from function
408 wrappers to the functions they are wrapping. The whole point is to
409 construct standard call sequences, but to do the call itself with a
410 special no-redirect call pseudo-instruction that the JIT
411 understands and handles specially. This section is long and
412 repetitious, and I can't see a way to make it shorter.
413
414 The naming scheme is as follows:
415
416 CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
417
418 'W' stands for "word" and 'v' for "void". Hence there are
419 different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
420 and for each, the possibility of returning a word-typed result, or
421 no result.
422*/
423
424/* Use these to write the name of your wrapper. NOTE: duplicates
425 VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
426
427#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
428 _vgwZU_##soname##_##fnname
429
430#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
431 _vgwZZ_##soname##_##fnname
432
sewardjd68ac3e2006-01-20 14:31:57 +0000433/* Use this macro from within a wrapper function to collect the
434 context (address and possibly other info) of the original function.
435 Once you have that you can then use it in one of the CALL_FN_
436 macros. The type of the argument _lval is OrigFn. */
437#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
sewardj0ec07f32006-01-12 12:32:32 +0000438
439/* Derivatives of the main macros below, for calling functions
440 returning void. */
441
442#define CALL_FN_v_v(fnptr) \
443 do { volatile unsigned long _junk; \
444 CALL_FN_W_v(_junk,fnptr); } while (0)
445
446#define CALL_FN_v_W(fnptr, arg1) \
447 do { volatile unsigned long _junk; \
448 CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
449
450#define CALL_FN_v_WW(fnptr, arg1,arg2) \
451 do { volatile unsigned long _junk; \
452 CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
453
454/* ---------------------------- x86 ---------------------------- */
455
456#if defined(ARCH_x86)
457
458/* These regs are trashed by the hidden call. No need to mention eax
459 as gcc can already see that, plus causes gcc to bomb. */
460#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
461
462/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
463 long) == 4. */
464
sewardj66226cc2006-01-20 15:46:46 +0000465#define CALL_FN_W_v(lval, orig) \
sewardj0ec07f32006-01-12 12:32:32 +0000466 do { \
sewardj66226cc2006-01-20 15:46:46 +0000467 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000468 volatile unsigned long _argvec[1]; \
469 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000470 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000471 __asm__ volatile( \
472 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
473 VALGRIND_CALL_NOREDIR_EAX \
474 : /*out*/ "=a" (_res) \
475 : /*in*/ "a" (&_argvec[0]) \
476 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
477 ); \
478 lval = (__typeof__(lval)) _res; \
479 } while (0)
480
sewardj66226cc2006-01-20 15:46:46 +0000481#define CALL_FN_W_W(lval, orig, arg1) \
sewardj0ec07f32006-01-12 12:32:32 +0000482 do { \
sewardj66226cc2006-01-20 15:46:46 +0000483 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000484 volatile unsigned long _argvec[2]; \
485 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000486 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000487 _argvec[1] = (unsigned long)(arg1); \
488 __asm__ volatile( \
489 "pushl 4(%%eax)\n\t" \
490 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
491 VALGRIND_CALL_NOREDIR_EAX \
492 "addl $4, %%esp\n" \
493 : /*out*/ "=a" (_res) \
494 : /*in*/ "a" (&_argvec[0]) \
495 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
496 ); \
497 lval = (__typeof__(lval)) _res; \
498 } while (0)
499
sewardj66226cc2006-01-20 15:46:46 +0000500#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj0ec07f32006-01-12 12:32:32 +0000501 do { \
sewardj66226cc2006-01-20 15:46:46 +0000502 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000503 volatile unsigned long _argvec[3]; \
504 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000505 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000506 _argvec[1] = (unsigned long)(arg1); \
507 _argvec[2] = (unsigned long)(arg2); \
508 __asm__ volatile( \
509 "pushl 8(%%eax)\n\t" \
510 "pushl 4(%%eax)\n\t" \
511 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
512 VALGRIND_CALL_NOREDIR_EAX \
513 "addl $8, %%esp\n" \
514 : /*out*/ "=a" (_res) \
515 : /*in*/ "a" (&_argvec[0]) \
516 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
517 ); \
518 lval = (__typeof__(lval)) _res; \
519 } while (0)
520
sewardj9e8b07a2006-02-18 21:13:29 +0000521#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
522 do { \
523 volatile OrigFn _orig = (orig); \
524 volatile unsigned long _argvec[4]; \
525 volatile unsigned long _res; \
526 _argvec[0] = (unsigned long)_orig.nraddr; \
527 _argvec[1] = (unsigned long)(arg1); \
528 _argvec[2] = (unsigned long)(arg2); \
529 _argvec[3] = (unsigned long)(arg3); \
530 __asm__ volatile( \
531 "pushl 12(%%eax)\n\t" \
532 "pushl 8(%%eax)\n\t" \
533 "pushl 4(%%eax)\n\t" \
534 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
535 VALGRIND_CALL_NOREDIR_EAX \
536 "addl $12, %%esp\n" \
537 : /*out*/ "=a" (_res) \
538 : /*in*/ "a" (&_argvec[0]) \
539 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
540 ); \
541 lval = (__typeof__(lval)) _res; \
542 } while (0)
543
sewardj66226cc2006-01-20 15:46:46 +0000544#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
sewardj0ec07f32006-01-12 12:32:32 +0000545 do { \
sewardj66226cc2006-01-20 15:46:46 +0000546 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000547 volatile unsigned long _argvec[5]; \
548 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000549 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000550 _argvec[1] = (unsigned long)(arg1); \
551 _argvec[2] = (unsigned long)(arg2); \
552 _argvec[3] = (unsigned long)(arg3); \
553 _argvec[4] = (unsigned long)(arg4); \
554 __asm__ volatile( \
555 "pushl 16(%%eax)\n\t" \
556 "pushl 12(%%eax)\n\t" \
557 "pushl 8(%%eax)\n\t" \
558 "pushl 4(%%eax)\n\t" \
559 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
560 VALGRIND_CALL_NOREDIR_EAX \
561 "addl $16, %%esp\n" \
562 : /*out*/ "=a" (_res) \
563 : /*in*/ "a" (&_argvec[0]) \
564 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
565 ); \
566 lval = (__typeof__(lval)) _res; \
567 } while (0)
568
sewardj66226cc2006-01-20 15:46:46 +0000569#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
sewardj0ec07f32006-01-12 12:32:32 +0000570 do { \
sewardj66226cc2006-01-20 15:46:46 +0000571 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000572 volatile unsigned long _argvec[6]; \
573 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000574 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000575 _argvec[1] = (unsigned long)(arg1); \
576 _argvec[2] = (unsigned long)(arg2); \
577 _argvec[3] = (unsigned long)(arg3); \
578 _argvec[4] = (unsigned long)(arg4); \
579 _argvec[5] = (unsigned long)(arg5); \
580 __asm__ volatile( \
581 "pushl 20(%%eax)\n\t" \
582 "pushl 16(%%eax)\n\t" \
583 "pushl 12(%%eax)\n\t" \
584 "pushl 8(%%eax)\n\t" \
585 "pushl 4(%%eax)\n\t" \
586 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
587 VALGRIND_CALL_NOREDIR_EAX \
588 "addl $20, %%esp\n" \
589 : /*out*/ "=a" (_res) \
590 : /*in*/ "a" (&_argvec[0]) \
591 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
592 ); \
593 lval = (__typeof__(lval)) _res; \
594 } while (0)
595
sewardj66226cc2006-01-20 15:46:46 +0000596#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
sewardj0ec07f32006-01-12 12:32:32 +0000597 do { \
sewardj66226cc2006-01-20 15:46:46 +0000598 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000599 volatile unsigned long _argvec[7]; \
600 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000601 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000602 _argvec[1] = (unsigned long)(arg1); \
603 _argvec[2] = (unsigned long)(arg2); \
604 _argvec[3] = (unsigned long)(arg3); \
605 _argvec[4] = (unsigned long)(arg4); \
606 _argvec[5] = (unsigned long)(arg5); \
607 _argvec[6] = (unsigned long)(arg6); \
608 __asm__ volatile( \
609 "pushl 24(%%eax)\n\t" \
610 "pushl 20(%%eax)\n\t" \
611 "pushl 16(%%eax)\n\t" \
612 "pushl 12(%%eax)\n\t" \
613 "pushl 8(%%eax)\n\t" \
614 "pushl 4(%%eax)\n\t" \
615 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
616 VALGRIND_CALL_NOREDIR_EAX \
617 "addl $24, %%esp\n" \
618 : /*out*/ "=a" (_res) \
619 : /*in*/ "a" (&_argvec[0]) \
620 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
621 ); \
622 lval = (__typeof__(lval)) _res; \
623 } while (0)
624
sewardj66226cc2006-01-20 15:46:46 +0000625#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
626 arg7) \
sewardj0ec07f32006-01-12 12:32:32 +0000627 do { \
sewardj66226cc2006-01-20 15:46:46 +0000628 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000629 volatile unsigned long _argvec[8]; \
630 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000631 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000632 _argvec[1] = (unsigned long)(arg1); \
633 _argvec[2] = (unsigned long)(arg2); \
634 _argvec[3] = (unsigned long)(arg3); \
635 _argvec[4] = (unsigned long)(arg4); \
636 _argvec[5] = (unsigned long)(arg5); \
637 _argvec[6] = (unsigned long)(arg6); \
638 _argvec[7] = (unsigned long)(arg7); \
639 __asm__ volatile( \
640 "pushl 28(%%eax)\n\t" \
641 "pushl 24(%%eax)\n\t" \
642 "pushl 20(%%eax)\n\t" \
643 "pushl 16(%%eax)\n\t" \
644 "pushl 12(%%eax)\n\t" \
645 "pushl 8(%%eax)\n\t" \
646 "pushl 4(%%eax)\n\t" \
647 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
648 VALGRIND_CALL_NOREDIR_EAX \
649 "addl $28, %%esp\n" \
650 : /*out*/ "=a" (_res) \
651 : /*in*/ "a" (&_argvec[0]) \
652 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
653 ); \
654 lval = (__typeof__(lval)) _res; \
655 } while (0)
656
sewardj66226cc2006-01-20 15:46:46 +0000657#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
658 arg7,arg8) \
sewardj0ec07f32006-01-12 12:32:32 +0000659 do { \
sewardj66226cc2006-01-20 15:46:46 +0000660 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000661 volatile unsigned long _argvec[9]; \
662 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000663 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000664 _argvec[1] = (unsigned long)(arg1); \
665 _argvec[2] = (unsigned long)(arg2); \
666 _argvec[3] = (unsigned long)(arg3); \
667 _argvec[4] = (unsigned long)(arg4); \
668 _argvec[5] = (unsigned long)(arg5); \
669 _argvec[6] = (unsigned long)(arg6); \
670 _argvec[7] = (unsigned long)(arg7); \
671 _argvec[8] = (unsigned long)(arg8); \
672 __asm__ volatile( \
673 "pushl 32(%%eax)\n\t" \
674 "pushl 28(%%eax)\n\t" \
675 "pushl 24(%%eax)\n\t" \
676 "pushl 20(%%eax)\n\t" \
677 "pushl 16(%%eax)\n\t" \
678 "pushl 12(%%eax)\n\t" \
679 "pushl 8(%%eax)\n\t" \
680 "pushl 4(%%eax)\n\t" \
681 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
682 VALGRIND_CALL_NOREDIR_EAX \
683 "addl $32, %%esp\n" \
684 : /*out*/ "=a" (_res) \
685 : /*in*/ "a" (&_argvec[0]) \
686 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
687 ); \
688 lval = (__typeof__(lval)) _res; \
689 } while (0)
690
sewardj45fa5b02006-03-09 19:06:23 +0000691#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
692 arg7,arg8,arg9) \
693 do { \
694 volatile OrigFn _orig = (orig); \
695 volatile unsigned long _argvec[10]; \
696 volatile unsigned long _res; \
697 _argvec[0] = (unsigned long)_orig.nraddr; \
698 _argvec[1] = (unsigned long)(arg1); \
699 _argvec[2] = (unsigned long)(arg2); \
700 _argvec[3] = (unsigned long)(arg3); \
701 _argvec[4] = (unsigned long)(arg4); \
702 _argvec[5] = (unsigned long)(arg5); \
703 _argvec[6] = (unsigned long)(arg6); \
704 _argvec[7] = (unsigned long)(arg7); \
705 _argvec[8] = (unsigned long)(arg8); \
706 _argvec[9] = (unsigned long)(arg9); \
707 __asm__ volatile( \
708 "pushl 36(%%eax)\n\t" \
709 "pushl 32(%%eax)\n\t" \
710 "pushl 28(%%eax)\n\t" \
711 "pushl 24(%%eax)\n\t" \
712 "pushl 20(%%eax)\n\t" \
713 "pushl 16(%%eax)\n\t" \
714 "pushl 12(%%eax)\n\t" \
715 "pushl 8(%%eax)\n\t" \
716 "pushl 4(%%eax)\n\t" \
717 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
718 VALGRIND_CALL_NOREDIR_EAX \
719 "addl $36, %%esp\n" \
720 : /*out*/ "=a" (_res) \
721 : /*in*/ "a" (&_argvec[0]) \
722 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
723 ); \
724 lval = (__typeof__(lval)) _res; \
725 } while (0)
726
727#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
728 arg7,arg8,arg9,arg10) \
729 do { \
730 volatile OrigFn _orig = (orig); \
731 volatile unsigned long _argvec[11]; \
732 volatile unsigned long _res; \
733 _argvec[0] = (unsigned long)_orig.nraddr; \
734 _argvec[1] = (unsigned long)(arg1); \
735 _argvec[2] = (unsigned long)(arg2); \
736 _argvec[3] = (unsigned long)(arg3); \
737 _argvec[4] = (unsigned long)(arg4); \
738 _argvec[5] = (unsigned long)(arg5); \
739 _argvec[6] = (unsigned long)(arg6); \
740 _argvec[7] = (unsigned long)(arg7); \
741 _argvec[8] = (unsigned long)(arg8); \
742 _argvec[9] = (unsigned long)(arg9); \
743 _argvec[10] = (unsigned long)(arg10); \
744 __asm__ volatile( \
745 "pushl 40(%%eax)\n\t" \
746 "pushl 36(%%eax)\n\t" \
747 "pushl 32(%%eax)\n\t" \
748 "pushl 28(%%eax)\n\t" \
749 "pushl 24(%%eax)\n\t" \
750 "pushl 20(%%eax)\n\t" \
751 "pushl 16(%%eax)\n\t" \
752 "pushl 12(%%eax)\n\t" \
753 "pushl 8(%%eax)\n\t" \
754 "pushl 4(%%eax)\n\t" \
755 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
756 VALGRIND_CALL_NOREDIR_EAX \
757 "addl $40, %%esp\n" \
758 : /*out*/ "=a" (_res) \
759 : /*in*/ "a" (&_argvec[0]) \
760 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
761 ); \
762 lval = (__typeof__(lval)) _res; \
763 } while (0)
764
sewardj66226cc2006-01-20 15:46:46 +0000765#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
766 arg6,arg7,arg8,arg9,arg10, \
767 arg11,arg12) \
sewardj0ec07f32006-01-12 12:32:32 +0000768 do { \
sewardj66226cc2006-01-20 15:46:46 +0000769 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000770 volatile unsigned long _argvec[13]; \
771 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000772 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000773 _argvec[1] = (unsigned long)(arg1); \
774 _argvec[2] = (unsigned long)(arg2); \
775 _argvec[3] = (unsigned long)(arg3); \
776 _argvec[4] = (unsigned long)(arg4); \
777 _argvec[5] = (unsigned long)(arg5); \
778 _argvec[6] = (unsigned long)(arg6); \
779 _argvec[7] = (unsigned long)(arg7); \
780 _argvec[8] = (unsigned long)(arg8); \
781 _argvec[9] = (unsigned long)(arg9); \
782 _argvec[10] = (unsigned long)(arg10); \
783 _argvec[11] = (unsigned long)(arg11); \
784 _argvec[12] = (unsigned long)(arg12); \
785 __asm__ volatile( \
786 "pushl 48(%%eax)\n\t" \
787 "pushl 44(%%eax)\n\t" \
788 "pushl 40(%%eax)\n\t" \
789 "pushl 36(%%eax)\n\t" \
790 "pushl 32(%%eax)\n\t" \
791 "pushl 28(%%eax)\n\t" \
792 "pushl 24(%%eax)\n\t" \
793 "pushl 20(%%eax)\n\t" \
794 "pushl 16(%%eax)\n\t" \
795 "pushl 12(%%eax)\n\t" \
796 "pushl 8(%%eax)\n\t" \
797 "pushl 4(%%eax)\n\t" \
798 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
799 VALGRIND_CALL_NOREDIR_EAX \
800 "addl $48, %%esp\n" \
801 : /*out*/ "=a" (_res) \
802 : /*in*/ "a" (&_argvec[0]) \
803 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
804 ); \
805 lval = (__typeof__(lval)) _res; \
806 } while (0)
807
808#endif /* ARCH_x86 */
809
810/* --------------------------- amd64 --------------------------- */
811
812#if defined(ARCH_amd64)
813
814/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
815
816/* These regs are trashed by the hidden call. */
817#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
818 "rdi", "r8", "r9", "r10", "r11"
819
820/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
821 long) == 8. */
822
sewardjc8858442006-01-20 15:17:20 +0000823#define CALL_FN_W_v(lval, orig) \
sewardj0ec07f32006-01-12 12:32:32 +0000824 do { \
sewardjc8858442006-01-20 15:17:20 +0000825 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000826 volatile unsigned long _argvec[1]; \
827 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000828 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000829 __asm__ volatile( \
830 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
831 VALGRIND_CALL_NOREDIR_RAX \
832 : /*out*/ "=a" (_res) \
833 : /*in*/ "a" (&_argvec[0]) \
834 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
835 ); \
836 lval = (__typeof__(lval)) _res; \
837 } while (0)
838
sewardjc8858442006-01-20 15:17:20 +0000839#define CALL_FN_W_W(lval, orig, arg1) \
sewardj0ec07f32006-01-12 12:32:32 +0000840 do { \
sewardjc8858442006-01-20 15:17:20 +0000841 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000842 volatile unsigned long _argvec[2]; \
843 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000844 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000845 _argvec[1] = (unsigned long)(arg1); \
846 __asm__ volatile( \
847 "movq 8(%%rax), %%rdi\n\t" \
848 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
849 VALGRIND_CALL_NOREDIR_RAX \
850 : /*out*/ "=a" (_res) \
851 : /*in*/ "a" (&_argvec[0]) \
852 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
853 ); \
854 lval = (__typeof__(lval)) _res; \
855 } while (0)
856
sewardjc8858442006-01-20 15:17:20 +0000857#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj0ec07f32006-01-12 12:32:32 +0000858 do { \
sewardjc8858442006-01-20 15:17:20 +0000859 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000860 volatile unsigned long _argvec[3]; \
861 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000862 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000863 _argvec[1] = (unsigned long)(arg1); \
864 _argvec[2] = (unsigned long)(arg2); \
865 __asm__ volatile( \
866 "movq 16(%%rax), %%rsi\n\t" \
867 "movq 8(%%rax), %%rdi\n\t" \
868 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
869 VALGRIND_CALL_NOREDIR_RAX \
870 : /*out*/ "=a" (_res) \
871 : /*in*/ "a" (&_argvec[0]) \
872 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
873 ); \
874 lval = (__typeof__(lval)) _res; \
875 } while (0)
876
877#endif /* ARCH_amd64 */
878
879/* --------------------------- ppc32 --------------------------- */
880
881#if defined(ARCH_ppc32)
882
883/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
884
885/* These regs are trashed by the hidden call. */
886#define __CALLER_SAVED_REGS "lr", \
887 "r0", "r2", "r3", "r4", "r5", "r6", \
888 "r7", "r8", "r9", "r10", "r11", "r12"
889
890/* These CALL_FN_ macros assume that on ppc32-linux, sizeof(unsigned
891 long) == 4. */
892
sewardj38de0992006-01-20 16:46:34 +0000893#define CALL_FN_W_v(lval, orig) \
sewardj0ec07f32006-01-12 12:32:32 +0000894 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000895 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000896 volatile unsigned long _argvec[1]; \
897 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000898 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000899 __asm__ volatile( \
900 "mr 11,%1\n\t" \
901 "lwz 11,0(11)\n\t" /* target->r11 */ \
902 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
903 "mr %0,3" \
904 : /*out*/ "=r" (_res) \
905 : /*in*/ "r" (&_argvec[0]) \
906 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
907 ); \
908 lval = (__typeof__(lval)) _res; \
909 } while (0)
910
sewardj38de0992006-01-20 16:46:34 +0000911#define CALL_FN_W_W(lval, orig, arg1) \
sewardj0ec07f32006-01-12 12:32:32 +0000912 do { \
sewardj38de0992006-01-20 16:46:34 +0000913 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000914 volatile unsigned long _argvec[2]; \
915 volatile unsigned long _res; \
sewardj38de0992006-01-20 16:46:34 +0000916 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000917 _argvec[1] = (unsigned long)arg1; \
918 __asm__ volatile( \
919 "mr 11,%1\n\t" \
920 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
921 "lwz 11,0(11)\n\t" /* target->r11 */ \
922 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
923 "mr %0,3" \
924 : /*out*/ "=r" (_res) \
925 : /*in*/ "r" (&_argvec[0]) \
926 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
927 ); \
928 lval = (__typeof__(lval)) _res; \
929 } while (0)
930
sewardj38de0992006-01-20 16:46:34 +0000931#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj0ec07f32006-01-12 12:32:32 +0000932 do { \
sewardj38de0992006-01-20 16:46:34 +0000933 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000934 volatile unsigned long _argvec[3]; \
935 volatile unsigned long _res; \
sewardj38de0992006-01-20 16:46:34 +0000936 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000937 _argvec[1] = (unsigned long)arg1; \
938 _argvec[2] = (unsigned long)arg2; \
939 __asm__ volatile( \
940 "mr 11,%1\n\t" \
941 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
942 "lwz 4,8(11)\n\t" \
943 "lwz 11,0(11)\n\t" /* target->r11 */ \
944 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
945 "mr %0,3" \
946 : /*out*/ "=r" (_res) \
947 : /*in*/ "r" (&_argvec[0]) \
948 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
949 ); \
950 lval = (__typeof__(lval)) _res; \
951 } while (0)
952
953#endif /* ARCH_ppc32 */
954
955/* --------------------------- ppc64 --------------------------- */
956
sewardj9734b202006-01-17 01:49:37 +0000957#if defined(ARCH_ppc64)
958
959/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
960
961/* These regs are trashed by the hidden call. */
962#define __CALLER_SAVED_REGS "lr", \
963 "r0", "r2", "r3", "r4", "r5", "r6", \
964 "r7", "r8", "r9", "r10", "r11", "r12"
965
966/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
967 long) == 8. */
968
sewardjd68ac3e2006-01-20 14:31:57 +0000969#define CALL_FN_W_v(lval, orig) \
sewardj9734b202006-01-17 01:49:37 +0000970 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000971 volatile OrigFn _orig = (orig); \
972 volatile unsigned long _argvec[3+0]; \
sewardj9734b202006-01-17 01:49:37 +0000973 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000974 /* _argvec[0] holds current r2 across the call */ \
975 _argvec[1] = (unsigned long)_orig.r2; \
976 _argvec[2] = (unsigned long)_orig.nraddr; \
sewardj9734b202006-01-17 01:49:37 +0000977 __asm__ volatile( \
978 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000979 "std 2,-16(11)\n\t" /* save tocptr */ \
980 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
981 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +0000982 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
983 "mr 11,%1\n\t" \
984 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000985 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +0000986 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +0000987 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +0000988 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
989 ); \
990 lval = (__typeof__(lval)) _res; \
991 } while (0)
992
sewardjd68ac3e2006-01-20 14:31:57 +0000993#define CALL_FN_W_W(lval, orig, arg1) \
sewardj9734b202006-01-17 01:49:37 +0000994 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000995 volatile OrigFn _orig = (orig); \
996 volatile unsigned long _argvec[3+1]; \
sewardj9734b202006-01-17 01:49:37 +0000997 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000998 /* _argvec[0] holds current r2 across the call */ \
999 _argvec[1] = (unsigned long)_orig.r2; \
1000 _argvec[2] = (unsigned long)_orig.nraddr; \
1001 _argvec[2+1] = (unsigned long)arg1; \
sewardj9734b202006-01-17 01:49:37 +00001002 __asm__ volatile( \
1003 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +00001004 "std 2,-16(11)\n\t" /* save tocptr */ \
1005 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
1006 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
1007 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +00001008 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1009 "mr 11,%1\n\t" \
1010 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +00001011 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +00001012 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +00001013 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +00001014 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1015 ); \
1016 lval = (__typeof__(lval)) _res; \
1017 } while (0)
1018
sewardjd68ac3e2006-01-20 14:31:57 +00001019#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj9734b202006-01-17 01:49:37 +00001020 do { \
sewardjd68ac3e2006-01-20 14:31:57 +00001021 volatile OrigFn _orig = (orig); \
1022 volatile unsigned long _argvec[3+2]; \
sewardj9734b202006-01-17 01:49:37 +00001023 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +00001024 /* _argvec[0] holds current r2 across the call */ \
1025 _argvec[1] = (unsigned long)_orig.r2; \
1026 _argvec[2] = (unsigned long)_orig.nraddr; \
1027 _argvec[2+1] = (unsigned long)arg1; \
1028 _argvec[2+2] = (unsigned long)arg2; \
sewardj9734b202006-01-17 01:49:37 +00001029 __asm__ volatile( \
1030 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +00001031 "std 2,-16(11)\n\t" /* save tocptr */ \
1032 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
1033 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
1034 "ld 4, 16(11)\n\t" /* arg1->r4 */ \
1035 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +00001036 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1037 "mr 11,%1\n\t" \
1038 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +00001039 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +00001040 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +00001041 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +00001042 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1043 ); \
1044 lval = (__typeof__(lval)) _res; \
1045 } while (0)
1046
1047#endif /* ARCH_ppc64 */
1048
sewardj0ec07f32006-01-12 12:32:32 +00001049
1050/* ------------------------------------------------------------------ */
1051/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
1052/* */
njn30d76c62005-06-18 15:07:39 +00001053/* ------------------------------------------------------------------ */
1054
sewardj2e93c502002-04-12 11:12:52 +00001055/* Some request codes. There are many more of these, but most are not
1056 exposed to end-user view. These are the public ones, all of the
njn25e49d8e72002-09-23 09:36:25 +00001057 form 0x1000 + small_number.
njnd7994182003-10-02 13:44:04 +00001058
sewardj0ec07f32006-01-12 12:32:32 +00001059 Core ones are in the range 0x00000000--0x0000ffff. The non-public
1060 ones start at 0x2000.
sewardj2e93c502002-04-12 11:12:52 +00001061*/
1062
sewardj0ec07f32006-01-12 12:32:32 +00001063/* These macros are used by tools -- they must be public, but don't
1064 embed them into other programs. */
njnfc26ff92004-11-22 19:12:49 +00001065#define VG_USERREQ_TOOL_BASE(a,b) \
njn4c791212003-05-02 17:53:54 +00001066 ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
njnfc26ff92004-11-22 19:12:49 +00001067#define VG_IS_TOOL_USERREQ(a, b, v) \
1068 (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
sewardj34042512002-10-22 04:14:35 +00001069
njn25e49d8e72002-09-23 09:36:25 +00001070typedef
njn4c791212003-05-02 17:53:54 +00001071 enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
1072 VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
njn3e884182003-04-15 13:03:23 +00001073
sewardj0ec07f32006-01-12 12:32:32 +00001074 /* These allow any function to be called from the simulated
1075 CPU but run on the real CPU. Nb: the first arg passed to
1076 the function is always the ThreadId of the running
1077 thread! So CLIENT_CALL0 actually requires a 1 arg
njnd4795be2004-11-24 11:57:51 +00001078 function, etc. */
njn4c791212003-05-02 17:53:54 +00001079 VG_USERREQ__CLIENT_CALL0 = 0x1101,
1080 VG_USERREQ__CLIENT_CALL1 = 0x1102,
1081 VG_USERREQ__CLIENT_CALL2 = 0x1103,
1082 VG_USERREQ__CLIENT_CALL3 = 0x1104,
njn3e884182003-04-15 13:03:23 +00001083
sewardj0ec07f32006-01-12 12:32:32 +00001084 /* Can be useful in regression testing suites -- eg. can
1085 send Valgrind's output to /dev/null and still count
1086 errors. */
njn4c791212003-05-02 17:53:54 +00001087 VG_USERREQ__COUNT_ERRORS = 0x1201,
njn47363ab2003-04-21 13:24:40 +00001088
sewardj0ec07f32006-01-12 12:32:32 +00001089 /* These are useful and can be interpreted by any tool that
1090 tracks malloc() et al, by using vg_replace_malloc.c. */
njnd7994182003-10-02 13:44:04 +00001091 VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
1092 VG_USERREQ__FREELIKE_BLOCK = 0x1302,
rjwalshbc0bb832004-06-19 18:12:36 +00001093 /* Memory pool support. */
1094 VG_USERREQ__CREATE_MEMPOOL = 0x1303,
1095 VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
1096 VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
1097 VG_USERREQ__MEMPOOL_FREE = 0x1306,
njnd7994182003-10-02 13:44:04 +00001098
fitzhardinge39de4b42003-10-31 07:12:21 +00001099 /* Allow printfs to valgrind log. */
njn30d76c62005-06-18 15:07:39 +00001100 VG_USERREQ__PRINTF = 0x1401,
rjwalsh0140af52005-06-04 20:42:33 +00001101 VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
1102
1103 /* Stack support. */
1104 VG_USERREQ__STACK_REGISTER = 0x1501,
1105 VG_USERREQ__STACK_DEREGISTER = 0x1502,
1106 VG_USERREQ__STACK_CHANGE = 0x1503,
njn25e49d8e72002-09-23 09:36:25 +00001107 } Vg_ClientRequest;
sewardj2e93c502002-04-12 11:12:52 +00001108
sewardj0ec07f32006-01-12 12:32:32 +00001109#if !defined(__GNUC__)
1110# define __extension__ /* */
muellerc9b36552003-12-31 14:32:23 +00001111#endif
sewardj2e93c502002-04-12 11:12:52 +00001112
sewardj0ec07f32006-01-12 12:32:32 +00001113/* Returns the number of Valgrinds this code is running under. That
1114 is, 0 if running natively, 1 if running under Valgrind, 2 if
1115 running under Valgrind which is running under another Valgrind,
1116 etc. */
1117#define RUNNING_ON_VALGRIND __extension__ \
1118 ({unsigned int _qzz_res; \
1119 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
1120 VG_USERREQ__RUNNING_ON_VALGRIND, \
sewardj9af10a12006-02-01 14:59:42 +00001121 0, 0, 0, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001122 _qzz_res; \
sewardjde4a1d02002-03-22 01:27:54 +00001123 })
1124
1125
sewardj18d75132002-05-16 11:06:21 +00001126/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
1127 _qzz_len - 1]. Useful if you are debugging a JITter or some such,
1128 since it provides a way to make sure valgrind will retranslate the
1129 invalidated area. Returns no value. */
sewardj0ec07f32006-01-12 12:32:32 +00001130#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
1131 {unsigned int _qzz_res; \
1132 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1133 VG_USERREQ__DISCARD_TRANSLATIONS, \
sewardj9af10a12006-02-01 14:59:42 +00001134 _qzz_addr, _qzz_len, 0, 0, 0); \
sewardj18d75132002-05-16 11:06:21 +00001135 }
1136
njn26aba4d2005-05-16 13:31:23 +00001137
sewardj0ec07f32006-01-12 12:32:32 +00001138/* These requests are for getting Valgrind itself to print something.
1139 Possibly with a backtrace. This is a really ugly hack. */
1140
1141#if defined(NVALGRIND)
1142
1143# define VALGRIND_PRINTF(...)
1144# define VALGRIND_PRINTF_BACKTRACE(...)
njn26aba4d2005-05-16 13:31:23 +00001145
1146#else /* NVALGRIND */
fitzhardinge39de4b42003-10-31 07:12:21 +00001147
fitzhardingea09a1b52003-11-07 23:09:48 +00001148int VALGRIND_PRINTF(const char *format, ...)
1149 __attribute__((format(__printf__, 1, 2)));
fitzhardinge39de4b42003-10-31 07:12:21 +00001150__attribute__((weak))
1151int
fitzhardingea09a1b52003-11-07 23:09:48 +00001152VALGRIND_PRINTF(const char *format, ...)
fitzhardinge39de4b42003-10-31 07:12:21 +00001153{
njnc6168192004-11-29 13:54:10 +00001154 unsigned long _qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001155 va_list vargs;
1156 va_start(vargs, format);
sewardj0ec07f32006-01-12 12:32:32 +00001157 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
sewardj9af10a12006-02-01 14:59:42 +00001158 (unsigned long)format, (unsigned long)vargs,
1159 0, 0, 0);
fitzhardinge39de4b42003-10-31 07:12:21 +00001160 va_end(vargs);
njnc6168192004-11-29 13:54:10 +00001161 return (int)_qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001162}
1163
fitzhardingea09a1b52003-11-07 23:09:48 +00001164int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
1165 __attribute__((format(__printf__, 1, 2)));
fitzhardinge39de4b42003-10-31 07:12:21 +00001166__attribute__((weak))
1167int
fitzhardingea09a1b52003-11-07 23:09:48 +00001168VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
fitzhardinge39de4b42003-10-31 07:12:21 +00001169{
njnc6168192004-11-29 13:54:10 +00001170 unsigned long _qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001171 va_list vargs;
1172 va_start(vargs, format);
sewardj0ec07f32006-01-12 12:32:32 +00001173 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
sewardj9af10a12006-02-01 14:59:42 +00001174 (unsigned long)format, (unsigned long)vargs,
1175 0, 0, 0);
fitzhardinge39de4b42003-10-31 07:12:21 +00001176 va_end(vargs);
njnc6168192004-11-29 13:54:10 +00001177 return (int)_qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001178}
1179
fitzhardinge39de4b42003-10-31 07:12:21 +00001180#endif /* NVALGRIND */
sewardj18d75132002-05-16 11:06:21 +00001181
sewardj0ec07f32006-01-12 12:32:32 +00001182
njn3e884182003-04-15 13:03:23 +00001183/* These requests allow control to move from the simulated CPU to the
1184 real CPU, calling an arbitary function */
sewardj0ec07f32006-01-12 12:32:32 +00001185#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
1186 ({unsigned long _qyy_res; \
1187 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1188 VG_USERREQ__CLIENT_CALL0, \
1189 _qyy_fn, \
sewardj9af10a12006-02-01 14:59:42 +00001190 0, 0, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001191 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001192 })
1193
sewardj0ec07f32006-01-12 12:32:32 +00001194#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
1195 ({unsigned long _qyy_res; \
1196 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1197 VG_USERREQ__CLIENT_CALL1, \
1198 _qyy_fn, \
sewardj9af10a12006-02-01 14:59:42 +00001199 _qyy_arg1, 0, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001200 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001201 })
1202
sewardj0ec07f32006-01-12 12:32:32 +00001203#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
1204 ({unsigned long _qyy_res; \
1205 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1206 VG_USERREQ__CLIENT_CALL2, \
1207 _qyy_fn, \
sewardj9af10a12006-02-01 14:59:42 +00001208 _qyy_arg1, _qyy_arg2, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001209 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001210 })
1211
sewardj0ec07f32006-01-12 12:32:32 +00001212#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
1213 ({unsigned long _qyy_res; \
1214 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1215 VG_USERREQ__CLIENT_CALL3, \
1216 _qyy_fn, \
sewardj9af10a12006-02-01 14:59:42 +00001217 _qyy_arg1, _qyy_arg2, \
1218 _qyy_arg3, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001219 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001220 })
1221
1222
nethercote7cc9c232004-01-21 15:08:04 +00001223/* Counts the number of errors that have been recorded by a tool. Nb:
1224 the tool must record the errors with VG_(maybe_record_error)() or
njn47363ab2003-04-21 13:24:40 +00001225 VG_(unique_error)() for them to be counted. */
sewardj0ec07f32006-01-12 12:32:32 +00001226#define VALGRIND_COUNT_ERRORS \
1227 ({unsigned int _qyy_res; \
1228 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1229 VG_USERREQ__COUNT_ERRORS, \
sewardj9af10a12006-02-01 14:59:42 +00001230 0, 0, 0, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001231 _qyy_res; \
njn47363ab2003-04-21 13:24:40 +00001232 })
1233
njnd7994182003-10-02 13:44:04 +00001234/* Mark a block of memory as having been allocated by a malloc()-like
1235 function. `addr' is the start of the usable block (ie. after any
1236 redzone) `rzB' is redzone size if the allocator can apply redzones;
1237 use '0' if not. Adding redzones makes it more likely Valgrind will spot
1238 block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
1239 for calloc(). Put it immediately after the point where a block is
1240 allocated.
1241
1242 If you're allocating memory via superblocks, and then handing out small
1243 chunks of each superblock, if you don't have redzones on your small
1244 blocks, it's worth marking the superblock with VALGRIND_MAKE_NOACCESS
1245 when it's created, so that block overruns are detected. But if you can
1246 put redzones on, it's probably better to not do this, so that messages
1247 for small overruns are described in terms of the small block rather than
1248 the superblock (but if you have a big overrun that skips over a redzone,
1249 you could miss an error this way). See memcheck/tests/custom_alloc.c
1250 for an example.
1251
1252 Nb: block must be freed via a free()-like function specified
1253 with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
sewardj0ec07f32006-01-12 12:32:32 +00001254#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
1255 {unsigned int _qzz_res; \
1256 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1257 VG_USERREQ__MALLOCLIKE_BLOCK, \
sewardj9af10a12006-02-01 14:59:42 +00001258 addr, sizeB, rzB, is_zeroed, 0); \
njnd7994182003-10-02 13:44:04 +00001259 }
1260
1261/* Mark a block of memory as having been freed by a free()-like function.
1262 `rzB' is redzone size; it must match that given to
1263 VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
1264 checker. Put it immediately after the point where the block is freed. */
sewardj0ec07f32006-01-12 12:32:32 +00001265#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
1266 {unsigned int _qzz_res; \
1267 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1268 VG_USERREQ__FREELIKE_BLOCK, \
sewardj9af10a12006-02-01 14:59:42 +00001269 addr, rzB, 0, 0, 0); \
njnd7994182003-10-02 13:44:04 +00001270 }
1271
rjwalshbc0bb832004-06-19 18:12:36 +00001272/* Create a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001273#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
1274 {unsigned int _qzz_res; \
1275 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1276 VG_USERREQ__CREATE_MEMPOOL, \
sewardj9af10a12006-02-01 14:59:42 +00001277 pool, rzB, is_zeroed, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001278 }
1279
1280/* Destroy a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001281#define VALGRIND_DESTROY_MEMPOOL(pool) \
1282 {unsigned int _qzz_res; \
1283 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1284 VG_USERREQ__DESTROY_MEMPOOL, \
sewardj9af10a12006-02-01 14:59:42 +00001285 pool, 0, 0, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001286 }
1287
1288/* Associate a piece of memory with a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001289#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
1290 {unsigned int _qzz_res; \
1291 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1292 VG_USERREQ__MEMPOOL_ALLOC, \
sewardj9af10a12006-02-01 14:59:42 +00001293 pool, addr, size, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001294 }
1295
1296/* Disassociate a piece of memory from a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001297#define VALGRIND_MEMPOOL_FREE(pool, addr) \
1298 {unsigned int _qzz_res; \
1299 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1300 VG_USERREQ__MEMPOOL_FREE, \
sewardj9af10a12006-02-01 14:59:42 +00001301 pool, addr, 0, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001302 }
1303
rjwalsh0140af52005-06-04 20:42:33 +00001304/* Mark a piece of memory as being a stack. Returns a stack id. */
sewardj0ec07f32006-01-12 12:32:32 +00001305#define VALGRIND_STACK_REGISTER(start, end) \
1306 ({unsigned int _qzz_res; \
1307 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1308 VG_USERREQ__STACK_REGISTER, \
sewardj9af10a12006-02-01 14:59:42 +00001309 start, end, 0, 0, 0); \
sewardj0ec07f32006-01-12 12:32:32 +00001310 _qzz_res; \
rjwalsh0140af52005-06-04 20:42:33 +00001311 })
1312
1313/* Unmark the piece of memory associated with a stack id as being a
1314 stack. */
sewardj0ec07f32006-01-12 12:32:32 +00001315#define VALGRIND_STACK_DEREGISTER(id) \
1316 {unsigned int _qzz_res; \
1317 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1318 VG_USERREQ__STACK_DEREGISTER, \
sewardj9af10a12006-02-01 14:59:42 +00001319 id, 0, 0, 0, 0); \
rjwalsh0140af52005-06-04 20:42:33 +00001320 }
1321
1322/* Change the start and end address of the stack id. */
sewardj0ec07f32006-01-12 12:32:32 +00001323#define VALGRIND_STACK_CHANGE(id, start, end) \
1324 {unsigned int _qzz_res; \
1325 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1326 VG_USERREQ__STACK_CHANGE, \
sewardj9af10a12006-02-01 14:59:42 +00001327 id, start, end, 0, 0); \
rjwalsh0140af52005-06-04 20:42:33 +00001328 }
1329
sewardj0ec07f32006-01-12 12:32:32 +00001330
1331#undef ARCH_x86
1332#undef ARCH_amd64
1333#undef ARCH_ppc32
1334#undef ARCH_ppc64
1335
njn3e884182003-04-15 13:03:23 +00001336#endif /* __VALGRIND_H */