blob: 96e9508d4b230cb9ee758d3f026f187715ffb1d5 [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, \
124 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
125 { \
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
143 be passed, but it's currently four.
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
149 _zzq_arg1..4 request params
150
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, \
182 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
183 { volatile unsigned int _zzq_args[5]; \
184 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); \
190 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
191 /* %EDX = client_request ( %EAX ) */ \
192 "xchgl %%ebx,%%ebx" \
193 : "=d" (_zzq_result) \
194 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
195 : "cc", "memory" \
196 ); \
197 _zzq_rlval = _zzq_result; \
cerion85665ca2005-06-20 15:51:07 +0000198 }
sewardj2c48c7b2005-11-29 13:05:56 +0000199
sewardjc8858442006-01-20 15:17:20 +0000200#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
201 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
202 volatile unsigned int __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000203 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
204 /* %EAX = guest_NRADDR */ \
205 "xchgl %%ecx,%%ecx" \
206 : "=a" (__addr) \
207 : \
208 : "cc", "memory" \
209 ); \
sewardjc8858442006-01-20 15:17:20 +0000210 _zzq_orig->nraddr = __addr; \
sewardj2c48c7b2005-11-29 13:05:56 +0000211 }
sewardj0ec07f32006-01-12 12:32:32 +0000212
213#define VALGRIND_CALL_NOREDIR_EAX \
214 __SPECIAL_INSTRUCTION_PREAMBLE \
215 /* call-noredir *%EAX */ \
216 "xchgl %%edx,%%edx\n\t"
217#endif /* ARCH_x86 */
218
219/* --------------------------- amd64 --------------------------- */
220
221#if defined(ARCH_amd64)
sewardjc8858442006-01-20 15:17:20 +0000222
223typedef
224 struct {
225 unsigned long long int nraddr; /* where's the code? */
226 }
227 OrigFn;
228
sewardj0ec07f32006-01-12 12:32:32 +0000229#define __SPECIAL_INSTRUCTION_PREAMBLE \
230 "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
sewardj1a85f4f2006-01-12 21:15:35 +0000231 "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
sewardj0ec07f32006-01-12 12:32:32 +0000232
233#define VALGRIND_DO_CLIENT_REQUEST( \
234 _zzq_rlval, _zzq_default, _zzq_request, \
235 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
236 { volatile unsigned long long int _zzq_args[5]; \
237 volatile unsigned long long int _zzq_result; \
238 _zzq_args[0] = (unsigned long long int)(_zzq_request); \
239 _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
240 _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
241 _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
242 _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
243 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
244 /* %RDX = client_request ( %RAX ) */ \
245 "xchgq %%rbx,%%rbx" \
246 : "=d" (_zzq_result) \
247 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
248 : "cc", "memory" \
249 ); \
250 _zzq_rlval = _zzq_result; \
251 }
252
sewardjc8858442006-01-20 15:17:20 +0000253#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
254 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
255 volatile unsigned long long int __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000256 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
257 /* %RAX = guest_NRADDR */ \
258 "xchgq %%rcx,%%rcx" \
259 : "=a" (__addr) \
260 : \
261 : "cc", "memory" \
262 ); \
sewardjc8858442006-01-20 15:17:20 +0000263 _zzq_orig->nraddr = __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000264 }
265
266#define VALGRIND_CALL_NOREDIR_RAX \
267 __SPECIAL_INSTRUCTION_PREAMBLE \
268 /* call-noredir *%RAX */ \
269 "xchgq %%rdx,%%rdx\n\t"
270#endif /* ARCH_amd64 */
271
272/* --------------------------- ppc32 --------------------------- */
273
274#if defined(ARCH_ppc32)
sewardjd68ac3e2006-01-20 14:31:57 +0000275
276typedef
277 struct {
sewardjc8858442006-01-20 15:17:20 +0000278 unsigned int nraddr; /* where's the code? */
sewardjd68ac3e2006-01-20 14:31:57 +0000279 }
280 OrigFn;
281
sewardj0ec07f32006-01-12 12:32:32 +0000282#define __SPECIAL_INSTRUCTION_PREAMBLE \
283 "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
sewardj1a85f4f2006-01-12 21:15:35 +0000284 "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
sewardj0ec07f32006-01-12 12:32:32 +0000285
286#define VALGRIND_DO_CLIENT_REQUEST( \
287 _zzq_rlval, _zzq_default, _zzq_request, \
288 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
289 \
sewardj1a85f4f2006-01-12 21:15:35 +0000290 { unsigned int _zzq_args[5]; \
291 register unsigned int _zzq_result __asm__("r3"); \
292 register unsigned int* _zzq_ptr __asm__("r4"); \
sewardj0ec07f32006-01-12 12:32:32 +0000293 _zzq_args[0] = (unsigned int)(_zzq_request); \
294 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
295 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
296 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
297 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
298 _zzq_ptr = _zzq_args; \
299 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
300 /* %R3 = client_request ( %R4 ) */ \
301 "or 1,1,1" \
302 : "=r" (_zzq_result) \
303 : "0" (_zzq_default), "r" (_zzq_ptr) \
304 : "cc", "memory"); \
305 _zzq_rlval = _zzq_result; \
306 }
307
sewardjd68ac3e2006-01-20 14:31:57 +0000308#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
309 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
310 register unsigned int __addr __asm__("r3"); \
sewardj0ec07f32006-01-12 12:32:32 +0000311 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
312 /* %R3 = guest_NRADDR */ \
313 "or 2,2,2" \
314 : "=r" (__addr) \
315 : \
316 : "cc", "memory" \
317 ); \
sewardjd68ac3e2006-01-20 14:31:57 +0000318 _zzq_orig->nraddr = __addr; \
sewardj0ec07f32006-01-12 12:32:32 +0000319 }
320
321#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
322 __SPECIAL_INSTRUCTION_PREAMBLE \
323 /* branch-and-link-to-noredir *%R11 */ \
324 "or 3,3,3\n\t"
325#endif /* ARCH_ppc32 */
326
327/* --------------------------- ppc64 --------------------------- */
328
329#if defined(ARCH_ppc64)
sewardjd68ac3e2006-01-20 14:31:57 +0000330
331typedef
332 struct {
333 unsigned long long int nraddr; /* where's the code? */
334 unsigned long long int r2; /* what tocptr do we need? */
335 }
336 OrigFn;
337
sewardj1a85f4f2006-01-12 21:15:35 +0000338#define __SPECIAL_INSTRUCTION_PREAMBLE \
339 "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
340 "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
341
sewardj0ec07f32006-01-12 12:32:32 +0000342#define VALGRIND_DO_CLIENT_REQUEST( \
343 _zzq_rlval, _zzq_default, _zzq_request, \
344 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
345 \
sewardj1a85f4f2006-01-12 21:15:35 +0000346 { unsigned long long int _zzq_args[5]; \
347 register unsigned long long int _zzq_result __asm__("r3"); \
348 register unsigned long long int* _zzq_ptr __asm__("r4"); \
349 _zzq_args[0] = (unsigned long long int)(_zzq_request); \
350 _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
351 _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
352 _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
353 _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
sewardj0ec07f32006-01-12 12:32:32 +0000354 _zzq_ptr = _zzq_args; \
sewardj1a85f4f2006-01-12 21:15:35 +0000355 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
356 /* %R3 = client_request ( %R4 ) */ \
357 "or 1,1,1" \
358 : "=r" (_zzq_result) \
sewardj0ec07f32006-01-12 12:32:32 +0000359 : "0" (_zzq_default), "r" (_zzq_ptr) \
sewardj1a85f4f2006-01-12 21:15:35 +0000360 : "cc", "memory"); \
361 _zzq_rlval = _zzq_result; \
sewardj0ec07f32006-01-12 12:32:32 +0000362 }
sewardj1a85f4f2006-01-12 21:15:35 +0000363
sewardjd68ac3e2006-01-20 14:31:57 +0000364#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
365 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
366 register unsigned long long int __addr __asm__("r3"); \
sewardj1a85f4f2006-01-12 21:15:35 +0000367 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
368 /* %R3 = guest_NRADDR */ \
369 "or 2,2,2" \
370 : "=r" (__addr) \
371 : \
372 : "cc", "memory" \
373 ); \
sewardjd68ac3e2006-01-20 14:31:57 +0000374 _zzq_orig->nraddr = __addr; \
375 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
376 /* %R3 = guest_NRADDR_GPR2 */ \
377 "or 4,4,4" \
378 : "=r" (__addr) \
379 : \
380 : "cc", "memory" \
381 ); \
382 _zzq_orig->r2 = __addr; \
sewardj1a85f4f2006-01-12 21:15:35 +0000383 }
384
385#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
386 __SPECIAL_INSTRUCTION_PREAMBLE \
387 /* branch-and-link-to-noredir *%R11 */ \
388 "or 3,3,3\n\t"
389
sewardj0ec07f32006-01-12 12:32:32 +0000390#endif /* ARCH_ppc64 */
cerion85665ca2005-06-20 15:51:07 +0000391
njn3dd0a912005-06-28 19:44:10 +0000392/* Insert assembly code for other architectures here... */
njn26aba4d2005-05-16 13:31:23 +0000393
sewardj37091fb2002-11-16 11:06:50 +0000394#endif /* NVALGRIND */
sewardj2e93c502002-04-12 11:12:52 +0000395
nethercote69d9c462004-10-26 13:00:12 +0000396
njn30d76c62005-06-18 15:07:39 +0000397/* ------------------------------------------------------------------ */
sewardj0ec07f32006-01-12 12:32:32 +0000398/* ARCHITECTURE SPECIFICS for FUNCTION WRAPPING. This is all very */
399/* ugly. It's the least-worst tradeoff I can think of. */
400/* ------------------------------------------------------------------ */
401
402/* This section defines magic (a.k.a appalling-hack) macros for doing
403 guaranteed-no-redirection macros, so as to get from function
404 wrappers to the functions they are wrapping. The whole point is to
405 construct standard call sequences, but to do the call itself with a
406 special no-redirect call pseudo-instruction that the JIT
407 understands and handles specially. This section is long and
408 repetitious, and I can't see a way to make it shorter.
409
410 The naming scheme is as follows:
411
412 CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
413
414 'W' stands for "word" and 'v' for "void". Hence there are
415 different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
416 and for each, the possibility of returning a word-typed result, or
417 no result.
418*/
419
420/* Use these to write the name of your wrapper. NOTE: duplicates
421 VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
422
423#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
424 _vgwZU_##soname##_##fnname
425
426#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
427 _vgwZZ_##soname##_##fnname
428
sewardjd68ac3e2006-01-20 14:31:57 +0000429/* Use this macro from within a wrapper function to collect the
430 context (address and possibly other info) of the original function.
431 Once you have that you can then use it in one of the CALL_FN_
432 macros. The type of the argument _lval is OrigFn. */
433#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
sewardj0ec07f32006-01-12 12:32:32 +0000434
435/* Derivatives of the main macros below, for calling functions
436 returning void. */
437
438#define CALL_FN_v_v(fnptr) \
439 do { volatile unsigned long _junk; \
440 CALL_FN_W_v(_junk,fnptr); } while (0)
441
442#define CALL_FN_v_W(fnptr, arg1) \
443 do { volatile unsigned long _junk; \
444 CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
445
446#define CALL_FN_v_WW(fnptr, arg1,arg2) \
447 do { volatile unsigned long _junk; \
448 CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
449
450/* ---------------------------- x86 ---------------------------- */
451
452#if defined(ARCH_x86)
453
454/* These regs are trashed by the hidden call. No need to mention eax
455 as gcc can already see that, plus causes gcc to bomb. */
456#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
457
458/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
459 long) == 4. */
460
sewardj66226cc2006-01-20 15:46:46 +0000461#define CALL_FN_W_v(lval, orig) \
sewardj0ec07f32006-01-12 12:32:32 +0000462 do { \
sewardj66226cc2006-01-20 15:46:46 +0000463 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000464 volatile unsigned long _argvec[1]; \
465 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000466 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000467 __asm__ volatile( \
468 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
469 VALGRIND_CALL_NOREDIR_EAX \
470 : /*out*/ "=a" (_res) \
471 : /*in*/ "a" (&_argvec[0]) \
472 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
473 ); \
474 lval = (__typeof__(lval)) _res; \
475 } while (0)
476
sewardj66226cc2006-01-20 15:46:46 +0000477#define CALL_FN_W_W(lval, orig, arg1) \
sewardj0ec07f32006-01-12 12:32:32 +0000478 do { \
sewardj66226cc2006-01-20 15:46:46 +0000479 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000480 volatile unsigned long _argvec[2]; \
481 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000482 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000483 _argvec[1] = (unsigned long)(arg1); \
484 __asm__ volatile( \
485 "pushl 4(%%eax)\n\t" \
486 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
487 VALGRIND_CALL_NOREDIR_EAX \
488 "addl $4, %%esp\n" \
489 : /*out*/ "=a" (_res) \
490 : /*in*/ "a" (&_argvec[0]) \
491 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
492 ); \
493 lval = (__typeof__(lval)) _res; \
494 } while (0)
495
sewardj66226cc2006-01-20 15:46:46 +0000496#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj0ec07f32006-01-12 12:32:32 +0000497 do { \
sewardj66226cc2006-01-20 15:46:46 +0000498 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000499 volatile unsigned long _argvec[3]; \
500 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000501 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000502 _argvec[1] = (unsigned long)(arg1); \
503 _argvec[2] = (unsigned long)(arg2); \
504 __asm__ volatile( \
505 "pushl 8(%%eax)\n\t" \
506 "pushl 4(%%eax)\n\t" \
507 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
508 VALGRIND_CALL_NOREDIR_EAX \
509 "addl $8, %%esp\n" \
510 : /*out*/ "=a" (_res) \
511 : /*in*/ "a" (&_argvec[0]) \
512 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
513 ); \
514 lval = (__typeof__(lval)) _res; \
515 } while (0)
516
sewardj66226cc2006-01-20 15:46:46 +0000517#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
sewardj0ec07f32006-01-12 12:32:32 +0000518 do { \
sewardj66226cc2006-01-20 15:46:46 +0000519 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000520 volatile unsigned long _argvec[5]; \
521 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000522 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000523 _argvec[1] = (unsigned long)(arg1); \
524 _argvec[2] = (unsigned long)(arg2); \
525 _argvec[3] = (unsigned long)(arg3); \
526 _argvec[4] = (unsigned long)(arg4); \
527 __asm__ volatile( \
528 "pushl 16(%%eax)\n\t" \
529 "pushl 12(%%eax)\n\t" \
530 "pushl 8(%%eax)\n\t" \
531 "pushl 4(%%eax)\n\t" \
532 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
533 VALGRIND_CALL_NOREDIR_EAX \
534 "addl $16, %%esp\n" \
535 : /*out*/ "=a" (_res) \
536 : /*in*/ "a" (&_argvec[0]) \
537 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
538 ); \
539 lval = (__typeof__(lval)) _res; \
540 } while (0)
541
sewardj66226cc2006-01-20 15:46:46 +0000542#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
sewardj0ec07f32006-01-12 12:32:32 +0000543 do { \
sewardj66226cc2006-01-20 15:46:46 +0000544 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000545 volatile unsigned long _argvec[6]; \
546 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000547 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000548 _argvec[1] = (unsigned long)(arg1); \
549 _argvec[2] = (unsigned long)(arg2); \
550 _argvec[3] = (unsigned long)(arg3); \
551 _argvec[4] = (unsigned long)(arg4); \
552 _argvec[5] = (unsigned long)(arg5); \
553 __asm__ volatile( \
554 "pushl 20(%%eax)\n\t" \
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 $20, %%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_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
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[7]; \
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 _argvec[6] = (unsigned long)(arg6); \
581 __asm__ volatile( \
582 "pushl 24(%%eax)\n\t" \
583 "pushl 20(%%eax)\n\t" \
584 "pushl 16(%%eax)\n\t" \
585 "pushl 12(%%eax)\n\t" \
586 "pushl 8(%%eax)\n\t" \
587 "pushl 4(%%eax)\n\t" \
588 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
589 VALGRIND_CALL_NOREDIR_EAX \
590 "addl $24, %%esp\n" \
591 : /*out*/ "=a" (_res) \
592 : /*in*/ "a" (&_argvec[0]) \
593 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
594 ); \
595 lval = (__typeof__(lval)) _res; \
596 } while (0)
597
sewardj66226cc2006-01-20 15:46:46 +0000598#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
599 arg7) \
sewardj0ec07f32006-01-12 12:32:32 +0000600 do { \
sewardj66226cc2006-01-20 15:46:46 +0000601 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000602 volatile unsigned long _argvec[8]; \
603 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000604 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000605 _argvec[1] = (unsigned long)(arg1); \
606 _argvec[2] = (unsigned long)(arg2); \
607 _argvec[3] = (unsigned long)(arg3); \
608 _argvec[4] = (unsigned long)(arg4); \
609 _argvec[5] = (unsigned long)(arg5); \
610 _argvec[6] = (unsigned long)(arg6); \
611 _argvec[7] = (unsigned long)(arg7); \
612 __asm__ volatile( \
613 "pushl 28(%%eax)\n\t" \
614 "pushl 24(%%eax)\n\t" \
615 "pushl 20(%%eax)\n\t" \
616 "pushl 16(%%eax)\n\t" \
617 "pushl 12(%%eax)\n\t" \
618 "pushl 8(%%eax)\n\t" \
619 "pushl 4(%%eax)\n\t" \
620 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
621 VALGRIND_CALL_NOREDIR_EAX \
622 "addl $28, %%esp\n" \
623 : /*out*/ "=a" (_res) \
624 : /*in*/ "a" (&_argvec[0]) \
625 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
626 ); \
627 lval = (__typeof__(lval)) _res; \
628 } while (0)
629
sewardj66226cc2006-01-20 15:46:46 +0000630#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
631 arg7,arg8) \
sewardj0ec07f32006-01-12 12:32:32 +0000632 do { \
sewardj66226cc2006-01-20 15:46:46 +0000633 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000634 volatile unsigned long _argvec[9]; \
635 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000636 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000637 _argvec[1] = (unsigned long)(arg1); \
638 _argvec[2] = (unsigned long)(arg2); \
639 _argvec[3] = (unsigned long)(arg3); \
640 _argvec[4] = (unsigned long)(arg4); \
641 _argvec[5] = (unsigned long)(arg5); \
642 _argvec[6] = (unsigned long)(arg6); \
643 _argvec[7] = (unsigned long)(arg7); \
644 _argvec[8] = (unsigned long)(arg8); \
645 __asm__ volatile( \
646 "pushl 32(%%eax)\n\t" \
647 "pushl 28(%%eax)\n\t" \
648 "pushl 24(%%eax)\n\t" \
649 "pushl 20(%%eax)\n\t" \
650 "pushl 16(%%eax)\n\t" \
651 "pushl 12(%%eax)\n\t" \
652 "pushl 8(%%eax)\n\t" \
653 "pushl 4(%%eax)\n\t" \
654 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
655 VALGRIND_CALL_NOREDIR_EAX \
656 "addl $32, %%esp\n" \
657 : /*out*/ "=a" (_res) \
658 : /*in*/ "a" (&_argvec[0]) \
659 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
660 ); \
661 lval = (__typeof__(lval)) _res; \
662 } while (0)
663
sewardj66226cc2006-01-20 15:46:46 +0000664#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
665 arg6,arg7,arg8,arg9,arg10, \
666 arg11,arg12) \
sewardj0ec07f32006-01-12 12:32:32 +0000667 do { \
sewardj66226cc2006-01-20 15:46:46 +0000668 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000669 volatile unsigned long _argvec[13]; \
670 volatile unsigned long _res; \
sewardj66226cc2006-01-20 15:46:46 +0000671 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000672 _argvec[1] = (unsigned long)(arg1); \
673 _argvec[2] = (unsigned long)(arg2); \
674 _argvec[3] = (unsigned long)(arg3); \
675 _argvec[4] = (unsigned long)(arg4); \
676 _argvec[5] = (unsigned long)(arg5); \
677 _argvec[6] = (unsigned long)(arg6); \
678 _argvec[7] = (unsigned long)(arg7); \
679 _argvec[8] = (unsigned long)(arg8); \
680 _argvec[9] = (unsigned long)(arg9); \
681 _argvec[10] = (unsigned long)(arg10); \
682 _argvec[11] = (unsigned long)(arg11); \
683 _argvec[12] = (unsigned long)(arg12); \
684 __asm__ volatile( \
685 "pushl 48(%%eax)\n\t" \
686 "pushl 44(%%eax)\n\t" \
687 "pushl 40(%%eax)\n\t" \
688 "pushl 36(%%eax)\n\t" \
689 "pushl 32(%%eax)\n\t" \
690 "pushl 28(%%eax)\n\t" \
691 "pushl 24(%%eax)\n\t" \
692 "pushl 20(%%eax)\n\t" \
693 "pushl 16(%%eax)\n\t" \
694 "pushl 12(%%eax)\n\t" \
695 "pushl 8(%%eax)\n\t" \
696 "pushl 4(%%eax)\n\t" \
697 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
698 VALGRIND_CALL_NOREDIR_EAX \
699 "addl $48, %%esp\n" \
700 : /*out*/ "=a" (_res) \
701 : /*in*/ "a" (&_argvec[0]) \
702 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
703 ); \
704 lval = (__typeof__(lval)) _res; \
705 } while (0)
706
707#endif /* ARCH_x86 */
708
709/* --------------------------- amd64 --------------------------- */
710
711#if defined(ARCH_amd64)
712
713/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
714
715/* These regs are trashed by the hidden call. */
716#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
717 "rdi", "r8", "r9", "r10", "r11"
718
719/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
720 long) == 8. */
721
sewardjc8858442006-01-20 15:17:20 +0000722#define CALL_FN_W_v(lval, orig) \
sewardj0ec07f32006-01-12 12:32:32 +0000723 do { \
sewardjc8858442006-01-20 15:17:20 +0000724 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000725 volatile unsigned long _argvec[1]; \
726 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000727 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000728 __asm__ volatile( \
729 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
730 VALGRIND_CALL_NOREDIR_RAX \
731 : /*out*/ "=a" (_res) \
732 : /*in*/ "a" (&_argvec[0]) \
733 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
734 ); \
735 lval = (__typeof__(lval)) _res; \
736 } while (0)
737
sewardjc8858442006-01-20 15:17:20 +0000738#define CALL_FN_W_W(lval, orig, arg1) \
sewardj0ec07f32006-01-12 12:32:32 +0000739 do { \
sewardjc8858442006-01-20 15:17:20 +0000740 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000741 volatile unsigned long _argvec[2]; \
742 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000743 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000744 _argvec[1] = (unsigned long)(arg1); \
745 __asm__ volatile( \
746 "movq 8(%%rax), %%rdi\n\t" \
747 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
748 VALGRIND_CALL_NOREDIR_RAX \
749 : /*out*/ "=a" (_res) \
750 : /*in*/ "a" (&_argvec[0]) \
751 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
752 ); \
753 lval = (__typeof__(lval)) _res; \
754 } while (0)
755
sewardjc8858442006-01-20 15:17:20 +0000756#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj0ec07f32006-01-12 12:32:32 +0000757 do { \
sewardjc8858442006-01-20 15:17:20 +0000758 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000759 volatile unsigned long _argvec[3]; \
760 volatile unsigned long _res; \
sewardjc8858442006-01-20 15:17:20 +0000761 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000762 _argvec[1] = (unsigned long)(arg1); \
763 _argvec[2] = (unsigned long)(arg2); \
764 __asm__ volatile( \
765 "movq 16(%%rax), %%rsi\n\t" \
766 "movq 8(%%rax), %%rdi\n\t" \
767 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
768 VALGRIND_CALL_NOREDIR_RAX \
769 : /*out*/ "=a" (_res) \
770 : /*in*/ "a" (&_argvec[0]) \
771 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
772 ); \
773 lval = (__typeof__(lval)) _res; \
774 } while (0)
775
776#endif /* ARCH_amd64 */
777
778/* --------------------------- ppc32 --------------------------- */
779
780#if defined(ARCH_ppc32)
781
782/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
783
784/* These regs are trashed by the hidden call. */
785#define __CALLER_SAVED_REGS "lr", \
786 "r0", "r2", "r3", "r4", "r5", "r6", \
787 "r7", "r8", "r9", "r10", "r11", "r12"
788
789/* These CALL_FN_ macros assume that on ppc32-linux, sizeof(unsigned
790 long) == 4. */
791
792#define CALL_FN_W_v(lval, fnptr) \
793 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000794 volatile OrigFn _orig = (orig); \
sewardj0ec07f32006-01-12 12:32:32 +0000795 volatile unsigned long _argvec[1]; \
796 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000797 _argvec[0] = (unsigned long)_orig.nraddr; \
sewardj0ec07f32006-01-12 12:32:32 +0000798 __asm__ volatile( \
799 "mr 11,%1\n\t" \
800 "lwz 11,0(11)\n\t" /* target->r11 */ \
801 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
802 "mr %0,3" \
803 : /*out*/ "=r" (_res) \
804 : /*in*/ "r" (&_argvec[0]) \
805 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
806 ); \
807 lval = (__typeof__(lval)) _res; \
808 } while (0)
809
810#define CALL_FN_W_W(lval, fnptr, arg1) \
811 do { \
812 volatile void* _fnptr = (fnptr); \
813 volatile unsigned long _argvec[2]; \
814 volatile unsigned long _res; \
815 _argvec[0] = (unsigned long)_fnptr; \
816 _argvec[1] = (unsigned long)arg1; \
817 __asm__ volatile( \
818 "mr 11,%1\n\t" \
819 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
820 "lwz 11,0(11)\n\t" /* target->r11 */ \
821 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
822 "mr %0,3" \
823 : /*out*/ "=r" (_res) \
824 : /*in*/ "r" (&_argvec[0]) \
825 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
826 ); \
827 lval = (__typeof__(lval)) _res; \
828 } while (0)
829
830#define CALL_FN_W_WW(lval, fnptr, arg1,arg2) \
831 do { \
832 volatile void* _fnptr = (fnptr); \
833 volatile unsigned long _argvec[3]; \
834 volatile unsigned long _res; \
835 _argvec[0] = (unsigned long)_fnptr; \
836 _argvec[1] = (unsigned long)arg1; \
837 _argvec[2] = (unsigned long)arg2; \
838 __asm__ volatile( \
839 "mr 11,%1\n\t" \
840 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
841 "lwz 4,8(11)\n\t" \
842 "lwz 11,0(11)\n\t" /* target->r11 */ \
843 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
844 "mr %0,3" \
845 : /*out*/ "=r" (_res) \
846 : /*in*/ "r" (&_argvec[0]) \
847 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
848 ); \
849 lval = (__typeof__(lval)) _res; \
850 } while (0)
851
852#endif /* ARCH_ppc32 */
853
854/* --------------------------- ppc64 --------------------------- */
855
sewardj9734b202006-01-17 01:49:37 +0000856#if defined(ARCH_ppc64)
857
858/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
859
860/* These regs are trashed by the hidden call. */
861#define __CALLER_SAVED_REGS "lr", \
862 "r0", "r2", "r3", "r4", "r5", "r6", \
863 "r7", "r8", "r9", "r10", "r11", "r12"
864
865/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
866 long) == 8. */
867
sewardjd68ac3e2006-01-20 14:31:57 +0000868#define CALL_FN_W_v(lval, orig) \
sewardj9734b202006-01-17 01:49:37 +0000869 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000870 volatile OrigFn _orig = (orig); \
871 volatile unsigned long _argvec[3+0]; \
sewardj9734b202006-01-17 01:49:37 +0000872 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000873 /* _argvec[0] holds current r2 across the call */ \
874 _argvec[1] = (unsigned long)_orig.r2; \
875 _argvec[2] = (unsigned long)_orig.nraddr; \
sewardj9734b202006-01-17 01:49:37 +0000876 __asm__ volatile( \
877 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000878 "std 2,-16(11)\n\t" /* save tocptr */ \
879 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
880 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +0000881 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
882 "mr 11,%1\n\t" \
883 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000884 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +0000885 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +0000886 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +0000887 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
888 ); \
889 lval = (__typeof__(lval)) _res; \
890 } while (0)
891
sewardjd68ac3e2006-01-20 14:31:57 +0000892#define CALL_FN_W_W(lval, orig, arg1) \
sewardj9734b202006-01-17 01:49:37 +0000893 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000894 volatile OrigFn _orig = (orig); \
895 volatile unsigned long _argvec[3+1]; \
sewardj9734b202006-01-17 01:49:37 +0000896 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000897 /* _argvec[0] holds current r2 across the call */ \
898 _argvec[1] = (unsigned long)_orig.r2; \
899 _argvec[2] = (unsigned long)_orig.nraddr; \
900 _argvec[2+1] = (unsigned long)arg1; \
sewardj9734b202006-01-17 01:49:37 +0000901 __asm__ volatile( \
902 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000903 "std 2,-16(11)\n\t" /* save tocptr */ \
904 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
905 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
906 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +0000907 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
908 "mr 11,%1\n\t" \
909 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000910 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +0000911 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +0000912 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +0000913 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
914 ); \
915 lval = (__typeof__(lval)) _res; \
916 } while (0)
917
sewardjd68ac3e2006-01-20 14:31:57 +0000918#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
sewardj9734b202006-01-17 01:49:37 +0000919 do { \
sewardjd68ac3e2006-01-20 14:31:57 +0000920 volatile OrigFn _orig = (orig); \
921 volatile unsigned long _argvec[3+2]; \
sewardj9734b202006-01-17 01:49:37 +0000922 volatile unsigned long _res; \
sewardjd68ac3e2006-01-20 14:31:57 +0000923 /* _argvec[0] holds current r2 across the call */ \
924 _argvec[1] = (unsigned long)_orig.r2; \
925 _argvec[2] = (unsigned long)_orig.nraddr; \
926 _argvec[2+1] = (unsigned long)arg1; \
927 _argvec[2+2] = (unsigned long)arg2; \
sewardj9734b202006-01-17 01:49:37 +0000928 __asm__ volatile( \
929 "mr 11,%1\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000930 "std 2,-16(11)\n\t" /* save tocptr */ \
931 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
932 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
933 "ld 4, 16(11)\n\t" /* arg1->r4 */ \
934 "ld 11, 0(11)\n\t" /* target->r11 */ \
sewardj9734b202006-01-17 01:49:37 +0000935 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
936 "mr 11,%1\n\t" \
937 "mr %0,3\n\t" \
sewardjd68ac3e2006-01-20 14:31:57 +0000938 "ld 2,-16(11)" /* restore tocptr */ \
sewardj9734b202006-01-17 01:49:37 +0000939 : /*out*/ "=r" (_res) \
sewardjd68ac3e2006-01-20 14:31:57 +0000940 : /*in*/ "r" (&_argvec[2]) \
sewardj9734b202006-01-17 01:49:37 +0000941 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
942 ); \
943 lval = (__typeof__(lval)) _res; \
944 } while (0)
945
946#endif /* ARCH_ppc64 */
947
sewardj0ec07f32006-01-12 12:32:32 +0000948
949/* ------------------------------------------------------------------ */
950/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
951/* */
njn30d76c62005-06-18 15:07:39 +0000952/* ------------------------------------------------------------------ */
953
sewardj2e93c502002-04-12 11:12:52 +0000954/* Some request codes. There are many more of these, but most are not
955 exposed to end-user view. These are the public ones, all of the
njn25e49d8e72002-09-23 09:36:25 +0000956 form 0x1000 + small_number.
njnd7994182003-10-02 13:44:04 +0000957
sewardj0ec07f32006-01-12 12:32:32 +0000958 Core ones are in the range 0x00000000--0x0000ffff. The non-public
959 ones start at 0x2000.
sewardj2e93c502002-04-12 11:12:52 +0000960*/
961
sewardj0ec07f32006-01-12 12:32:32 +0000962/* These macros are used by tools -- they must be public, but don't
963 embed them into other programs. */
njnfc26ff92004-11-22 19:12:49 +0000964#define VG_USERREQ_TOOL_BASE(a,b) \
njn4c791212003-05-02 17:53:54 +0000965 ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
njnfc26ff92004-11-22 19:12:49 +0000966#define VG_IS_TOOL_USERREQ(a, b, v) \
967 (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
sewardj34042512002-10-22 04:14:35 +0000968
njn25e49d8e72002-09-23 09:36:25 +0000969typedef
njn4c791212003-05-02 17:53:54 +0000970 enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
971 VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
njn3e884182003-04-15 13:03:23 +0000972
sewardj0ec07f32006-01-12 12:32:32 +0000973 /* These allow any function to be called from the simulated
974 CPU but run on the real CPU. Nb: the first arg passed to
975 the function is always the ThreadId of the running
976 thread! So CLIENT_CALL0 actually requires a 1 arg
njnd4795be2004-11-24 11:57:51 +0000977 function, etc. */
njn4c791212003-05-02 17:53:54 +0000978 VG_USERREQ__CLIENT_CALL0 = 0x1101,
979 VG_USERREQ__CLIENT_CALL1 = 0x1102,
980 VG_USERREQ__CLIENT_CALL2 = 0x1103,
981 VG_USERREQ__CLIENT_CALL3 = 0x1104,
njn3e884182003-04-15 13:03:23 +0000982
sewardj0ec07f32006-01-12 12:32:32 +0000983 /* Can be useful in regression testing suites -- eg. can
984 send Valgrind's output to /dev/null and still count
985 errors. */
njn4c791212003-05-02 17:53:54 +0000986 VG_USERREQ__COUNT_ERRORS = 0x1201,
njn47363ab2003-04-21 13:24:40 +0000987
sewardj0ec07f32006-01-12 12:32:32 +0000988 /* These are useful and can be interpreted by any tool that
989 tracks malloc() et al, by using vg_replace_malloc.c. */
njnd7994182003-10-02 13:44:04 +0000990 VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
991 VG_USERREQ__FREELIKE_BLOCK = 0x1302,
rjwalshbc0bb832004-06-19 18:12:36 +0000992 /* Memory pool support. */
993 VG_USERREQ__CREATE_MEMPOOL = 0x1303,
994 VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
995 VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
996 VG_USERREQ__MEMPOOL_FREE = 0x1306,
njnd7994182003-10-02 13:44:04 +0000997
fitzhardinge39de4b42003-10-31 07:12:21 +0000998 /* Allow printfs to valgrind log. */
njn30d76c62005-06-18 15:07:39 +0000999 VG_USERREQ__PRINTF = 0x1401,
rjwalsh0140af52005-06-04 20:42:33 +00001000 VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
1001
1002 /* Stack support. */
1003 VG_USERREQ__STACK_REGISTER = 0x1501,
1004 VG_USERREQ__STACK_DEREGISTER = 0x1502,
1005 VG_USERREQ__STACK_CHANGE = 0x1503,
njn25e49d8e72002-09-23 09:36:25 +00001006 } Vg_ClientRequest;
sewardj2e93c502002-04-12 11:12:52 +00001007
sewardj0ec07f32006-01-12 12:32:32 +00001008#if !defined(__GNUC__)
1009# define __extension__ /* */
muellerc9b36552003-12-31 14:32:23 +00001010#endif
sewardj2e93c502002-04-12 11:12:52 +00001011
sewardj0ec07f32006-01-12 12:32:32 +00001012/* Returns the number of Valgrinds this code is running under. That
1013 is, 0 if running natively, 1 if running under Valgrind, 2 if
1014 running under Valgrind which is running under another Valgrind,
1015 etc. */
1016#define RUNNING_ON_VALGRIND __extension__ \
1017 ({unsigned int _qzz_res; \
1018 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
1019 VG_USERREQ__RUNNING_ON_VALGRIND, \
1020 0, 0, 0, 0); \
1021 _qzz_res; \
sewardjde4a1d02002-03-22 01:27:54 +00001022 })
1023
1024
sewardj18d75132002-05-16 11:06:21 +00001025/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
1026 _qzz_len - 1]. Useful if you are debugging a JITter or some such,
1027 since it provides a way to make sure valgrind will retranslate the
1028 invalidated area. Returns no value. */
sewardj0ec07f32006-01-12 12:32:32 +00001029#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
1030 {unsigned int _qzz_res; \
1031 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1032 VG_USERREQ__DISCARD_TRANSLATIONS, \
1033 _qzz_addr, _qzz_len, 0, 0); \
sewardj18d75132002-05-16 11:06:21 +00001034 }
1035
njn26aba4d2005-05-16 13:31:23 +00001036
sewardj0ec07f32006-01-12 12:32:32 +00001037/* These requests are for getting Valgrind itself to print something.
1038 Possibly with a backtrace. This is a really ugly hack. */
1039
1040#if defined(NVALGRIND)
1041
1042# define VALGRIND_PRINTF(...)
1043# define VALGRIND_PRINTF_BACKTRACE(...)
njn26aba4d2005-05-16 13:31:23 +00001044
1045#else /* NVALGRIND */
fitzhardinge39de4b42003-10-31 07:12:21 +00001046
fitzhardingea09a1b52003-11-07 23:09:48 +00001047int VALGRIND_PRINTF(const char *format, ...)
1048 __attribute__((format(__printf__, 1, 2)));
fitzhardinge39de4b42003-10-31 07:12:21 +00001049__attribute__((weak))
1050int
fitzhardingea09a1b52003-11-07 23:09:48 +00001051VALGRIND_PRINTF(const char *format, ...)
fitzhardinge39de4b42003-10-31 07:12:21 +00001052{
njnc6168192004-11-29 13:54:10 +00001053 unsigned long _qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001054 va_list vargs;
1055 va_start(vargs, format);
sewardj0ec07f32006-01-12 12:32:32 +00001056 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
njnc6168192004-11-29 13:54:10 +00001057 (unsigned long)format, (unsigned long)vargs, 0, 0);
fitzhardinge39de4b42003-10-31 07:12:21 +00001058 va_end(vargs);
njnc6168192004-11-29 13:54:10 +00001059 return (int)_qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001060}
1061
fitzhardingea09a1b52003-11-07 23:09:48 +00001062int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
1063 __attribute__((format(__printf__, 1, 2)));
fitzhardinge39de4b42003-10-31 07:12:21 +00001064__attribute__((weak))
1065int
fitzhardingea09a1b52003-11-07 23:09:48 +00001066VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
fitzhardinge39de4b42003-10-31 07:12:21 +00001067{
njnc6168192004-11-29 13:54:10 +00001068 unsigned long _qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001069 va_list vargs;
1070 va_start(vargs, format);
sewardj0ec07f32006-01-12 12:32:32 +00001071 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
njnc6168192004-11-29 13:54:10 +00001072 (unsigned long)format, (unsigned long)vargs, 0, 0);
fitzhardinge39de4b42003-10-31 07:12:21 +00001073 va_end(vargs);
njnc6168192004-11-29 13:54:10 +00001074 return (int)_qzz_res;
fitzhardinge39de4b42003-10-31 07:12:21 +00001075}
1076
fitzhardinge39de4b42003-10-31 07:12:21 +00001077#endif /* NVALGRIND */
sewardj18d75132002-05-16 11:06:21 +00001078
sewardj0ec07f32006-01-12 12:32:32 +00001079
njn3e884182003-04-15 13:03:23 +00001080/* These requests allow control to move from the simulated CPU to the
1081 real CPU, calling an arbitary function */
sewardj0ec07f32006-01-12 12:32:32 +00001082#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
1083 ({unsigned long _qyy_res; \
1084 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1085 VG_USERREQ__CLIENT_CALL0, \
1086 _qyy_fn, \
1087 0, 0, 0); \
1088 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001089 })
1090
sewardj0ec07f32006-01-12 12:32:32 +00001091#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
1092 ({unsigned long _qyy_res; \
1093 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1094 VG_USERREQ__CLIENT_CALL1, \
1095 _qyy_fn, \
1096 _qyy_arg1, 0, 0); \
1097 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001098 })
1099
sewardj0ec07f32006-01-12 12:32:32 +00001100#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
1101 ({unsigned long _qyy_res; \
1102 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1103 VG_USERREQ__CLIENT_CALL2, \
1104 _qyy_fn, \
1105 _qyy_arg1, _qyy_arg2, 0); \
1106 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001107 })
1108
sewardj0ec07f32006-01-12 12:32:32 +00001109#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
1110 ({unsigned long _qyy_res; \
1111 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1112 VG_USERREQ__CLIENT_CALL3, \
1113 _qyy_fn, \
1114 _qyy_arg1, _qyy_arg2, _qyy_arg3); \
1115 _qyy_res; \
njn3e884182003-04-15 13:03:23 +00001116 })
1117
1118
nethercote7cc9c232004-01-21 15:08:04 +00001119/* Counts the number of errors that have been recorded by a tool. Nb:
1120 the tool must record the errors with VG_(maybe_record_error)() or
njn47363ab2003-04-21 13:24:40 +00001121 VG_(unique_error)() for them to be counted. */
sewardj0ec07f32006-01-12 12:32:32 +00001122#define VALGRIND_COUNT_ERRORS \
1123 ({unsigned int _qyy_res; \
1124 VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
1125 VG_USERREQ__COUNT_ERRORS, \
1126 0, 0, 0, 0); \
1127 _qyy_res; \
njn47363ab2003-04-21 13:24:40 +00001128 })
1129
njnd7994182003-10-02 13:44:04 +00001130/* Mark a block of memory as having been allocated by a malloc()-like
1131 function. `addr' is the start of the usable block (ie. after any
1132 redzone) `rzB' is redzone size if the allocator can apply redzones;
1133 use '0' if not. Adding redzones makes it more likely Valgrind will spot
1134 block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
1135 for calloc(). Put it immediately after the point where a block is
1136 allocated.
1137
1138 If you're allocating memory via superblocks, and then handing out small
1139 chunks of each superblock, if you don't have redzones on your small
1140 blocks, it's worth marking the superblock with VALGRIND_MAKE_NOACCESS
1141 when it's created, so that block overruns are detected. But if you can
1142 put redzones on, it's probably better to not do this, so that messages
1143 for small overruns are described in terms of the small block rather than
1144 the superblock (but if you have a big overrun that skips over a redzone,
1145 you could miss an error this way). See memcheck/tests/custom_alloc.c
1146 for an example.
1147
1148 Nb: block must be freed via a free()-like function specified
1149 with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
sewardj0ec07f32006-01-12 12:32:32 +00001150#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
1151 {unsigned int _qzz_res; \
1152 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1153 VG_USERREQ__MALLOCLIKE_BLOCK, \
1154 addr, sizeB, rzB, is_zeroed); \
njnd7994182003-10-02 13:44:04 +00001155 }
1156
1157/* Mark a block of memory as having been freed by a free()-like function.
1158 `rzB' is redzone size; it must match that given to
1159 VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
1160 checker. Put it immediately after the point where the block is freed. */
sewardj0ec07f32006-01-12 12:32:32 +00001161#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
1162 {unsigned int _qzz_res; \
1163 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1164 VG_USERREQ__FREELIKE_BLOCK, \
1165 addr, rzB, 0, 0); \
njnd7994182003-10-02 13:44:04 +00001166 }
1167
rjwalshbc0bb832004-06-19 18:12:36 +00001168/* Create a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001169#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
1170 {unsigned int _qzz_res; \
1171 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1172 VG_USERREQ__CREATE_MEMPOOL, \
1173 pool, rzB, is_zeroed, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001174 }
1175
1176/* Destroy a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001177#define VALGRIND_DESTROY_MEMPOOL(pool) \
1178 {unsigned int _qzz_res; \
1179 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1180 VG_USERREQ__DESTROY_MEMPOOL, \
1181 pool, 0, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001182 }
1183
1184/* Associate a piece of memory with a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001185#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
1186 {unsigned int _qzz_res; \
1187 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1188 VG_USERREQ__MEMPOOL_ALLOC, \
1189 pool, addr, size, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001190 }
1191
1192/* Disassociate a piece of memory from a memory pool. */
sewardj0ec07f32006-01-12 12:32:32 +00001193#define VALGRIND_MEMPOOL_FREE(pool, addr) \
1194 {unsigned int _qzz_res; \
1195 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1196 VG_USERREQ__MEMPOOL_FREE, \
1197 pool, addr, 0, 0); \
rjwalshbc0bb832004-06-19 18:12:36 +00001198 }
1199
rjwalsh0140af52005-06-04 20:42:33 +00001200/* Mark a piece of memory as being a stack. Returns a stack id. */
sewardj0ec07f32006-01-12 12:32:32 +00001201#define VALGRIND_STACK_REGISTER(start, end) \
1202 ({unsigned int _qzz_res; \
1203 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1204 VG_USERREQ__STACK_REGISTER, \
1205 start, end, 0, 0); \
1206 _qzz_res; \
rjwalsh0140af52005-06-04 20:42:33 +00001207 })
1208
1209/* Unmark the piece of memory associated with a stack id as being a
1210 stack. */
sewardj0ec07f32006-01-12 12:32:32 +00001211#define VALGRIND_STACK_DEREGISTER(id) \
1212 {unsigned int _qzz_res; \
1213 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1214 VG_USERREQ__STACK_DEREGISTER, \
1215 id, 0, 0, 0); \
rjwalsh0140af52005-06-04 20:42:33 +00001216 }
1217
1218/* Change the start and end address of the stack id. */
sewardj0ec07f32006-01-12 12:32:32 +00001219#define VALGRIND_STACK_CHANGE(id, start, end) \
1220 {unsigned int _qzz_res; \
1221 VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
1222 VG_USERREQ__STACK_CHANGE, \
1223 id, start, end, 0); \
rjwalsh0140af52005-06-04 20:42:33 +00001224 }
1225
sewardj0ec07f32006-01-12 12:32:32 +00001226
1227#undef ARCH_x86
1228#undef ARCH_amd64
1229#undef ARCH_ppc32
1230#undef ARCH_ppc64
1231
njn3e884182003-04-15 13:03:23 +00001232#endif /* __VALGRIND_H */