1 /* SPDX-License-Identifier: GPL-2.0+ AND bzip2-1.0.6 */
3 This file is part of Valgrind, a dynamic binary instrumentation
6 Copyright (C) 2000-2017 Julian Seward. All rights reserved.
7 Copyright (C) 2021 Sean Anderson <seanga2@gmail.com>
10 /* This file is for inclusion into client (your!) code.
12 You can use these macros to manipulate and query Valgrind's
13 execution inside your own programs.
15 The resulting executables will still run without Valgrind, just a
16 little bit more slowly than they otherwise would, but otherwise
17 unchanged. When not running on valgrind, each client request
18 consumes very few (eg. 7) instructions, so the resulting performance
19 loss is negligible unless you plan to execute client requests
20 millions of times per second. Nevertheless, if that is still a
21 problem, you can compile with the NVALGRIND symbol defined (gcc
22 -DNVALGRIND) so that client requests are not even compiled in. */
28 /* ------------------------------------------------------------------ */
29 /* VERSION NUMBER OF VALGRIND */
30 /* ------------------------------------------------------------------ */
32 /* Specify Valgrind's version number, so that user code can
33 conditionally compile based on our version number. Note that these
34 were introduced at version 3.6 and so do not exist in version 3.5
35 or earlier. The recommended way to use them to check for "version
38 #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \
39 && (__VALGRIND_MAJOR__ > 3 \
40 || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
42 #define __VALGRIND_MAJOR__ 3
43 #define __VALGRIND_MINOR__ 16
48 /* Nb: this file might be included in a file compiled with -ansi. So
49 we can't use C++ style "//" comments nor the "asm" keyword (instead
52 /* Derive some tags indicating what the target platform is. Note
53 that in this file we're using the compiler's CPP symbols for
54 identifying architectures, which are different to the ones we use
55 within the rest of Valgrind. Note, __powerpc__ is active for both
56 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
57 latter (on Linux, that is).
59 Misc note: how to find out what's predefined in gcc by default:
60 gcc -Wp,-dM somefile.c
62 #undef PLAT_x86_darwin
63 #undef PLAT_amd64_darwin
65 #undef PLAT_amd64_win64
67 #undef PLAT_amd64_linux
68 #undef PLAT_ppc32_linux
69 #undef PLAT_ppc64be_linux
70 #undef PLAT_ppc64le_linux
72 #undef PLAT_arm64_linux
73 #undef PLAT_s390x_linux
74 #undef PLAT_mips32_linux
75 #undef PLAT_mips64_linux
76 #undef PLAT_nanomips_linux
77 #undef PLAT_x86_solaris
78 #undef PLAT_amd64_solaris
81 #if defined(__APPLE__) && defined(__i386__)
82 # define PLAT_x86_darwin 1
83 #elif defined(__APPLE__) && defined(__x86_64__)
84 # define PLAT_amd64_darwin 1
85 #elif (defined(__MINGW32__) && defined(__i386__)) \
86 || defined(__CYGWIN32__) \
87 || (defined(_WIN32) && defined(_M_IX86))
88 # define PLAT_x86_win32 1
89 #elif (defined(__MINGW32__) && defined(__x86_64__)) \
90 || (defined(_WIN32) && defined(_M_X64))
91 /* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */
92 # define PLAT_amd64_win64 1
93 #elif defined(__linux__) && defined(__i386__)
94 # define PLAT_x86_linux 1
95 #elif defined(__linux__) && defined(__x86_64__) && !defined(__ILP32__)
96 # define PLAT_amd64_linux 1
97 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
98 # define PLAT_ppc32_linux 1
99 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2
100 /* Big Endian uses ELF version 1 */
101 # define PLAT_ppc64be_linux 1
102 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2
103 /* Little Endian uses ELF version 2 */
104 # define PLAT_ppc64le_linux 1
105 #elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__)
106 # define PLAT_arm_linux 1
107 #elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__)
108 # define PLAT_arm64_linux 1
109 #elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
110 # define PLAT_s390x_linux 1
111 #elif defined(__linux__) && defined(__mips__) && (__mips==64)
112 # define PLAT_mips64_linux 1
113 #elif defined(__linux__) && defined(__mips__) && (__mips==32)
114 # define PLAT_mips32_linux 1
115 #elif defined(__linux__) && defined(__nanomips__)
116 # define PLAT_nanomips_linux 1
117 #elif defined(__sun) && defined(__i386__)
118 # define PLAT_x86_solaris 1
119 #elif defined(__sun) && defined(__x86_64__)
120 # define PLAT_amd64_solaris 1
122 /* If we're not compiling for our target platform, don't generate
124 # undef CONFIG_VALGRIND
128 /* ------------------------------------------------------------------ */
129 /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
130 /* in here of use to end-users -- skip to the next section. */
131 /* ------------------------------------------------------------------ */
134 * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
135 * request. Accepts both pointers and integers as arguments.
137 * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
138 * client request that does not return a value.
140 * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
141 * client request and whose value equals the client request result. Accepts
142 * both pointers and integers as arguments. Note that such calls are not
143 * necessarily pure functions -- they may have side effects.
146 #define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \
147 _zzq_request, _zzq_arg1, _zzq_arg2, \
148 _zzq_arg3, _zzq_arg4, _zzq_arg5) \
149 do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \
150 (_zzq_request), (_zzq_arg1), (_zzq_arg2), \
151 (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
153 #define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \
154 _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
155 do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
156 (_zzq_request), (_zzq_arg1), (_zzq_arg2), \
157 (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
159 #if !IS_ENABLED(CONFIG_VALGRIND)
161 /* Define NVALGRIND to completely remove the Valgrind magic sequence
162 from the compiled code (analogous to NDEBUG's effects on
164 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
165 _zzq_default, _zzq_request, \
166 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
169 #else /* ! CONFIG_VALGRIND */
171 /* The following defines the magic code sequences which the JITter
172 spots and handles magically. Don't look too closely at them as
173 they will rot your brain.
175 The assembly code sequences for all architectures is in this one
176 file. This is because this file must be stand-alone, and we don't
177 want to have multiple files.
179 For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
180 value gets put in the return slot, so that everything works when
181 this is executed not under Valgrind. Args are passed in a memory
182 block, and so there's no intrinsic limit to the number that could
183 be passed, but it's currently five.
186 _zzq_rlval result lvalue
187 _zzq_default default value (result returned when running on real CPU)
188 _zzq_request request code
189 _zzq_arg1..5 request params
191 The other two macros are used to support function wrapping, and are
192 a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
193 guest's NRADDR pseudo-register and whatever other information is
194 needed to safely run the call original from the wrapper: on
195 ppc64-linux, the R2 value at the divert point is also needed. This
196 information is abstracted into a user-visible type, OrigFn.
198 VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
199 guest, but guarantees that the branch instruction will not be
200 redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
201 branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
202 complete inline asm, since it needs to be combined with more magic
203 inline asm stuff to be useful.
206 /* ----------------- x86-{linux,darwin,solaris} ---------------- */
208 #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
209 || (defined(PLAT_x86_win32) && defined(__GNUC__)) \
210 || defined(PLAT_x86_solaris)
214 unsigned int nraddr; /* where's the code? */
218 #define __SPECIAL_INSTRUCTION_PREAMBLE \
219 "roll $3, %%edi ; roll $13, %%edi\n\t" \
220 "roll $29, %%edi ; roll $19, %%edi\n\t"
222 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
223 _zzq_default, _zzq_request, \
224 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
226 ({volatile unsigned int _zzq_args[6]; \
227 volatile unsigned int _zzq_result; \
228 _zzq_args[0] = (unsigned int)(_zzq_request); \
229 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
230 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
231 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
232 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
233 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
234 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
235 /* %EDX = client_request ( %EAX ) */ \
236 "xchgl %%ebx,%%ebx" \
237 : "=d" (_zzq_result) \
238 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
244 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
245 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
246 volatile unsigned int __addr; \
247 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
248 /* %EAX = guest_NRADDR */ \
249 "xchgl %%ecx,%%ecx" \
254 _zzq_orig->nraddr = __addr; \
257 #define VALGRIND_CALL_NOREDIR_EAX \
258 __SPECIAL_INSTRUCTION_PREAMBLE \
259 /* call-noredir *%EAX */ \
260 "xchgl %%edx,%%edx\n\t"
262 #define VALGRIND_VEX_INJECT_IR() \
264 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
265 "xchgl %%edi,%%edi\n\t" \
266 : : : "cc", "memory" \
270 #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__)
271 || PLAT_x86_solaris */
273 /* ------------------------- x86-Win32 ------------------------- */
275 #if defined(PLAT_x86_win32) && !defined(__GNUC__)
279 unsigned int nraddr; /* where's the code? */
283 #if defined(_MSC_VER)
285 #define __SPECIAL_INSTRUCTION_PREAMBLE \
286 __asm rol edi, 3 __asm rol edi, 13 \
287 __asm rol edi, 29 __asm rol edi, 19
289 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
290 _zzq_default, _zzq_request, \
291 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
292 valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \
293 (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \
294 (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \
295 (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
297 static __inline uintptr_t
298 valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
299 uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
300 uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
303 volatile uintptr_t _zzq_args[6];
304 volatile unsigned int _zzq_result;
305 _zzq_args[0] = (uintptr_t)(_zzq_request);
306 _zzq_args[1] = (uintptr_t)(_zzq_arg1);
307 _zzq_args[2] = (uintptr_t)(_zzq_arg2);
308 _zzq_args[3] = (uintptr_t)(_zzq_arg3);
309 _zzq_args[4] = (uintptr_t)(_zzq_arg4);
310 _zzq_args[5] = (uintptr_t)(_zzq_arg5);
311 __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
312 __SPECIAL_INSTRUCTION_PREAMBLE
313 /* %EDX = client_request ( %EAX ) */
315 __asm mov _zzq_result, edx
320 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
321 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
322 volatile unsigned int __addr; \
323 __asm { __SPECIAL_INSTRUCTION_PREAMBLE \
324 /* %EAX = guest_NRADDR */ \
326 __asm mov __addr, eax \
328 _zzq_orig->nraddr = __addr; \
331 #define VALGRIND_CALL_NOREDIR_EAX ERROR
333 #define VALGRIND_VEX_INJECT_IR() \
335 __asm { __SPECIAL_INSTRUCTION_PREAMBLE \
341 #error Unsupported compiler.
344 #endif /* PLAT_x86_win32 */
346 /* ----------------- amd64-{linux,darwin,solaris} --------------- */
348 #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
349 || defined(PLAT_amd64_solaris) \
350 || (defined(PLAT_amd64_win64) && defined(__GNUC__))
354 unsigned long int nraddr; /* where's the code? */
358 #define __SPECIAL_INSTRUCTION_PREAMBLE \
359 "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
360 "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
362 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
363 _zzq_default, _zzq_request, \
364 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
366 ({ volatile unsigned long int _zzq_args[6]; \
367 volatile unsigned long int _zzq_result; \
368 _zzq_args[0] = (unsigned long int)(_zzq_request); \
369 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
370 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
371 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
372 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
373 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
374 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
375 /* %RDX = client_request ( %RAX ) */ \
376 "xchgq %%rbx,%%rbx" \
377 : "=d" (_zzq_result) \
378 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
384 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
385 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
386 volatile unsigned long int __addr; \
387 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
388 /* %RAX = guest_NRADDR */ \
389 "xchgq %%rcx,%%rcx" \
394 _zzq_orig->nraddr = __addr; \
397 #define VALGRIND_CALL_NOREDIR_RAX \
398 __SPECIAL_INSTRUCTION_PREAMBLE \
399 /* call-noredir *%RAX */ \
400 "xchgq %%rdx,%%rdx\n\t"
402 #define VALGRIND_VEX_INJECT_IR() \
404 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
405 "xchgq %%rdi,%%rdi\n\t" \
406 : : : "cc", "memory" \
410 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */
412 /* ------------------------- amd64-Win64 ------------------------- */
414 #if defined(PLAT_amd64_win64) && !defined(__GNUC__)
416 #error Unsupported compiler.
418 #endif /* PLAT_amd64_win64 */
420 /* ------------------------ ppc32-linux ------------------------ */
422 #if defined(PLAT_ppc32_linux)
426 unsigned int nraddr; /* where's the code? */
430 #define __SPECIAL_INSTRUCTION_PREAMBLE \
431 "rlwinm 0,0,3,0,31 ; rlwinm 0,0,13,0,31\n\t" \
432 "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t"
434 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
435 _zzq_default, _zzq_request, \
436 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
439 ({ unsigned int _zzq_args[6]; \
440 unsigned int _zzq_result; \
441 unsigned int* _zzq_ptr; \
442 _zzq_args[0] = (unsigned int)(_zzq_request); \
443 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
444 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
445 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
446 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
447 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
448 _zzq_ptr = _zzq_args; \
449 __asm__ volatile("mr 3,%1\n\t" /*default*/ \
450 "mr 4,%2\n\t" /*ptr*/ \
451 __SPECIAL_INSTRUCTION_PREAMBLE \
452 /* %R3 = client_request ( %R4 ) */ \
454 "mr %0,3" /*result*/ \
455 : "=b" (_zzq_result) \
456 : "b" (_zzq_default), "b" (_zzq_ptr) \
457 : "cc", "memory", "r3", "r4"); \
461 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
462 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
463 unsigned int __addr; \
464 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
465 /* %R3 = guest_NRADDR */ \
470 : "cc", "memory", "r3" \
472 _zzq_orig->nraddr = __addr; \
475 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
476 __SPECIAL_INSTRUCTION_PREAMBLE \
477 /* branch-and-link-to-noredir *%R11 */ \
480 #define VALGRIND_VEX_INJECT_IR() \
482 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
487 #endif /* PLAT_ppc32_linux */
489 /* ------------------------ ppc64-linux ------------------------ */
491 #if defined(PLAT_ppc64be_linux)
495 unsigned long int nraddr; /* where's the code? */
496 unsigned long int r2; /* what tocptr do we need? */
500 #define __SPECIAL_INSTRUCTION_PREAMBLE \
501 "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
502 "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
504 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
505 _zzq_default, _zzq_request, \
506 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
509 ({ unsigned long int _zzq_args[6]; \
510 unsigned long int _zzq_result; \
511 unsigned long int* _zzq_ptr; \
512 _zzq_args[0] = (unsigned long int)(_zzq_request); \
513 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
514 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
515 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
516 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
517 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
518 _zzq_ptr = _zzq_args; \
519 __asm__ volatile("mr 3,%1\n\t" /*default*/ \
520 "mr 4,%2\n\t" /*ptr*/ \
521 __SPECIAL_INSTRUCTION_PREAMBLE \
522 /* %R3 = client_request ( %R4 ) */ \
524 "mr %0,3" /*result*/ \
525 : "=b" (_zzq_result) \
526 : "b" (_zzq_default), "b" (_zzq_ptr) \
527 : "cc", "memory", "r3", "r4"); \
531 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
532 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
533 unsigned long int __addr; \
534 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
535 /* %R3 = guest_NRADDR */ \
540 : "cc", "memory", "r3" \
542 _zzq_orig->nraddr = __addr; \
543 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
544 /* %R3 = guest_NRADDR_GPR2 */ \
549 : "cc", "memory", "r3" \
551 _zzq_orig->r2 = __addr; \
554 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
555 __SPECIAL_INSTRUCTION_PREAMBLE \
556 /* branch-and-link-to-noredir *%R11 */ \
559 #define VALGRIND_VEX_INJECT_IR() \
561 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
566 #endif /* PLAT_ppc64be_linux */
568 #if defined(PLAT_ppc64le_linux)
572 unsigned long int nraddr; /* where's the code? */
573 unsigned long int r2; /* what tocptr do we need? */
577 #define __SPECIAL_INSTRUCTION_PREAMBLE \
578 "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
579 "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
581 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
582 _zzq_default, _zzq_request, \
583 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
586 ({ unsigned long int _zzq_args[6]; \
587 unsigned long int _zzq_result; \
588 unsigned long int* _zzq_ptr; \
589 _zzq_args[0] = (unsigned long int)(_zzq_request); \
590 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
591 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
592 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
593 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
594 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
595 _zzq_ptr = _zzq_args; \
596 __asm__ volatile("mr 3,%1\n\t" /*default*/ \
597 "mr 4,%2\n\t" /*ptr*/ \
598 __SPECIAL_INSTRUCTION_PREAMBLE \
599 /* %R3 = client_request ( %R4 ) */ \
601 "mr %0,3" /*result*/ \
602 : "=b" (_zzq_result) \
603 : "b" (_zzq_default), "b" (_zzq_ptr) \
604 : "cc", "memory", "r3", "r4"); \
608 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
609 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
610 unsigned long int __addr; \
611 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
612 /* %R3 = guest_NRADDR */ \
617 : "cc", "memory", "r3" \
619 _zzq_orig->nraddr = __addr; \
620 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
621 /* %R3 = guest_NRADDR_GPR2 */ \
626 : "cc", "memory", "r3" \
628 _zzq_orig->r2 = __addr; \
631 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
632 __SPECIAL_INSTRUCTION_PREAMBLE \
633 /* branch-and-link-to-noredir *%R12 */ \
636 #define VALGRIND_VEX_INJECT_IR() \
638 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
643 #endif /* PLAT_ppc64le_linux */
645 /* ------------------------- arm-linux ------------------------- */
647 #if defined(PLAT_arm_linux)
651 unsigned int nraddr; /* where's the code? */
655 #define __SPECIAL_INSTRUCTION_PREAMBLE \
656 "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \
657 "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
659 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
660 _zzq_default, _zzq_request, \
661 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
664 ({volatile unsigned int _zzq_args[6]; \
665 volatile unsigned int _zzq_result; \
666 _zzq_args[0] = (unsigned int)(_zzq_request); \
667 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
668 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
669 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
670 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
671 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
672 __asm__ volatile("mov r3, %1\n\t" /*default*/ \
673 "mov r4, %2\n\t" /*ptr*/ \
674 __SPECIAL_INSTRUCTION_PREAMBLE \
675 /* R3 = client_request ( R4 ) */ \
676 "orr r10, r10, r10\n\t" \
677 "mov %0, r3" /*result*/ \
678 : "=r" (_zzq_result) \
679 : "r" (_zzq_default), "r" (&_zzq_args[0]) \
680 : "cc","memory", "r3", "r4"); \
684 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
685 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
686 unsigned int __addr; \
687 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
688 /* R3 = guest_NRADDR */ \
689 "orr r11, r11, r11\n\t" \
693 : "cc", "memory", "r3" \
695 _zzq_orig->nraddr = __addr; \
698 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
699 __SPECIAL_INSTRUCTION_PREAMBLE \
700 /* branch-and-link-to-noredir *%R4 */ \
701 "orr r12, r12, r12\n\t"
703 #define VALGRIND_VEX_INJECT_IR() \
705 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
706 "orr r9, r9, r9\n\t" \
707 : : : "cc", "memory" \
711 #endif /* PLAT_arm_linux */
713 /* ------------------------ arm64-linux ------------------------- */
715 #if defined(PLAT_arm64_linux)
719 unsigned long int nraddr; /* where's the code? */
723 #define __SPECIAL_INSTRUCTION_PREAMBLE \
724 "ror x12, x12, #3 ; ror x12, x12, #13 \n\t" \
725 "ror x12, x12, #51 ; ror x12, x12, #61 \n\t"
727 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
728 _zzq_default, _zzq_request, \
729 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
732 ({volatile unsigned long int _zzq_args[6]; \
733 volatile unsigned long int _zzq_result; \
734 _zzq_args[0] = (unsigned long int)(_zzq_request); \
735 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
736 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
737 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
738 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
739 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
740 __asm__ volatile("mov x3, %1\n\t" /*default*/ \
741 "mov x4, %2\n\t" /*ptr*/ \
742 __SPECIAL_INSTRUCTION_PREAMBLE \
743 /* X3 = client_request ( X4 ) */ \
744 "orr x10, x10, x10\n\t" \
745 "mov %0, x3" /*result*/ \
746 : "=r" (_zzq_result) \
747 : "r" ((unsigned long int)(_zzq_default)), \
748 "r" (&_zzq_args[0]) \
749 : "cc","memory", "x3", "x4"); \
753 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
754 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
755 unsigned long int __addr; \
756 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
757 /* X3 = guest_NRADDR */ \
758 "orr x11, x11, x11\n\t" \
762 : "cc", "memory", "x3" \
764 _zzq_orig->nraddr = __addr; \
767 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
768 __SPECIAL_INSTRUCTION_PREAMBLE \
769 /* branch-and-link-to-noredir X8 */ \
770 "orr x12, x12, x12\n\t"
772 #define VALGRIND_VEX_INJECT_IR() \
774 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
775 "orr x9, x9, x9\n\t" \
776 : : : "cc", "memory" \
780 #endif /* PLAT_arm64_linux */
782 /* ------------------------ s390x-linux ------------------------ */
784 #if defined(PLAT_s390x_linux)
788 unsigned long int nraddr; /* where's the code? */
792 /* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
793 * code. This detection is implemented in platform specific toIR.c
794 * (e.g. VEX/priv/guest_s390_decoder.c).
796 #define __SPECIAL_INSTRUCTION_PREAMBLE \
802 #define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
803 #define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
804 #define __CALL_NO_REDIR_CODE "lr 4,4\n\t"
805 #define __VEX_INJECT_IR_CODE "lr 5,5\n\t"
807 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
808 _zzq_default, _zzq_request, \
809 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
811 ({volatile unsigned long int _zzq_args[6]; \
812 volatile unsigned long int _zzq_result; \
813 _zzq_args[0] = (unsigned long int)(_zzq_request); \
814 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
815 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
816 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
817 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
818 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
819 __asm__ volatile(/* r2 = args */ \
823 __SPECIAL_INSTRUCTION_PREAMBLE \
824 __CLIENT_REQUEST_CODE \
827 : "=d" (_zzq_result) \
828 : "a" (&_zzq_args[0]), "0" (_zzq_default) \
829 : "cc", "2", "3", "memory" \
834 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
835 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
836 volatile unsigned long int __addr; \
837 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
838 __GET_NR_CONTEXT_CODE \
842 : "cc", "3", "memory" \
844 _zzq_orig->nraddr = __addr; \
847 #define VALGRIND_CALL_NOREDIR_R1 \
848 __SPECIAL_INSTRUCTION_PREAMBLE \
851 #define VALGRIND_VEX_INJECT_IR() \
853 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
854 __VEX_INJECT_IR_CODE); \
857 #endif /* PLAT_s390x_linux */
859 /* ------------------------- mips32-linux ---------------- */
861 #if defined(PLAT_mips32_linux)
865 unsigned int nraddr; /* where's the code? */
873 #define __SPECIAL_INSTRUCTION_PREAMBLE \
874 "srl $0, $0, 13\n\t" \
875 "srl $0, $0, 29\n\t" \
876 "srl $0, $0, 3\n\t" \
879 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
880 _zzq_default, _zzq_request, \
881 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
883 ({ volatile unsigned int _zzq_args[6]; \
884 volatile unsigned int _zzq_result; \
885 _zzq_args[0] = (unsigned int)(_zzq_request); \
886 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
887 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
888 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
889 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
890 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
891 __asm__ volatile("move $11, %1\n\t" /*default*/ \
892 "move $12, %2\n\t" /*ptr*/ \
893 __SPECIAL_INSTRUCTION_PREAMBLE \
894 /* T3 = client_request ( T4 ) */ \
895 "or $13, $13, $13\n\t" \
896 "move %0, $11\n\t" /*result*/ \
897 : "=r" (_zzq_result) \
898 : "r" (_zzq_default), "r" (&_zzq_args[0]) \
899 : "$11", "$12", "memory"); \
903 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
904 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
905 volatile unsigned int __addr; \
906 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
907 /* %t9 = guest_NRADDR */ \
908 "or $14, $14, $14\n\t" \
909 "move %0, $11" /*result*/ \
914 _zzq_orig->nraddr = __addr; \
917 #define VALGRIND_CALL_NOREDIR_T9 \
918 __SPECIAL_INSTRUCTION_PREAMBLE \
919 /* call-noredir *%t9 */ \
920 "or $15, $15, $15\n\t"
922 #define VALGRIND_VEX_INJECT_IR() \
924 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
925 "or $11, $11, $11\n\t" \
930 #endif /* PLAT_mips32_linux */
932 /* ------------------------- mips64-linux ---------------- */
934 #if defined(PLAT_mips64_linux)
938 unsigned long nraddr; /* where's the code? */
946 #define __SPECIAL_INSTRUCTION_PREAMBLE \
947 "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \
948 "dsll $0,$0,29 ; dsll $0,$0,19\n\t"
950 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
951 _zzq_default, _zzq_request, \
952 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
954 ({ volatile unsigned long int _zzq_args[6]; \
955 volatile unsigned long int _zzq_result; \
956 _zzq_args[0] = (unsigned long int)(_zzq_request); \
957 _zzq_args[1] = (unsigned long int)(_zzq_arg1); \
958 _zzq_args[2] = (unsigned long int)(_zzq_arg2); \
959 _zzq_args[3] = (unsigned long int)(_zzq_arg3); \
960 _zzq_args[4] = (unsigned long int)(_zzq_arg4); \
961 _zzq_args[5] = (unsigned long int)(_zzq_arg5); \
962 __asm__ volatile("move $11, %1\n\t" /*default*/ \
963 "move $12, %2\n\t" /*ptr*/ \
964 __SPECIAL_INSTRUCTION_PREAMBLE \
965 /* $11 = client_request ( $12 ) */ \
966 "or $13, $13, $13\n\t" \
967 "move %0, $11\n\t" /*result*/ \
968 : "=r" (_zzq_result) \
969 : "r" (_zzq_default), "r" (&_zzq_args[0]) \
970 : "$11", "$12", "memory"); \
974 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
975 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
976 volatile unsigned long int __addr; \
977 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
978 /* $11 = guest_NRADDR */ \
979 "or $14, $14, $14\n\t" \
980 "move %0, $11" /*result*/ \
984 _zzq_orig->nraddr = __addr; \
987 #define VALGRIND_CALL_NOREDIR_T9 \
988 __SPECIAL_INSTRUCTION_PREAMBLE \
989 /* call-noredir $25 */ \
990 "or $15, $15, $15\n\t"
992 #define VALGRIND_VEX_INJECT_IR() \
994 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
995 "or $11, $11, $11\n\t" \
999 #endif /* PLAT_mips64_linux */
1001 #if defined(PLAT_nanomips_linux)
1005 unsigned int nraddr; /* where's the code? */
1009 8000 c04d srl zero, zero, 13
1010 8000 c05d srl zero, zero, 29
1011 8000 c043 srl zero, zero, 3
1012 8000 c053 srl zero, zero, 19
1015 #define __SPECIAL_INSTRUCTION_PREAMBLE "srl[32] $zero, $zero, 13 \n\t" \
1016 "srl[32] $zero, $zero, 29 \n\t" \
1017 "srl[32] $zero, $zero, 3 \n\t" \
1018 "srl[32] $zero, $zero, 19 \n\t"
1020 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
1021 _zzq_default, _zzq_request, \
1022 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
1024 ({ volatile unsigned int _zzq_args[6]; \
1025 volatile unsigned int _zzq_result; \
1026 _zzq_args[0] = (unsigned int)(_zzq_request); \
1027 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
1028 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
1029 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
1030 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
1031 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
1032 __asm__ volatile("move $a7, %1\n\t" /* default */ \
1033 "move $t0, %2\n\t" /* ptr */ \
1034 __SPECIAL_INSTRUCTION_PREAMBLE \
1035 /* $a7 = client_request( $t0 ) */ \
1036 "or[32] $t0, $t0, $t0\n\t" \
1037 "move %0, $a7\n\t" /* result */ \
1038 : "=r" (_zzq_result) \
1039 : "r" (_zzq_default), "r" (&_zzq_args[0]) \
1040 : "$a7", "$t0", "memory"); \
1044 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
1045 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
1046 volatile unsigned long int __addr; \
1047 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
1048 /* $a7 = guest_NRADDR */ \
1049 "or[32] $t1, $t1, $t1\n\t" \
1050 "move %0, $a7" /*result*/ \
1054 _zzq_orig->nraddr = __addr; \
1057 #define VALGRIND_CALL_NOREDIR_T9 \
1058 __SPECIAL_INSTRUCTION_PREAMBLE \
1059 /* call-noredir $25 */ \
1060 "or[32] $t2, $t2, $t2\n\t"
1062 #define VALGRIND_VEX_INJECT_IR() \
1064 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
1065 "or[32] $t3, $t3, $t3\n\t" \
1070 /* Insert assembly code for other platforms here... */
1072 #endif /* CONFIG_VALGRIND */
1075 /* ------------------------------------------------------------------ */
1076 /* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */
1077 /* ugly. It's the least-worst tradeoff I can think of. */
1078 /* ------------------------------------------------------------------ */
1080 /* This section defines magic (a.k.a appalling-hack) macros for doing
1081 guaranteed-no-redirection macros, so as to get from function
1082 wrappers to the functions they are wrapping. The whole point is to
1083 construct standard call sequences, but to do the call itself with a
1084 special no-redirect call pseudo-instruction that the JIT
1085 understands and handles specially. This section is long and
1086 repetitious, and I can't see a way to make it shorter.
1088 The naming scheme is as follows:
1090 CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
1092 'W' stands for "word" and 'v' for "void". Hence there are
1093 different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
1094 and for each, the possibility of returning a word-typed result, or
1098 /* Use these to write the name of your wrapper. NOTE: duplicates
1099 VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts
1100 the default behaviour equivalance class tag "0000" into the name.
1101 See pub_tool_redir.h for details -- normally you don't need to
1102 think about this, though. */
1104 /* Use an extra level of macroisation so as to ensure the soname/fnname
1105 args are fully macro-expanded before pasting them together. */
1106 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
1108 #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
1109 VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
1111 #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
1112 VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
1114 /* Use this macro from within a wrapper function to collect the
1115 context (address and possibly other info) of the original function.
1116 Once you have that you can then use it in one of the CALL_FN_
1117 macros. The type of the argument _lval is OrigFn. */
1118 #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
1120 /* Also provide end-user facilities for function replacement, rather
1121 than wrapping. A replacement function differs from a wrapper in
1122 that it has no way to get hold of the original function being
1123 called, and hence no way to call onwards to it. In a replacement
1124 function, VALGRIND_GET_ORIG_FN always returns zero. */
1126 #define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \
1127 VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
1129 #define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \
1130 VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
1132 /* Derivatives of the main macros below, for calling functions
1135 #define CALL_FN_v_v(fnptr) \
1136 do { volatile unsigned long _junk; \
1137 CALL_FN_W_v(_junk,fnptr); } while (0)
1139 #define CALL_FN_v_W(fnptr, arg1) \
1140 do { volatile unsigned long _junk; \
1141 CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
1143 #define CALL_FN_v_WW(fnptr, arg1,arg2) \
1144 do { volatile unsigned long _junk; \
1145 CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
1147 #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \
1148 do { volatile unsigned long _junk; \
1149 CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
1151 #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \
1152 do { volatile unsigned long _junk; \
1153 CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
1155 #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \
1156 do { volatile unsigned long _junk; \
1157 CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
1159 #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \
1160 do { volatile unsigned long _junk; \
1161 CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
1163 #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \
1164 do { volatile unsigned long _junk; \
1165 CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
1167 /* ----------------- x86-{linux,darwin,solaris} ---------------- */
1169 #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
1170 || defined(PLAT_x86_solaris)
1172 /* These regs are trashed by the hidden call. No need to mention eax
1173 as gcc can already see that, plus causes gcc to bomb. */
1174 #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
1176 /* Macros to save and align the stack before making a function
1177 call and restore it afterwards as gcc may not keep the stack
1178 pointer aligned if it doesn't realise calls are being made
1179 to other functions. */
1181 #define VALGRIND_ALIGN_STACK \
1182 "movl %%esp,%%edi\n\t" \
1183 "andl $0xfffffff0,%%esp\n\t"
1184 #define VALGRIND_RESTORE_STACK \
1185 "movl %%edi,%%esp\n\t"
1187 /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
1190 #define CALL_FN_W_v(lval, orig) \
1192 volatile OrigFn _orig = (orig); \
1193 volatile unsigned long _argvec[1]; \
1194 volatile unsigned long _res; \
1195 _argvec[0] = (unsigned long)_orig.nraddr; \
1197 VALGRIND_ALIGN_STACK \
1198 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1199 VALGRIND_CALL_NOREDIR_EAX \
1200 VALGRIND_RESTORE_STACK \
1201 : /*out*/ "=a" (_res) \
1202 : /*in*/ "a" (&_argvec[0]) \
1203 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1205 lval = (__typeof__(lval)) _res; \
1208 #define CALL_FN_W_W(lval, orig, arg1) \
1210 volatile OrigFn _orig = (orig); \
1211 volatile unsigned long _argvec[2]; \
1212 volatile unsigned long _res; \
1213 _argvec[0] = (unsigned long)_orig.nraddr; \
1214 _argvec[1] = (unsigned long)(arg1); \
1216 VALGRIND_ALIGN_STACK \
1217 "subl $12, %%esp\n\t" \
1218 "pushl 4(%%eax)\n\t" \
1219 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1220 VALGRIND_CALL_NOREDIR_EAX \
1221 VALGRIND_RESTORE_STACK \
1222 : /*out*/ "=a" (_res) \
1223 : /*in*/ "a" (&_argvec[0]) \
1224 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1226 lval = (__typeof__(lval)) _res; \
1229 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1231 volatile OrigFn _orig = (orig); \
1232 volatile unsigned long _argvec[3]; \
1233 volatile unsigned long _res; \
1234 _argvec[0] = (unsigned long)_orig.nraddr; \
1235 _argvec[1] = (unsigned long)(arg1); \
1236 _argvec[2] = (unsigned long)(arg2); \
1238 VALGRIND_ALIGN_STACK \
1239 "subl $8, %%esp\n\t" \
1240 "pushl 8(%%eax)\n\t" \
1241 "pushl 4(%%eax)\n\t" \
1242 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1243 VALGRIND_CALL_NOREDIR_EAX \
1244 VALGRIND_RESTORE_STACK \
1245 : /*out*/ "=a" (_res) \
1246 : /*in*/ "a" (&_argvec[0]) \
1247 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1249 lval = (__typeof__(lval)) _res; \
1252 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1254 volatile OrigFn _orig = (orig); \
1255 volatile unsigned long _argvec[4]; \
1256 volatile unsigned long _res; \
1257 _argvec[0] = (unsigned long)_orig.nraddr; \
1258 _argvec[1] = (unsigned long)(arg1); \
1259 _argvec[2] = (unsigned long)(arg2); \
1260 _argvec[3] = (unsigned long)(arg3); \
1262 VALGRIND_ALIGN_STACK \
1263 "subl $4, %%esp\n\t" \
1264 "pushl 12(%%eax)\n\t" \
1265 "pushl 8(%%eax)\n\t" \
1266 "pushl 4(%%eax)\n\t" \
1267 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1268 VALGRIND_CALL_NOREDIR_EAX \
1269 VALGRIND_RESTORE_STACK \
1270 : /*out*/ "=a" (_res) \
1271 : /*in*/ "a" (&_argvec[0]) \
1272 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1274 lval = (__typeof__(lval)) _res; \
1277 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1279 volatile OrigFn _orig = (orig); \
1280 volatile unsigned long _argvec[5]; \
1281 volatile unsigned long _res; \
1282 _argvec[0] = (unsigned long)_orig.nraddr; \
1283 _argvec[1] = (unsigned long)(arg1); \
1284 _argvec[2] = (unsigned long)(arg2); \
1285 _argvec[3] = (unsigned long)(arg3); \
1286 _argvec[4] = (unsigned long)(arg4); \
1288 VALGRIND_ALIGN_STACK \
1289 "pushl 16(%%eax)\n\t" \
1290 "pushl 12(%%eax)\n\t" \
1291 "pushl 8(%%eax)\n\t" \
1292 "pushl 4(%%eax)\n\t" \
1293 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1294 VALGRIND_CALL_NOREDIR_EAX \
1295 VALGRIND_RESTORE_STACK \
1296 : /*out*/ "=a" (_res) \
1297 : /*in*/ "a" (&_argvec[0]) \
1298 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1300 lval = (__typeof__(lval)) _res; \
1303 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1305 volatile OrigFn _orig = (orig); \
1306 volatile unsigned long _argvec[6]; \
1307 volatile unsigned long _res; \
1308 _argvec[0] = (unsigned long)_orig.nraddr; \
1309 _argvec[1] = (unsigned long)(arg1); \
1310 _argvec[2] = (unsigned long)(arg2); \
1311 _argvec[3] = (unsigned long)(arg3); \
1312 _argvec[4] = (unsigned long)(arg4); \
1313 _argvec[5] = (unsigned long)(arg5); \
1315 VALGRIND_ALIGN_STACK \
1316 "subl $12, %%esp\n\t" \
1317 "pushl 20(%%eax)\n\t" \
1318 "pushl 16(%%eax)\n\t" \
1319 "pushl 12(%%eax)\n\t" \
1320 "pushl 8(%%eax)\n\t" \
1321 "pushl 4(%%eax)\n\t" \
1322 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1323 VALGRIND_CALL_NOREDIR_EAX \
1324 VALGRIND_RESTORE_STACK \
1325 : /*out*/ "=a" (_res) \
1326 : /*in*/ "a" (&_argvec[0]) \
1327 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1329 lval = (__typeof__(lval)) _res; \
1332 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1334 volatile OrigFn _orig = (orig); \
1335 volatile unsigned long _argvec[7]; \
1336 volatile unsigned long _res; \
1337 _argvec[0] = (unsigned long)_orig.nraddr; \
1338 _argvec[1] = (unsigned long)(arg1); \
1339 _argvec[2] = (unsigned long)(arg2); \
1340 _argvec[3] = (unsigned long)(arg3); \
1341 _argvec[4] = (unsigned long)(arg4); \
1342 _argvec[5] = (unsigned long)(arg5); \
1343 _argvec[6] = (unsigned long)(arg6); \
1345 VALGRIND_ALIGN_STACK \
1346 "subl $8, %%esp\n\t" \
1347 "pushl 24(%%eax)\n\t" \
1348 "pushl 20(%%eax)\n\t" \
1349 "pushl 16(%%eax)\n\t" \
1350 "pushl 12(%%eax)\n\t" \
1351 "pushl 8(%%eax)\n\t" \
1352 "pushl 4(%%eax)\n\t" \
1353 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1354 VALGRIND_CALL_NOREDIR_EAX \
1355 VALGRIND_RESTORE_STACK \
1356 : /*out*/ "=a" (_res) \
1357 : /*in*/ "a" (&_argvec[0]) \
1358 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1360 lval = (__typeof__(lval)) _res; \
1363 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1366 volatile OrigFn _orig = (orig); \
1367 volatile unsigned long _argvec[8]; \
1368 volatile unsigned long _res; \
1369 _argvec[0] = (unsigned long)_orig.nraddr; \
1370 _argvec[1] = (unsigned long)(arg1); \
1371 _argvec[2] = (unsigned long)(arg2); \
1372 _argvec[3] = (unsigned long)(arg3); \
1373 _argvec[4] = (unsigned long)(arg4); \
1374 _argvec[5] = (unsigned long)(arg5); \
1375 _argvec[6] = (unsigned long)(arg6); \
1376 _argvec[7] = (unsigned long)(arg7); \
1378 VALGRIND_ALIGN_STACK \
1379 "subl $4, %%esp\n\t" \
1380 "pushl 28(%%eax)\n\t" \
1381 "pushl 24(%%eax)\n\t" \
1382 "pushl 20(%%eax)\n\t" \
1383 "pushl 16(%%eax)\n\t" \
1384 "pushl 12(%%eax)\n\t" \
1385 "pushl 8(%%eax)\n\t" \
1386 "pushl 4(%%eax)\n\t" \
1387 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1388 VALGRIND_CALL_NOREDIR_EAX \
1389 VALGRIND_RESTORE_STACK \
1390 : /*out*/ "=a" (_res) \
1391 : /*in*/ "a" (&_argvec[0]) \
1392 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1394 lval = (__typeof__(lval)) _res; \
1397 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1400 volatile OrigFn _orig = (orig); \
1401 volatile unsigned long _argvec[9]; \
1402 volatile unsigned long _res; \
1403 _argvec[0] = (unsigned long)_orig.nraddr; \
1404 _argvec[1] = (unsigned long)(arg1); \
1405 _argvec[2] = (unsigned long)(arg2); \
1406 _argvec[3] = (unsigned long)(arg3); \
1407 _argvec[4] = (unsigned long)(arg4); \
1408 _argvec[5] = (unsigned long)(arg5); \
1409 _argvec[6] = (unsigned long)(arg6); \
1410 _argvec[7] = (unsigned long)(arg7); \
1411 _argvec[8] = (unsigned long)(arg8); \
1413 VALGRIND_ALIGN_STACK \
1414 "pushl 32(%%eax)\n\t" \
1415 "pushl 28(%%eax)\n\t" \
1416 "pushl 24(%%eax)\n\t" \
1417 "pushl 20(%%eax)\n\t" \
1418 "pushl 16(%%eax)\n\t" \
1419 "pushl 12(%%eax)\n\t" \
1420 "pushl 8(%%eax)\n\t" \
1421 "pushl 4(%%eax)\n\t" \
1422 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1423 VALGRIND_CALL_NOREDIR_EAX \
1424 VALGRIND_RESTORE_STACK \
1425 : /*out*/ "=a" (_res) \
1426 : /*in*/ "a" (&_argvec[0]) \
1427 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1429 lval = (__typeof__(lval)) _res; \
1432 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1435 volatile OrigFn _orig = (orig); \
1436 volatile unsigned long _argvec[10]; \
1437 volatile unsigned long _res; \
1438 _argvec[0] = (unsigned long)_orig.nraddr; \
1439 _argvec[1] = (unsigned long)(arg1); \
1440 _argvec[2] = (unsigned long)(arg2); \
1441 _argvec[3] = (unsigned long)(arg3); \
1442 _argvec[4] = (unsigned long)(arg4); \
1443 _argvec[5] = (unsigned long)(arg5); \
1444 _argvec[6] = (unsigned long)(arg6); \
1445 _argvec[7] = (unsigned long)(arg7); \
1446 _argvec[8] = (unsigned long)(arg8); \
1447 _argvec[9] = (unsigned long)(arg9); \
1449 VALGRIND_ALIGN_STACK \
1450 "subl $12, %%esp\n\t" \
1451 "pushl 36(%%eax)\n\t" \
1452 "pushl 32(%%eax)\n\t" \
1453 "pushl 28(%%eax)\n\t" \
1454 "pushl 24(%%eax)\n\t" \
1455 "pushl 20(%%eax)\n\t" \
1456 "pushl 16(%%eax)\n\t" \
1457 "pushl 12(%%eax)\n\t" \
1458 "pushl 8(%%eax)\n\t" \
1459 "pushl 4(%%eax)\n\t" \
1460 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1461 VALGRIND_CALL_NOREDIR_EAX \
1462 VALGRIND_RESTORE_STACK \
1463 : /*out*/ "=a" (_res) \
1464 : /*in*/ "a" (&_argvec[0]) \
1465 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1467 lval = (__typeof__(lval)) _res; \
1470 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1471 arg7,arg8,arg9,arg10) \
1473 volatile OrigFn _orig = (orig); \
1474 volatile unsigned long _argvec[11]; \
1475 volatile unsigned long _res; \
1476 _argvec[0] = (unsigned long)_orig.nraddr; \
1477 _argvec[1] = (unsigned long)(arg1); \
1478 _argvec[2] = (unsigned long)(arg2); \
1479 _argvec[3] = (unsigned long)(arg3); \
1480 _argvec[4] = (unsigned long)(arg4); \
1481 _argvec[5] = (unsigned long)(arg5); \
1482 _argvec[6] = (unsigned long)(arg6); \
1483 _argvec[7] = (unsigned long)(arg7); \
1484 _argvec[8] = (unsigned long)(arg8); \
1485 _argvec[9] = (unsigned long)(arg9); \
1486 _argvec[10] = (unsigned long)(arg10); \
1488 VALGRIND_ALIGN_STACK \
1489 "subl $8, %%esp\n\t" \
1490 "pushl 40(%%eax)\n\t" \
1491 "pushl 36(%%eax)\n\t" \
1492 "pushl 32(%%eax)\n\t" \
1493 "pushl 28(%%eax)\n\t" \
1494 "pushl 24(%%eax)\n\t" \
1495 "pushl 20(%%eax)\n\t" \
1496 "pushl 16(%%eax)\n\t" \
1497 "pushl 12(%%eax)\n\t" \
1498 "pushl 8(%%eax)\n\t" \
1499 "pushl 4(%%eax)\n\t" \
1500 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1501 VALGRIND_CALL_NOREDIR_EAX \
1502 VALGRIND_RESTORE_STACK \
1503 : /*out*/ "=a" (_res) \
1504 : /*in*/ "a" (&_argvec[0]) \
1505 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1507 lval = (__typeof__(lval)) _res; \
1510 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
1511 arg6,arg7,arg8,arg9,arg10, \
1514 volatile OrigFn _orig = (orig); \
1515 volatile unsigned long _argvec[12]; \
1516 volatile unsigned long _res; \
1517 _argvec[0] = (unsigned long)_orig.nraddr; \
1518 _argvec[1] = (unsigned long)(arg1); \
1519 _argvec[2] = (unsigned long)(arg2); \
1520 _argvec[3] = (unsigned long)(arg3); \
1521 _argvec[4] = (unsigned long)(arg4); \
1522 _argvec[5] = (unsigned long)(arg5); \
1523 _argvec[6] = (unsigned long)(arg6); \
1524 _argvec[7] = (unsigned long)(arg7); \
1525 _argvec[8] = (unsigned long)(arg8); \
1526 _argvec[9] = (unsigned long)(arg9); \
1527 _argvec[10] = (unsigned long)(arg10); \
1528 _argvec[11] = (unsigned long)(arg11); \
1530 VALGRIND_ALIGN_STACK \
1531 "subl $4, %%esp\n\t" \
1532 "pushl 44(%%eax)\n\t" \
1533 "pushl 40(%%eax)\n\t" \
1534 "pushl 36(%%eax)\n\t" \
1535 "pushl 32(%%eax)\n\t" \
1536 "pushl 28(%%eax)\n\t" \
1537 "pushl 24(%%eax)\n\t" \
1538 "pushl 20(%%eax)\n\t" \
1539 "pushl 16(%%eax)\n\t" \
1540 "pushl 12(%%eax)\n\t" \
1541 "pushl 8(%%eax)\n\t" \
1542 "pushl 4(%%eax)\n\t" \
1543 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1544 VALGRIND_CALL_NOREDIR_EAX \
1545 VALGRIND_RESTORE_STACK \
1546 : /*out*/ "=a" (_res) \
1547 : /*in*/ "a" (&_argvec[0]) \
1548 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1550 lval = (__typeof__(lval)) _res; \
1553 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
1554 arg6,arg7,arg8,arg9,arg10, \
1557 volatile OrigFn _orig = (orig); \
1558 volatile unsigned long _argvec[13]; \
1559 volatile unsigned long _res; \
1560 _argvec[0] = (unsigned long)_orig.nraddr; \
1561 _argvec[1] = (unsigned long)(arg1); \
1562 _argvec[2] = (unsigned long)(arg2); \
1563 _argvec[3] = (unsigned long)(arg3); \
1564 _argvec[4] = (unsigned long)(arg4); \
1565 _argvec[5] = (unsigned long)(arg5); \
1566 _argvec[6] = (unsigned long)(arg6); \
1567 _argvec[7] = (unsigned long)(arg7); \
1568 _argvec[8] = (unsigned long)(arg8); \
1569 _argvec[9] = (unsigned long)(arg9); \
1570 _argvec[10] = (unsigned long)(arg10); \
1571 _argvec[11] = (unsigned long)(arg11); \
1572 _argvec[12] = (unsigned long)(arg12); \
1574 VALGRIND_ALIGN_STACK \
1575 "pushl 48(%%eax)\n\t" \
1576 "pushl 44(%%eax)\n\t" \
1577 "pushl 40(%%eax)\n\t" \
1578 "pushl 36(%%eax)\n\t" \
1579 "pushl 32(%%eax)\n\t" \
1580 "pushl 28(%%eax)\n\t" \
1581 "pushl 24(%%eax)\n\t" \
1582 "pushl 20(%%eax)\n\t" \
1583 "pushl 16(%%eax)\n\t" \
1584 "pushl 12(%%eax)\n\t" \
1585 "pushl 8(%%eax)\n\t" \
1586 "pushl 4(%%eax)\n\t" \
1587 "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1588 VALGRIND_CALL_NOREDIR_EAX \
1589 VALGRIND_RESTORE_STACK \
1590 : /*out*/ "=a" (_res) \
1591 : /*in*/ "a" (&_argvec[0]) \
1592 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \
1594 lval = (__typeof__(lval)) _res; \
1597 #endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */
1599 /* ---------------- amd64-{linux,darwin,solaris} --------------- */
1601 #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
1602 || defined(PLAT_amd64_solaris)
1604 /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1606 /* These regs are trashed by the hidden call. */
1607 #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
1608 "rdi", "r8", "r9", "r10", "r11"
1610 /* This is all pretty complex. It's so as to make stack unwinding
1611 work reliably. See bug 243270. The basic problem is the sub and
1612 add of 128 of %rsp in all of the following macros. If gcc believes
1613 the CFA is in %rsp, then unwinding may fail, because what's at the
1614 CFA is not what gcc "expected" when it constructs the CFIs for the
1615 places where the macros are instantiated.
1617 But we can't just add a CFI annotation to increase the CFA offset
1618 by 128, to match the sub of 128 from %rsp, because we don't know
1619 whether gcc has chosen %rsp as the CFA at that point, or whether it
1620 has chosen some other register (eg, %rbp). In the latter case,
1621 adding a CFI annotation to change the CFA offset is simply wrong.
1623 So the solution is to get hold of the CFA using
1624 __builtin_dwarf_cfa(), put it in a known register, and add a
1625 CFI annotation to say what the register is. We choose %rbp for
1626 this (perhaps perversely), because:
1628 (1) %rbp is already subject to unwinding. If a new register was
1629 chosen then the unwinder would have to unwind it in all stack
1630 traces, which is expensive, and
1632 (2) %rbp is already subject to precise exception updates in the
1633 JIT. If a new register was chosen, we'd have to have precise
1634 exceptions for it too, which reduces performance of the
1637 However .. one extra complication. We can't just whack the result
1638 of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1639 list of trashed registers at the end of the inline assembly
1640 fragments; gcc won't allow %rbp to appear in that list. Hence
1641 instead we need to stash %rbp in %r15 for the duration of the asm,
1642 and say that %r15 is trashed instead. gcc seems happy to go with
1645 Oh .. and this all needs to be conditionalised so that it is
1646 unchanged from before this commit, when compiled with older gccs
1647 that don't support __builtin_dwarf_cfa. Furthermore, since
1648 this header file is freestanding, it has to be independent of
1649 config.h, and so the following conditionalisation cannot depend on
1650 configure time checks.
1652 Although it's not clear from
1653 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
1654 this expression excludes Darwin.
1655 .cfi directives in Darwin assembly appear to be completely
1656 different and I haven't investigated how they work.
1658 For even more entertainment value, note we have to use the
1659 completely undocumented __builtin_dwarf_cfa(), which appears to
1660 really compute the CFA, whereas __builtin_frame_address(0) claims
1661 to but actually doesn't. See
1662 https://bugs.kde.org/show_bug.cgi?id=243270#c47
1664 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1665 # define __FRAME_POINTER \
1666 ,"r"(__builtin_dwarf_cfa())
1667 # define VALGRIND_CFI_PROLOGUE \
1668 "movq %%rbp, %%r15\n\t" \
1669 "movq %2, %%rbp\n\t" \
1670 ".cfi_remember_state\n\t" \
1671 ".cfi_def_cfa rbp, 0\n\t"
1672 # define VALGRIND_CFI_EPILOGUE \
1673 "movq %%r15, %%rbp\n\t" \
1674 ".cfi_restore_state\n\t"
1676 # define __FRAME_POINTER
1677 # define VALGRIND_CFI_PROLOGUE
1678 # define VALGRIND_CFI_EPILOGUE
1681 /* Macros to save and align the stack before making a function
1682 call and restore it afterwards as gcc may not keep the stack
1683 pointer aligned if it doesn't realise calls are being made
1684 to other functions. */
1686 #define VALGRIND_ALIGN_STACK \
1687 "movq %%rsp,%%r14\n\t" \
1688 "andq $0xfffffffffffffff0,%%rsp\n\t"
1689 #define VALGRIND_RESTORE_STACK \
1690 "movq %%r14,%%rsp\n\t"
1692 /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1695 /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_
1696 macros. In order not to trash the stack redzone, we need to drop
1697 %rsp by 128 before the hidden call, and restore afterwards. The
1698 nastyness is that it is only by luck that the stack still appears
1699 to be unwindable during the hidden call - since then the behaviour
1700 of any routine using this macro does not match what the CFI data
1703 Why is this important? Imagine that a wrapper has a stack
1704 allocated local, and passes to the hidden call, a pointer to it.
1705 Because gcc does not know about the hidden call, it may allocate
1706 that local in the redzone. Unfortunately the hidden call may then
1707 trash it before it comes to use it. So we must step clear of the
1708 redzone, for the duration of the hidden call, to make it safe.
1710 Probably the same problem afflicts the other redzone-style ABIs too
1711 (ppc64-linux); but for those, the stack is
1712 self describing (none of this CFI nonsense) so at least messing
1713 with the stack pointer doesn't give a danger of non-unwindable
1716 #define CALL_FN_W_v(lval, orig) \
1718 volatile OrigFn _orig = (orig); \
1719 volatile unsigned long _argvec[1]; \
1720 volatile unsigned long _res; \
1721 _argvec[0] = (unsigned long)_orig.nraddr; \
1723 VALGRIND_CFI_PROLOGUE \
1724 VALGRIND_ALIGN_STACK \
1725 "subq $128,%%rsp\n\t" \
1726 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1727 VALGRIND_CALL_NOREDIR_RAX \
1728 VALGRIND_RESTORE_STACK \
1729 VALGRIND_CFI_EPILOGUE \
1730 : /*out*/ "=a" (_res) \
1731 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1732 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1734 lval = (__typeof__(lval)) _res; \
1737 #define CALL_FN_W_W(lval, orig, arg1) \
1739 volatile OrigFn _orig = (orig); \
1740 volatile unsigned long _argvec[2]; \
1741 volatile unsigned long _res; \
1742 _argvec[0] = (unsigned long)_orig.nraddr; \
1743 _argvec[1] = (unsigned long)(arg1); \
1745 VALGRIND_CFI_PROLOGUE \
1746 VALGRIND_ALIGN_STACK \
1747 "subq $128,%%rsp\n\t" \
1748 "movq 8(%%rax), %%rdi\n\t" \
1749 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1750 VALGRIND_CALL_NOREDIR_RAX \
1751 VALGRIND_RESTORE_STACK \
1752 VALGRIND_CFI_EPILOGUE \
1753 : /*out*/ "=a" (_res) \
1754 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1755 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1757 lval = (__typeof__(lval)) _res; \
1760 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1762 volatile OrigFn _orig = (orig); \
1763 volatile unsigned long _argvec[3]; \
1764 volatile unsigned long _res; \
1765 _argvec[0] = (unsigned long)_orig.nraddr; \
1766 _argvec[1] = (unsigned long)(arg1); \
1767 _argvec[2] = (unsigned long)(arg2); \
1769 VALGRIND_CFI_PROLOGUE \
1770 VALGRIND_ALIGN_STACK \
1771 "subq $128,%%rsp\n\t" \
1772 "movq 16(%%rax), %%rsi\n\t" \
1773 "movq 8(%%rax), %%rdi\n\t" \
1774 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1775 VALGRIND_CALL_NOREDIR_RAX \
1776 VALGRIND_RESTORE_STACK \
1777 VALGRIND_CFI_EPILOGUE \
1778 : /*out*/ "=a" (_res) \
1779 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1780 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1782 lval = (__typeof__(lval)) _res; \
1785 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1787 volatile OrigFn _orig = (orig); \
1788 volatile unsigned long _argvec[4]; \
1789 volatile unsigned long _res; \
1790 _argvec[0] = (unsigned long)_orig.nraddr; \
1791 _argvec[1] = (unsigned long)(arg1); \
1792 _argvec[2] = (unsigned long)(arg2); \
1793 _argvec[3] = (unsigned long)(arg3); \
1795 VALGRIND_CFI_PROLOGUE \
1796 VALGRIND_ALIGN_STACK \
1797 "subq $128,%%rsp\n\t" \
1798 "movq 24(%%rax), %%rdx\n\t" \
1799 "movq 16(%%rax), %%rsi\n\t" \
1800 "movq 8(%%rax), %%rdi\n\t" \
1801 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1802 VALGRIND_CALL_NOREDIR_RAX \
1803 VALGRIND_RESTORE_STACK \
1804 VALGRIND_CFI_EPILOGUE \
1805 : /*out*/ "=a" (_res) \
1806 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1807 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1809 lval = (__typeof__(lval)) _res; \
1812 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1814 volatile OrigFn _orig = (orig); \
1815 volatile unsigned long _argvec[5]; \
1816 volatile unsigned long _res; \
1817 _argvec[0] = (unsigned long)_orig.nraddr; \
1818 _argvec[1] = (unsigned long)(arg1); \
1819 _argvec[2] = (unsigned long)(arg2); \
1820 _argvec[3] = (unsigned long)(arg3); \
1821 _argvec[4] = (unsigned long)(arg4); \
1823 VALGRIND_CFI_PROLOGUE \
1824 VALGRIND_ALIGN_STACK \
1825 "subq $128,%%rsp\n\t" \
1826 "movq 32(%%rax), %%rcx\n\t" \
1827 "movq 24(%%rax), %%rdx\n\t" \
1828 "movq 16(%%rax), %%rsi\n\t" \
1829 "movq 8(%%rax), %%rdi\n\t" \
1830 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1831 VALGRIND_CALL_NOREDIR_RAX \
1832 VALGRIND_RESTORE_STACK \
1833 VALGRIND_CFI_EPILOGUE \
1834 : /*out*/ "=a" (_res) \
1835 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1836 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1838 lval = (__typeof__(lval)) _res; \
1841 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1843 volatile OrigFn _orig = (orig); \
1844 volatile unsigned long _argvec[6]; \
1845 volatile unsigned long _res; \
1846 _argvec[0] = (unsigned long)_orig.nraddr; \
1847 _argvec[1] = (unsigned long)(arg1); \
1848 _argvec[2] = (unsigned long)(arg2); \
1849 _argvec[3] = (unsigned long)(arg3); \
1850 _argvec[4] = (unsigned long)(arg4); \
1851 _argvec[5] = (unsigned long)(arg5); \
1853 VALGRIND_CFI_PROLOGUE \
1854 VALGRIND_ALIGN_STACK \
1855 "subq $128,%%rsp\n\t" \
1856 "movq 40(%%rax), %%r8\n\t" \
1857 "movq 32(%%rax), %%rcx\n\t" \
1858 "movq 24(%%rax), %%rdx\n\t" \
1859 "movq 16(%%rax), %%rsi\n\t" \
1860 "movq 8(%%rax), %%rdi\n\t" \
1861 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1862 VALGRIND_CALL_NOREDIR_RAX \
1863 VALGRIND_RESTORE_STACK \
1864 VALGRIND_CFI_EPILOGUE \
1865 : /*out*/ "=a" (_res) \
1866 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1867 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1869 lval = (__typeof__(lval)) _res; \
1872 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1874 volatile OrigFn _orig = (orig); \
1875 volatile unsigned long _argvec[7]; \
1876 volatile unsigned long _res; \
1877 _argvec[0] = (unsigned long)_orig.nraddr; \
1878 _argvec[1] = (unsigned long)(arg1); \
1879 _argvec[2] = (unsigned long)(arg2); \
1880 _argvec[3] = (unsigned long)(arg3); \
1881 _argvec[4] = (unsigned long)(arg4); \
1882 _argvec[5] = (unsigned long)(arg5); \
1883 _argvec[6] = (unsigned long)(arg6); \
1885 VALGRIND_CFI_PROLOGUE \
1886 VALGRIND_ALIGN_STACK \
1887 "subq $128,%%rsp\n\t" \
1888 "movq 48(%%rax), %%r9\n\t" \
1889 "movq 40(%%rax), %%r8\n\t" \
1890 "movq 32(%%rax), %%rcx\n\t" \
1891 "movq 24(%%rax), %%rdx\n\t" \
1892 "movq 16(%%rax), %%rsi\n\t" \
1893 "movq 8(%%rax), %%rdi\n\t" \
1894 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1895 VALGRIND_CALL_NOREDIR_RAX \
1896 VALGRIND_RESTORE_STACK \
1897 VALGRIND_CFI_EPILOGUE \
1898 : /*out*/ "=a" (_res) \
1899 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1900 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1902 lval = (__typeof__(lval)) _res; \
1905 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1908 volatile OrigFn _orig = (orig); \
1909 volatile unsigned long _argvec[8]; \
1910 volatile unsigned long _res; \
1911 _argvec[0] = (unsigned long)_orig.nraddr; \
1912 _argvec[1] = (unsigned long)(arg1); \
1913 _argvec[2] = (unsigned long)(arg2); \
1914 _argvec[3] = (unsigned long)(arg3); \
1915 _argvec[4] = (unsigned long)(arg4); \
1916 _argvec[5] = (unsigned long)(arg5); \
1917 _argvec[6] = (unsigned long)(arg6); \
1918 _argvec[7] = (unsigned long)(arg7); \
1920 VALGRIND_CFI_PROLOGUE \
1921 VALGRIND_ALIGN_STACK \
1922 "subq $136,%%rsp\n\t" \
1923 "pushq 56(%%rax)\n\t" \
1924 "movq 48(%%rax), %%r9\n\t" \
1925 "movq 40(%%rax), %%r8\n\t" \
1926 "movq 32(%%rax), %%rcx\n\t" \
1927 "movq 24(%%rax), %%rdx\n\t" \
1928 "movq 16(%%rax), %%rsi\n\t" \
1929 "movq 8(%%rax), %%rdi\n\t" \
1930 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1931 VALGRIND_CALL_NOREDIR_RAX \
1932 VALGRIND_RESTORE_STACK \
1933 VALGRIND_CFI_EPILOGUE \
1934 : /*out*/ "=a" (_res) \
1935 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1936 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1938 lval = (__typeof__(lval)) _res; \
1941 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1944 volatile OrigFn _orig = (orig); \
1945 volatile unsigned long _argvec[9]; \
1946 volatile unsigned long _res; \
1947 _argvec[0] = (unsigned long)_orig.nraddr; \
1948 _argvec[1] = (unsigned long)(arg1); \
1949 _argvec[2] = (unsigned long)(arg2); \
1950 _argvec[3] = (unsigned long)(arg3); \
1951 _argvec[4] = (unsigned long)(arg4); \
1952 _argvec[5] = (unsigned long)(arg5); \
1953 _argvec[6] = (unsigned long)(arg6); \
1954 _argvec[7] = (unsigned long)(arg7); \
1955 _argvec[8] = (unsigned long)(arg8); \
1957 VALGRIND_CFI_PROLOGUE \
1958 VALGRIND_ALIGN_STACK \
1959 "subq $128,%%rsp\n\t" \
1960 "pushq 64(%%rax)\n\t" \
1961 "pushq 56(%%rax)\n\t" \
1962 "movq 48(%%rax), %%r9\n\t" \
1963 "movq 40(%%rax), %%r8\n\t" \
1964 "movq 32(%%rax), %%rcx\n\t" \
1965 "movq 24(%%rax), %%rdx\n\t" \
1966 "movq 16(%%rax), %%rsi\n\t" \
1967 "movq 8(%%rax), %%rdi\n\t" \
1968 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1969 VALGRIND_CALL_NOREDIR_RAX \
1970 VALGRIND_RESTORE_STACK \
1971 VALGRIND_CFI_EPILOGUE \
1972 : /*out*/ "=a" (_res) \
1973 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1974 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1976 lval = (__typeof__(lval)) _res; \
1979 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1982 volatile OrigFn _orig = (orig); \
1983 volatile unsigned long _argvec[10]; \
1984 volatile unsigned long _res; \
1985 _argvec[0] = (unsigned long)_orig.nraddr; \
1986 _argvec[1] = (unsigned long)(arg1); \
1987 _argvec[2] = (unsigned long)(arg2); \
1988 _argvec[3] = (unsigned long)(arg3); \
1989 _argvec[4] = (unsigned long)(arg4); \
1990 _argvec[5] = (unsigned long)(arg5); \
1991 _argvec[6] = (unsigned long)(arg6); \
1992 _argvec[7] = (unsigned long)(arg7); \
1993 _argvec[8] = (unsigned long)(arg8); \
1994 _argvec[9] = (unsigned long)(arg9); \
1996 VALGRIND_CFI_PROLOGUE \
1997 VALGRIND_ALIGN_STACK \
1998 "subq $136,%%rsp\n\t" \
1999 "pushq 72(%%rax)\n\t" \
2000 "pushq 64(%%rax)\n\t" \
2001 "pushq 56(%%rax)\n\t" \
2002 "movq 48(%%rax), %%r9\n\t" \
2003 "movq 40(%%rax), %%r8\n\t" \
2004 "movq 32(%%rax), %%rcx\n\t" \
2005 "movq 24(%%rax), %%rdx\n\t" \
2006 "movq 16(%%rax), %%rsi\n\t" \
2007 "movq 8(%%rax), %%rdi\n\t" \
2008 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
2009 VALGRIND_CALL_NOREDIR_RAX \
2010 VALGRIND_RESTORE_STACK \
2011 VALGRIND_CFI_EPILOGUE \
2012 : /*out*/ "=a" (_res) \
2013 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
2014 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
2016 lval = (__typeof__(lval)) _res; \
2019 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2020 arg7,arg8,arg9,arg10) \
2022 volatile OrigFn _orig = (orig); \
2023 volatile unsigned long _argvec[11]; \
2024 volatile unsigned long _res; \
2025 _argvec[0] = (unsigned long)_orig.nraddr; \
2026 _argvec[1] = (unsigned long)(arg1); \
2027 _argvec[2] = (unsigned long)(arg2); \
2028 _argvec[3] = (unsigned long)(arg3); \
2029 _argvec[4] = (unsigned long)(arg4); \
2030 _argvec[5] = (unsigned long)(arg5); \
2031 _argvec[6] = (unsigned long)(arg6); \
2032 _argvec[7] = (unsigned long)(arg7); \
2033 _argvec[8] = (unsigned long)(arg8); \
2034 _argvec[9] = (unsigned long)(arg9); \
2035 _argvec[10] = (unsigned long)(arg10); \
2037 VALGRIND_CFI_PROLOGUE \
2038 VALGRIND_ALIGN_STACK \
2039 "subq $128,%%rsp\n\t" \
2040 "pushq 80(%%rax)\n\t" \
2041 "pushq 72(%%rax)\n\t" \
2042 "pushq 64(%%rax)\n\t" \
2043 "pushq 56(%%rax)\n\t" \
2044 "movq 48(%%rax), %%r9\n\t" \
2045 "movq 40(%%rax), %%r8\n\t" \
2046 "movq 32(%%rax), %%rcx\n\t" \
2047 "movq 24(%%rax), %%rdx\n\t" \
2048 "movq 16(%%rax), %%rsi\n\t" \
2049 "movq 8(%%rax), %%rdi\n\t" \
2050 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
2051 VALGRIND_CALL_NOREDIR_RAX \
2052 VALGRIND_RESTORE_STACK \
2053 VALGRIND_CFI_EPILOGUE \
2054 : /*out*/ "=a" (_res) \
2055 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
2056 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
2058 lval = (__typeof__(lval)) _res; \
2061 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2062 arg7,arg8,arg9,arg10,arg11) \
2064 volatile OrigFn _orig = (orig); \
2065 volatile unsigned long _argvec[12]; \
2066 volatile unsigned long _res; \
2067 _argvec[0] = (unsigned long)_orig.nraddr; \
2068 _argvec[1] = (unsigned long)(arg1); \
2069 _argvec[2] = (unsigned long)(arg2); \
2070 _argvec[3] = (unsigned long)(arg3); \
2071 _argvec[4] = (unsigned long)(arg4); \
2072 _argvec[5] = (unsigned long)(arg5); \
2073 _argvec[6] = (unsigned long)(arg6); \
2074 _argvec[7] = (unsigned long)(arg7); \
2075 _argvec[8] = (unsigned long)(arg8); \
2076 _argvec[9] = (unsigned long)(arg9); \
2077 _argvec[10] = (unsigned long)(arg10); \
2078 _argvec[11] = (unsigned long)(arg11); \
2080 VALGRIND_CFI_PROLOGUE \
2081 VALGRIND_ALIGN_STACK \
2082 "subq $136,%%rsp\n\t" \
2083 "pushq 88(%%rax)\n\t" \
2084 "pushq 80(%%rax)\n\t" \
2085 "pushq 72(%%rax)\n\t" \
2086 "pushq 64(%%rax)\n\t" \
2087 "pushq 56(%%rax)\n\t" \
2088 "movq 48(%%rax), %%r9\n\t" \
2089 "movq 40(%%rax), %%r8\n\t" \
2090 "movq 32(%%rax), %%rcx\n\t" \
2091 "movq 24(%%rax), %%rdx\n\t" \
2092 "movq 16(%%rax), %%rsi\n\t" \
2093 "movq 8(%%rax), %%rdi\n\t" \
2094 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
2095 VALGRIND_CALL_NOREDIR_RAX \
2096 VALGRIND_RESTORE_STACK \
2097 VALGRIND_CFI_EPILOGUE \
2098 : /*out*/ "=a" (_res) \
2099 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
2100 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
2102 lval = (__typeof__(lval)) _res; \
2105 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2106 arg7,arg8,arg9,arg10,arg11,arg12) \
2108 volatile OrigFn _orig = (orig); \
2109 volatile unsigned long _argvec[13]; \
2110 volatile unsigned long _res; \
2111 _argvec[0] = (unsigned long)_orig.nraddr; \
2112 _argvec[1] = (unsigned long)(arg1); \
2113 _argvec[2] = (unsigned long)(arg2); \
2114 _argvec[3] = (unsigned long)(arg3); \
2115 _argvec[4] = (unsigned long)(arg4); \
2116 _argvec[5] = (unsigned long)(arg5); \
2117 _argvec[6] = (unsigned long)(arg6); \
2118 _argvec[7] = (unsigned long)(arg7); \
2119 _argvec[8] = (unsigned long)(arg8); \
2120 _argvec[9] = (unsigned long)(arg9); \
2121 _argvec[10] = (unsigned long)(arg10); \
2122 _argvec[11] = (unsigned long)(arg11); \
2123 _argvec[12] = (unsigned long)(arg12); \
2125 VALGRIND_CFI_PROLOGUE \
2126 VALGRIND_ALIGN_STACK \
2127 "subq $128,%%rsp\n\t" \
2128 "pushq 96(%%rax)\n\t" \
2129 "pushq 88(%%rax)\n\t" \
2130 "pushq 80(%%rax)\n\t" \
2131 "pushq 72(%%rax)\n\t" \
2132 "pushq 64(%%rax)\n\t" \
2133 "pushq 56(%%rax)\n\t" \
2134 "movq 48(%%rax), %%r9\n\t" \
2135 "movq 40(%%rax), %%r8\n\t" \
2136 "movq 32(%%rax), %%rcx\n\t" \
2137 "movq 24(%%rax), %%rdx\n\t" \
2138 "movq 16(%%rax), %%rsi\n\t" \
2139 "movq 8(%%rax), %%rdi\n\t" \
2140 "movq (%%rax), %%rax\n\t" /* target->%rax */ \
2141 VALGRIND_CALL_NOREDIR_RAX \
2142 VALGRIND_RESTORE_STACK \
2143 VALGRIND_CFI_EPILOGUE \
2144 : /*out*/ "=a" (_res) \
2145 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
2146 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
2148 lval = (__typeof__(lval)) _res; \
2151 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */
2153 /* ------------------------ ppc32-linux ------------------------ */
2155 #if defined(PLAT_ppc32_linux)
2157 /* This is useful for finding out about the on-stack stuff:
2159 extern int f9 ( int,int,int,int,int,int,int,int,int );
2160 extern int f10 ( int,int,int,int,int,int,int,int,int,int );
2161 extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
2162 extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
2165 return f9(11,22,33,44,55,66,77,88,99);
2168 return f10(11,22,33,44,55,66,77,88,99,110);
2171 return f11(11,22,33,44,55,66,77,88,99,110,121);
2174 return f12(11,22,33,44,55,66,77,88,99,110,121,132);
2178 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2180 /* These regs are trashed by the hidden call. */
2181 #define __CALLER_SAVED_REGS \
2182 "lr", "ctr", "xer", \
2183 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
2184 "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
2187 /* Macros to save and align the stack before making a function
2188 call and restore it afterwards as gcc may not keep the stack
2189 pointer aligned if it doesn't realise calls are being made
2190 to other functions. */
2192 #define VALGRIND_ALIGN_STACK \
2194 "rlwinm 1,1,0,0,27\n\t"
2195 #define VALGRIND_RESTORE_STACK \
2198 /* These CALL_FN_ macros assume that on ppc32-linux,
2199 sizeof(unsigned long) == 4. */
2201 #define CALL_FN_W_v(lval, orig) \
2203 volatile OrigFn _orig = (orig); \
2204 volatile unsigned long _argvec[1]; \
2205 volatile unsigned long _res; \
2206 _argvec[0] = (unsigned long)_orig.nraddr; \
2208 VALGRIND_ALIGN_STACK \
2210 "lwz 11,0(11)\n\t" /* target->r11 */ \
2211 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2212 VALGRIND_RESTORE_STACK \
2214 : /*out*/ "=r" (_res) \
2215 : /*in*/ "r" (&_argvec[0]) \
2216 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2218 lval = (__typeof__(lval)) _res; \
2221 #define CALL_FN_W_W(lval, orig, arg1) \
2223 volatile OrigFn _orig = (orig); \
2224 volatile unsigned long _argvec[2]; \
2225 volatile unsigned long _res; \
2226 _argvec[0] = (unsigned long)_orig.nraddr; \
2227 _argvec[1] = (unsigned long)arg1; \
2229 VALGRIND_ALIGN_STACK \
2231 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2232 "lwz 11,0(11)\n\t" /* target->r11 */ \
2233 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2234 VALGRIND_RESTORE_STACK \
2236 : /*out*/ "=r" (_res) \
2237 : /*in*/ "r" (&_argvec[0]) \
2238 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2240 lval = (__typeof__(lval)) _res; \
2243 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2245 volatile OrigFn _orig = (orig); \
2246 volatile unsigned long _argvec[3]; \
2247 volatile unsigned long _res; \
2248 _argvec[0] = (unsigned long)_orig.nraddr; \
2249 _argvec[1] = (unsigned long)arg1; \
2250 _argvec[2] = (unsigned long)arg2; \
2252 VALGRIND_ALIGN_STACK \
2254 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2256 "lwz 11,0(11)\n\t" /* target->r11 */ \
2257 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2258 VALGRIND_RESTORE_STACK \
2260 : /*out*/ "=r" (_res) \
2261 : /*in*/ "r" (&_argvec[0]) \
2262 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2264 lval = (__typeof__(lval)) _res; \
2267 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2269 volatile OrigFn _orig = (orig); \
2270 volatile unsigned long _argvec[4]; \
2271 volatile unsigned long _res; \
2272 _argvec[0] = (unsigned long)_orig.nraddr; \
2273 _argvec[1] = (unsigned long)arg1; \
2274 _argvec[2] = (unsigned long)arg2; \
2275 _argvec[3] = (unsigned long)arg3; \
2277 VALGRIND_ALIGN_STACK \
2279 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2281 "lwz 5,12(11)\n\t" \
2282 "lwz 11,0(11)\n\t" /* target->r11 */ \
2283 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2284 VALGRIND_RESTORE_STACK \
2286 : /*out*/ "=r" (_res) \
2287 : /*in*/ "r" (&_argvec[0]) \
2288 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2290 lval = (__typeof__(lval)) _res; \
2293 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2295 volatile OrigFn _orig = (orig); \
2296 volatile unsigned long _argvec[5]; \
2297 volatile unsigned long _res; \
2298 _argvec[0] = (unsigned long)_orig.nraddr; \
2299 _argvec[1] = (unsigned long)arg1; \
2300 _argvec[2] = (unsigned long)arg2; \
2301 _argvec[3] = (unsigned long)arg3; \
2302 _argvec[4] = (unsigned long)arg4; \
2304 VALGRIND_ALIGN_STACK \
2306 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2308 "lwz 5,12(11)\n\t" \
2309 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2310 "lwz 11,0(11)\n\t" /* target->r11 */ \
2311 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2312 VALGRIND_RESTORE_STACK \
2314 : /*out*/ "=r" (_res) \
2315 : /*in*/ "r" (&_argvec[0]) \
2316 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2318 lval = (__typeof__(lval)) _res; \
2321 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2323 volatile OrigFn _orig = (orig); \
2324 volatile unsigned long _argvec[6]; \
2325 volatile unsigned long _res; \
2326 _argvec[0] = (unsigned long)_orig.nraddr; \
2327 _argvec[1] = (unsigned long)arg1; \
2328 _argvec[2] = (unsigned long)arg2; \
2329 _argvec[3] = (unsigned long)arg3; \
2330 _argvec[4] = (unsigned long)arg4; \
2331 _argvec[5] = (unsigned long)arg5; \
2333 VALGRIND_ALIGN_STACK \
2335 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2337 "lwz 5,12(11)\n\t" \
2338 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2339 "lwz 7,20(11)\n\t" \
2340 "lwz 11,0(11)\n\t" /* target->r11 */ \
2341 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2342 VALGRIND_RESTORE_STACK \
2344 : /*out*/ "=r" (_res) \
2345 : /*in*/ "r" (&_argvec[0]) \
2346 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2348 lval = (__typeof__(lval)) _res; \
2351 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2353 volatile OrigFn _orig = (orig); \
2354 volatile unsigned long _argvec[7]; \
2355 volatile unsigned long _res; \
2356 _argvec[0] = (unsigned long)_orig.nraddr; \
2357 _argvec[1] = (unsigned long)arg1; \
2358 _argvec[2] = (unsigned long)arg2; \
2359 _argvec[3] = (unsigned long)arg3; \
2360 _argvec[4] = (unsigned long)arg4; \
2361 _argvec[5] = (unsigned long)arg5; \
2362 _argvec[6] = (unsigned long)arg6; \
2364 VALGRIND_ALIGN_STACK \
2366 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2368 "lwz 5,12(11)\n\t" \
2369 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2370 "lwz 7,20(11)\n\t" \
2371 "lwz 8,24(11)\n\t" \
2372 "lwz 11,0(11)\n\t" /* target->r11 */ \
2373 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2374 VALGRIND_RESTORE_STACK \
2376 : /*out*/ "=r" (_res) \
2377 : /*in*/ "r" (&_argvec[0]) \
2378 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2380 lval = (__typeof__(lval)) _res; \
2383 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2386 volatile OrigFn _orig = (orig); \
2387 volatile unsigned long _argvec[8]; \
2388 volatile unsigned long _res; \
2389 _argvec[0] = (unsigned long)_orig.nraddr; \
2390 _argvec[1] = (unsigned long)arg1; \
2391 _argvec[2] = (unsigned long)arg2; \
2392 _argvec[3] = (unsigned long)arg3; \
2393 _argvec[4] = (unsigned long)arg4; \
2394 _argvec[5] = (unsigned long)arg5; \
2395 _argvec[6] = (unsigned long)arg6; \
2396 _argvec[7] = (unsigned long)arg7; \
2398 VALGRIND_ALIGN_STACK \
2400 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2402 "lwz 5,12(11)\n\t" \
2403 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2404 "lwz 7,20(11)\n\t" \
2405 "lwz 8,24(11)\n\t" \
2406 "lwz 9,28(11)\n\t" \
2407 "lwz 11,0(11)\n\t" /* target->r11 */ \
2408 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2409 VALGRIND_RESTORE_STACK \
2411 : /*out*/ "=r" (_res) \
2412 : /*in*/ "r" (&_argvec[0]) \
2413 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2415 lval = (__typeof__(lval)) _res; \
2418 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2421 volatile OrigFn _orig = (orig); \
2422 volatile unsigned long _argvec[9]; \
2423 volatile unsigned long _res; \
2424 _argvec[0] = (unsigned long)_orig.nraddr; \
2425 _argvec[1] = (unsigned long)arg1; \
2426 _argvec[2] = (unsigned long)arg2; \
2427 _argvec[3] = (unsigned long)arg3; \
2428 _argvec[4] = (unsigned long)arg4; \
2429 _argvec[5] = (unsigned long)arg5; \
2430 _argvec[6] = (unsigned long)arg6; \
2431 _argvec[7] = (unsigned long)arg7; \
2432 _argvec[8] = (unsigned long)arg8; \
2434 VALGRIND_ALIGN_STACK \
2436 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2438 "lwz 5,12(11)\n\t" \
2439 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2440 "lwz 7,20(11)\n\t" \
2441 "lwz 8,24(11)\n\t" \
2442 "lwz 9,28(11)\n\t" \
2443 "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2444 "lwz 11,0(11)\n\t" /* target->r11 */ \
2445 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2446 VALGRIND_RESTORE_STACK \
2448 : /*out*/ "=r" (_res) \
2449 : /*in*/ "r" (&_argvec[0]) \
2450 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2452 lval = (__typeof__(lval)) _res; \
2455 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2458 volatile OrigFn _orig = (orig); \
2459 volatile unsigned long _argvec[10]; \
2460 volatile unsigned long _res; \
2461 _argvec[0] = (unsigned long)_orig.nraddr; \
2462 _argvec[1] = (unsigned long)arg1; \
2463 _argvec[2] = (unsigned long)arg2; \
2464 _argvec[3] = (unsigned long)arg3; \
2465 _argvec[4] = (unsigned long)arg4; \
2466 _argvec[5] = (unsigned long)arg5; \
2467 _argvec[6] = (unsigned long)arg6; \
2468 _argvec[7] = (unsigned long)arg7; \
2469 _argvec[8] = (unsigned long)arg8; \
2470 _argvec[9] = (unsigned long)arg9; \
2472 VALGRIND_ALIGN_STACK \
2474 "addi 1,1,-16\n\t" \
2476 "lwz 3,36(11)\n\t" \
2479 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2481 "lwz 5,12(11)\n\t" \
2482 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2483 "lwz 7,20(11)\n\t" \
2484 "lwz 8,24(11)\n\t" \
2485 "lwz 9,28(11)\n\t" \
2486 "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2487 "lwz 11,0(11)\n\t" /* target->r11 */ \
2488 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2489 VALGRIND_RESTORE_STACK \
2491 : /*out*/ "=r" (_res) \
2492 : /*in*/ "r" (&_argvec[0]) \
2493 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2495 lval = (__typeof__(lval)) _res; \
2498 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2499 arg7,arg8,arg9,arg10) \
2501 volatile OrigFn _orig = (orig); \
2502 volatile unsigned long _argvec[11]; \
2503 volatile unsigned long _res; \
2504 _argvec[0] = (unsigned long)_orig.nraddr; \
2505 _argvec[1] = (unsigned long)arg1; \
2506 _argvec[2] = (unsigned long)arg2; \
2507 _argvec[3] = (unsigned long)arg3; \
2508 _argvec[4] = (unsigned long)arg4; \
2509 _argvec[5] = (unsigned long)arg5; \
2510 _argvec[6] = (unsigned long)arg6; \
2511 _argvec[7] = (unsigned long)arg7; \
2512 _argvec[8] = (unsigned long)arg8; \
2513 _argvec[9] = (unsigned long)arg9; \
2514 _argvec[10] = (unsigned long)arg10; \
2516 VALGRIND_ALIGN_STACK \
2518 "addi 1,1,-16\n\t" \
2520 "lwz 3,40(11)\n\t" \
2523 "lwz 3,36(11)\n\t" \
2526 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2528 "lwz 5,12(11)\n\t" \
2529 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2530 "lwz 7,20(11)\n\t" \
2531 "lwz 8,24(11)\n\t" \
2532 "lwz 9,28(11)\n\t" \
2533 "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2534 "lwz 11,0(11)\n\t" /* target->r11 */ \
2535 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2536 VALGRIND_RESTORE_STACK \
2538 : /*out*/ "=r" (_res) \
2539 : /*in*/ "r" (&_argvec[0]) \
2540 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2542 lval = (__typeof__(lval)) _res; \
2545 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2546 arg7,arg8,arg9,arg10,arg11) \
2548 volatile OrigFn _orig = (orig); \
2549 volatile unsigned long _argvec[12]; \
2550 volatile unsigned long _res; \
2551 _argvec[0] = (unsigned long)_orig.nraddr; \
2552 _argvec[1] = (unsigned long)arg1; \
2553 _argvec[2] = (unsigned long)arg2; \
2554 _argvec[3] = (unsigned long)arg3; \
2555 _argvec[4] = (unsigned long)arg4; \
2556 _argvec[5] = (unsigned long)arg5; \
2557 _argvec[6] = (unsigned long)arg6; \
2558 _argvec[7] = (unsigned long)arg7; \
2559 _argvec[8] = (unsigned long)arg8; \
2560 _argvec[9] = (unsigned long)arg9; \
2561 _argvec[10] = (unsigned long)arg10; \
2562 _argvec[11] = (unsigned long)arg11; \
2564 VALGRIND_ALIGN_STACK \
2566 "addi 1,1,-32\n\t" \
2568 "lwz 3,44(11)\n\t" \
2571 "lwz 3,40(11)\n\t" \
2574 "lwz 3,36(11)\n\t" \
2577 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2579 "lwz 5,12(11)\n\t" \
2580 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2581 "lwz 7,20(11)\n\t" \
2582 "lwz 8,24(11)\n\t" \
2583 "lwz 9,28(11)\n\t" \
2584 "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2585 "lwz 11,0(11)\n\t" /* target->r11 */ \
2586 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2587 VALGRIND_RESTORE_STACK \
2589 : /*out*/ "=r" (_res) \
2590 : /*in*/ "r" (&_argvec[0]) \
2591 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2593 lval = (__typeof__(lval)) _res; \
2596 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2597 arg7,arg8,arg9,arg10,arg11,arg12) \
2599 volatile OrigFn _orig = (orig); \
2600 volatile unsigned long _argvec[13]; \
2601 volatile unsigned long _res; \
2602 _argvec[0] = (unsigned long)_orig.nraddr; \
2603 _argvec[1] = (unsigned long)arg1; \
2604 _argvec[2] = (unsigned long)arg2; \
2605 _argvec[3] = (unsigned long)arg3; \
2606 _argvec[4] = (unsigned long)arg4; \
2607 _argvec[5] = (unsigned long)arg5; \
2608 _argvec[6] = (unsigned long)arg6; \
2609 _argvec[7] = (unsigned long)arg7; \
2610 _argvec[8] = (unsigned long)arg8; \
2611 _argvec[9] = (unsigned long)arg9; \
2612 _argvec[10] = (unsigned long)arg10; \
2613 _argvec[11] = (unsigned long)arg11; \
2614 _argvec[12] = (unsigned long)arg12; \
2616 VALGRIND_ALIGN_STACK \
2618 "addi 1,1,-32\n\t" \
2620 "lwz 3,48(11)\n\t" \
2623 "lwz 3,44(11)\n\t" \
2626 "lwz 3,40(11)\n\t" \
2629 "lwz 3,36(11)\n\t" \
2632 "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2634 "lwz 5,12(11)\n\t" \
2635 "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2636 "lwz 7,20(11)\n\t" \
2637 "lwz 8,24(11)\n\t" \
2638 "lwz 9,28(11)\n\t" \
2639 "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2640 "lwz 11,0(11)\n\t" /* target->r11 */ \
2641 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2642 VALGRIND_RESTORE_STACK \
2644 : /*out*/ "=r" (_res) \
2645 : /*in*/ "r" (&_argvec[0]) \
2646 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2648 lval = (__typeof__(lval)) _res; \
2651 #endif /* PLAT_ppc32_linux */
2653 /* ------------------------ ppc64-linux ------------------------ */
2655 #if defined(PLAT_ppc64be_linux)
2657 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2659 /* These regs are trashed by the hidden call. */
2660 #define __CALLER_SAVED_REGS \
2661 "lr", "ctr", "xer", \
2662 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
2663 "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
2666 /* Macros to save and align the stack before making a function
2667 call and restore it afterwards as gcc may not keep the stack
2668 pointer aligned if it doesn't realise calls are being made
2669 to other functions. */
2671 #define VALGRIND_ALIGN_STACK \
2673 "rldicr 1,1,0,59\n\t"
2674 #define VALGRIND_RESTORE_STACK \
2677 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
2680 #define CALL_FN_W_v(lval, orig) \
2682 volatile OrigFn _orig = (orig); \
2683 volatile unsigned long _argvec[3+0]; \
2684 volatile unsigned long _res; \
2685 /* _argvec[0] holds current r2 across the call */ \
2686 _argvec[1] = (unsigned long)_orig.r2; \
2687 _argvec[2] = (unsigned long)_orig.nraddr; \
2689 VALGRIND_ALIGN_STACK \
2691 "std 2,-16(11)\n\t" /* save tocptr */ \
2692 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2693 "ld 11, 0(11)\n\t" /* target->r11 */ \
2694 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2697 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2698 VALGRIND_RESTORE_STACK \
2699 : /*out*/ "=r" (_res) \
2700 : /*in*/ "r" (&_argvec[2]) \
2701 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2703 lval = (__typeof__(lval)) _res; \
2706 #define CALL_FN_W_W(lval, orig, arg1) \
2708 volatile OrigFn _orig = (orig); \
2709 volatile unsigned long _argvec[3+1]; \
2710 volatile unsigned long _res; \
2711 /* _argvec[0] holds current r2 across the call */ \
2712 _argvec[1] = (unsigned long)_orig.r2; \
2713 _argvec[2] = (unsigned long)_orig.nraddr; \
2714 _argvec[2+1] = (unsigned long)arg1; \
2716 VALGRIND_ALIGN_STACK \
2718 "std 2,-16(11)\n\t" /* save tocptr */ \
2719 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2720 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2721 "ld 11, 0(11)\n\t" /* target->r11 */ \
2722 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2725 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2726 VALGRIND_RESTORE_STACK \
2727 : /*out*/ "=r" (_res) \
2728 : /*in*/ "r" (&_argvec[2]) \
2729 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2731 lval = (__typeof__(lval)) _res; \
2734 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2736 volatile OrigFn _orig = (orig); \
2737 volatile unsigned long _argvec[3+2]; \
2738 volatile unsigned long _res; \
2739 /* _argvec[0] holds current r2 across the call */ \
2740 _argvec[1] = (unsigned long)_orig.r2; \
2741 _argvec[2] = (unsigned long)_orig.nraddr; \
2742 _argvec[2+1] = (unsigned long)arg1; \
2743 _argvec[2+2] = (unsigned long)arg2; \
2745 VALGRIND_ALIGN_STACK \
2747 "std 2,-16(11)\n\t" /* save tocptr */ \
2748 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2749 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2750 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2751 "ld 11, 0(11)\n\t" /* target->r11 */ \
2752 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2755 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2756 VALGRIND_RESTORE_STACK \
2757 : /*out*/ "=r" (_res) \
2758 : /*in*/ "r" (&_argvec[2]) \
2759 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2761 lval = (__typeof__(lval)) _res; \
2764 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2766 volatile OrigFn _orig = (orig); \
2767 volatile unsigned long _argvec[3+3]; \
2768 volatile unsigned long _res; \
2769 /* _argvec[0] holds current r2 across the call */ \
2770 _argvec[1] = (unsigned long)_orig.r2; \
2771 _argvec[2] = (unsigned long)_orig.nraddr; \
2772 _argvec[2+1] = (unsigned long)arg1; \
2773 _argvec[2+2] = (unsigned long)arg2; \
2774 _argvec[2+3] = (unsigned long)arg3; \
2776 VALGRIND_ALIGN_STACK \
2778 "std 2,-16(11)\n\t" /* save tocptr */ \
2779 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2780 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2781 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2782 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2783 "ld 11, 0(11)\n\t" /* target->r11 */ \
2784 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2787 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2788 VALGRIND_RESTORE_STACK \
2789 : /*out*/ "=r" (_res) \
2790 : /*in*/ "r" (&_argvec[2]) \
2791 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2793 lval = (__typeof__(lval)) _res; \
2796 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2798 volatile OrigFn _orig = (orig); \
2799 volatile unsigned long _argvec[3+4]; \
2800 volatile unsigned long _res; \
2801 /* _argvec[0] holds current r2 across the call */ \
2802 _argvec[1] = (unsigned long)_orig.r2; \
2803 _argvec[2] = (unsigned long)_orig.nraddr; \
2804 _argvec[2+1] = (unsigned long)arg1; \
2805 _argvec[2+2] = (unsigned long)arg2; \
2806 _argvec[2+3] = (unsigned long)arg3; \
2807 _argvec[2+4] = (unsigned long)arg4; \
2809 VALGRIND_ALIGN_STACK \
2811 "std 2,-16(11)\n\t" /* save tocptr */ \
2812 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2813 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2814 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2815 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2816 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2817 "ld 11, 0(11)\n\t" /* target->r11 */ \
2818 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2821 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2822 VALGRIND_RESTORE_STACK \
2823 : /*out*/ "=r" (_res) \
2824 : /*in*/ "r" (&_argvec[2]) \
2825 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2827 lval = (__typeof__(lval)) _res; \
2830 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2832 volatile OrigFn _orig = (orig); \
2833 volatile unsigned long _argvec[3+5]; \
2834 volatile unsigned long _res; \
2835 /* _argvec[0] holds current r2 across the call */ \
2836 _argvec[1] = (unsigned long)_orig.r2; \
2837 _argvec[2] = (unsigned long)_orig.nraddr; \
2838 _argvec[2+1] = (unsigned long)arg1; \
2839 _argvec[2+2] = (unsigned long)arg2; \
2840 _argvec[2+3] = (unsigned long)arg3; \
2841 _argvec[2+4] = (unsigned long)arg4; \
2842 _argvec[2+5] = (unsigned long)arg5; \
2844 VALGRIND_ALIGN_STACK \
2846 "std 2,-16(11)\n\t" /* save tocptr */ \
2847 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2848 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2849 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2850 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2851 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2852 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2853 "ld 11, 0(11)\n\t" /* target->r11 */ \
2854 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2857 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2858 VALGRIND_RESTORE_STACK \
2859 : /*out*/ "=r" (_res) \
2860 : /*in*/ "r" (&_argvec[2]) \
2861 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2863 lval = (__typeof__(lval)) _res; \
2866 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2868 volatile OrigFn _orig = (orig); \
2869 volatile unsigned long _argvec[3+6]; \
2870 volatile unsigned long _res; \
2871 /* _argvec[0] holds current r2 across the call */ \
2872 _argvec[1] = (unsigned long)_orig.r2; \
2873 _argvec[2] = (unsigned long)_orig.nraddr; \
2874 _argvec[2+1] = (unsigned long)arg1; \
2875 _argvec[2+2] = (unsigned long)arg2; \
2876 _argvec[2+3] = (unsigned long)arg3; \
2877 _argvec[2+4] = (unsigned long)arg4; \
2878 _argvec[2+5] = (unsigned long)arg5; \
2879 _argvec[2+6] = (unsigned long)arg6; \
2881 VALGRIND_ALIGN_STACK \
2883 "std 2,-16(11)\n\t" /* save tocptr */ \
2884 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2885 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2886 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2887 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2888 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2889 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2890 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2891 "ld 11, 0(11)\n\t" /* target->r11 */ \
2892 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2895 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2896 VALGRIND_RESTORE_STACK \
2897 : /*out*/ "=r" (_res) \
2898 : /*in*/ "r" (&_argvec[2]) \
2899 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2901 lval = (__typeof__(lval)) _res; \
2904 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2907 volatile OrigFn _orig = (orig); \
2908 volatile unsigned long _argvec[3+7]; \
2909 volatile unsigned long _res; \
2910 /* _argvec[0] holds current r2 across the call */ \
2911 _argvec[1] = (unsigned long)_orig.r2; \
2912 _argvec[2] = (unsigned long)_orig.nraddr; \
2913 _argvec[2+1] = (unsigned long)arg1; \
2914 _argvec[2+2] = (unsigned long)arg2; \
2915 _argvec[2+3] = (unsigned long)arg3; \
2916 _argvec[2+4] = (unsigned long)arg4; \
2917 _argvec[2+5] = (unsigned long)arg5; \
2918 _argvec[2+6] = (unsigned long)arg6; \
2919 _argvec[2+7] = (unsigned long)arg7; \
2921 VALGRIND_ALIGN_STACK \
2923 "std 2,-16(11)\n\t" /* save tocptr */ \
2924 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2925 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2926 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2927 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2928 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2929 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2930 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2931 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2932 "ld 11, 0(11)\n\t" /* target->r11 */ \
2933 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2936 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2937 VALGRIND_RESTORE_STACK \
2938 : /*out*/ "=r" (_res) \
2939 : /*in*/ "r" (&_argvec[2]) \
2940 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2942 lval = (__typeof__(lval)) _res; \
2945 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2948 volatile OrigFn _orig = (orig); \
2949 volatile unsigned long _argvec[3+8]; \
2950 volatile unsigned long _res; \
2951 /* _argvec[0] holds current r2 across the call */ \
2952 _argvec[1] = (unsigned long)_orig.r2; \
2953 _argvec[2] = (unsigned long)_orig.nraddr; \
2954 _argvec[2+1] = (unsigned long)arg1; \
2955 _argvec[2+2] = (unsigned long)arg2; \
2956 _argvec[2+3] = (unsigned long)arg3; \
2957 _argvec[2+4] = (unsigned long)arg4; \
2958 _argvec[2+5] = (unsigned long)arg5; \
2959 _argvec[2+6] = (unsigned long)arg6; \
2960 _argvec[2+7] = (unsigned long)arg7; \
2961 _argvec[2+8] = (unsigned long)arg8; \
2963 VALGRIND_ALIGN_STACK \
2965 "std 2,-16(11)\n\t" /* save tocptr */ \
2966 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2967 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2968 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2969 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2970 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2971 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2972 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2973 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2974 "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2975 "ld 11, 0(11)\n\t" /* target->r11 */ \
2976 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2979 "ld 2,-16(11)\n\t" /* restore tocptr */ \
2980 VALGRIND_RESTORE_STACK \
2981 : /*out*/ "=r" (_res) \
2982 : /*in*/ "r" (&_argvec[2]) \
2983 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
2985 lval = (__typeof__(lval)) _res; \
2988 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2991 volatile OrigFn _orig = (orig); \
2992 volatile unsigned long _argvec[3+9]; \
2993 volatile unsigned long _res; \
2994 /* _argvec[0] holds current r2 across the call */ \
2995 _argvec[1] = (unsigned long)_orig.r2; \
2996 _argvec[2] = (unsigned long)_orig.nraddr; \
2997 _argvec[2+1] = (unsigned long)arg1; \
2998 _argvec[2+2] = (unsigned long)arg2; \
2999 _argvec[2+3] = (unsigned long)arg3; \
3000 _argvec[2+4] = (unsigned long)arg4; \
3001 _argvec[2+5] = (unsigned long)arg5; \
3002 _argvec[2+6] = (unsigned long)arg6; \
3003 _argvec[2+7] = (unsigned long)arg7; \
3004 _argvec[2+8] = (unsigned long)arg8; \
3005 _argvec[2+9] = (unsigned long)arg9; \
3007 VALGRIND_ALIGN_STACK \
3009 "std 2,-16(11)\n\t" /* save tocptr */ \
3010 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3011 "addi 1,1,-128\n\t" /* expand stack frame */ \
3014 "std 3,112(1)\n\t" \
3016 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3017 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3018 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3019 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3020 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3021 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3022 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3023 "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3024 "ld 11, 0(11)\n\t" /* target->r11 */ \
3025 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3028 "ld 2,-16(11)\n\t" /* restore tocptr */ \
3029 VALGRIND_RESTORE_STACK \
3030 : /*out*/ "=r" (_res) \
3031 : /*in*/ "r" (&_argvec[2]) \
3032 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3034 lval = (__typeof__(lval)) _res; \
3037 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3038 arg7,arg8,arg9,arg10) \
3040 volatile OrigFn _orig = (orig); \
3041 volatile unsigned long _argvec[3+10]; \
3042 volatile unsigned long _res; \
3043 /* _argvec[0] holds current r2 across the call */ \
3044 _argvec[1] = (unsigned long)_orig.r2; \
3045 _argvec[2] = (unsigned long)_orig.nraddr; \
3046 _argvec[2+1] = (unsigned long)arg1; \
3047 _argvec[2+2] = (unsigned long)arg2; \
3048 _argvec[2+3] = (unsigned long)arg3; \
3049 _argvec[2+4] = (unsigned long)arg4; \
3050 _argvec[2+5] = (unsigned long)arg5; \
3051 _argvec[2+6] = (unsigned long)arg6; \
3052 _argvec[2+7] = (unsigned long)arg7; \
3053 _argvec[2+8] = (unsigned long)arg8; \
3054 _argvec[2+9] = (unsigned long)arg9; \
3055 _argvec[2+10] = (unsigned long)arg10; \
3057 VALGRIND_ALIGN_STACK \
3059 "std 2,-16(11)\n\t" /* save tocptr */ \
3060 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3061 "addi 1,1,-128\n\t" /* expand stack frame */ \
3064 "std 3,120(1)\n\t" \
3067 "std 3,112(1)\n\t" \
3069 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3070 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3071 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3072 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3073 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3074 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3075 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3076 "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3077 "ld 11, 0(11)\n\t" /* target->r11 */ \
3078 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3081 "ld 2,-16(11)\n\t" /* restore tocptr */ \
3082 VALGRIND_RESTORE_STACK \
3083 : /*out*/ "=r" (_res) \
3084 : /*in*/ "r" (&_argvec[2]) \
3085 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3087 lval = (__typeof__(lval)) _res; \
3090 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3091 arg7,arg8,arg9,arg10,arg11) \
3093 volatile OrigFn _orig = (orig); \
3094 volatile unsigned long _argvec[3+11]; \
3095 volatile unsigned long _res; \
3096 /* _argvec[0] holds current r2 across the call */ \
3097 _argvec[1] = (unsigned long)_orig.r2; \
3098 _argvec[2] = (unsigned long)_orig.nraddr; \
3099 _argvec[2+1] = (unsigned long)arg1; \
3100 _argvec[2+2] = (unsigned long)arg2; \
3101 _argvec[2+3] = (unsigned long)arg3; \
3102 _argvec[2+4] = (unsigned long)arg4; \
3103 _argvec[2+5] = (unsigned long)arg5; \
3104 _argvec[2+6] = (unsigned long)arg6; \
3105 _argvec[2+7] = (unsigned long)arg7; \
3106 _argvec[2+8] = (unsigned long)arg8; \
3107 _argvec[2+9] = (unsigned long)arg9; \
3108 _argvec[2+10] = (unsigned long)arg10; \
3109 _argvec[2+11] = (unsigned long)arg11; \
3111 VALGRIND_ALIGN_STACK \
3113 "std 2,-16(11)\n\t" /* save tocptr */ \
3114 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3115 "addi 1,1,-144\n\t" /* expand stack frame */ \
3118 "std 3,128(1)\n\t" \
3121 "std 3,120(1)\n\t" \
3124 "std 3,112(1)\n\t" \
3126 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3127 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3128 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3129 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3130 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3131 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3132 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3133 "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3134 "ld 11, 0(11)\n\t" /* target->r11 */ \
3135 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3138 "ld 2,-16(11)\n\t" /* restore tocptr */ \
3139 VALGRIND_RESTORE_STACK \
3140 : /*out*/ "=r" (_res) \
3141 : /*in*/ "r" (&_argvec[2]) \
3142 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3144 lval = (__typeof__(lval)) _res; \
3147 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3148 arg7,arg8,arg9,arg10,arg11,arg12) \
3150 volatile OrigFn _orig = (orig); \
3151 volatile unsigned long _argvec[3+12]; \
3152 volatile unsigned long _res; \
3153 /* _argvec[0] holds current r2 across the call */ \
3154 _argvec[1] = (unsigned long)_orig.r2; \
3155 _argvec[2] = (unsigned long)_orig.nraddr; \
3156 _argvec[2+1] = (unsigned long)arg1; \
3157 _argvec[2+2] = (unsigned long)arg2; \
3158 _argvec[2+3] = (unsigned long)arg3; \
3159 _argvec[2+4] = (unsigned long)arg4; \
3160 _argvec[2+5] = (unsigned long)arg5; \
3161 _argvec[2+6] = (unsigned long)arg6; \
3162 _argvec[2+7] = (unsigned long)arg7; \
3163 _argvec[2+8] = (unsigned long)arg8; \
3164 _argvec[2+9] = (unsigned long)arg9; \
3165 _argvec[2+10] = (unsigned long)arg10; \
3166 _argvec[2+11] = (unsigned long)arg11; \
3167 _argvec[2+12] = (unsigned long)arg12; \
3169 VALGRIND_ALIGN_STACK \
3171 "std 2,-16(11)\n\t" /* save tocptr */ \
3172 "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3173 "addi 1,1,-144\n\t" /* expand stack frame */ \
3176 "std 3,136(1)\n\t" \
3179 "std 3,128(1)\n\t" \
3182 "std 3,120(1)\n\t" \
3185 "std 3,112(1)\n\t" \
3187 "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3188 "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3189 "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3190 "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3191 "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3192 "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3193 "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3194 "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3195 "ld 11, 0(11)\n\t" /* target->r11 */ \
3196 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3199 "ld 2,-16(11)\n\t" /* restore tocptr */ \
3200 VALGRIND_RESTORE_STACK \
3201 : /*out*/ "=r" (_res) \
3202 : /*in*/ "r" (&_argvec[2]) \
3203 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3205 lval = (__typeof__(lval)) _res; \
3208 #endif /* PLAT_ppc64be_linux */
3210 /* ------------------------- ppc64le-linux ----------------------- */
3211 #if defined(PLAT_ppc64le_linux)
3213 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
3215 /* These regs are trashed by the hidden call. */
3216 #define __CALLER_SAVED_REGS \
3217 "lr", "ctr", "xer", \
3218 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
3219 "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
3222 /* Macros to save and align the stack before making a function
3223 call and restore it afterwards as gcc may not keep the stack
3224 pointer aligned if it doesn't realise calls are being made
3225 to other functions. */
3227 #define VALGRIND_ALIGN_STACK \
3229 "rldicr 1,1,0,59\n\t"
3230 #define VALGRIND_RESTORE_STACK \
3233 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
3236 #define CALL_FN_W_v(lval, orig) \
3238 volatile OrigFn _orig = (orig); \
3239 volatile unsigned long _argvec[3+0]; \
3240 volatile unsigned long _res; \
3241 /* _argvec[0] holds current r2 across the call */ \
3242 _argvec[1] = (unsigned long)_orig.r2; \
3243 _argvec[2] = (unsigned long)_orig.nraddr; \
3245 VALGRIND_ALIGN_STACK \
3247 "std 2,-16(12)\n\t" /* save tocptr */ \
3248 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3249 "ld 12, 0(12)\n\t" /* target->r12 */ \
3250 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3253 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3254 VALGRIND_RESTORE_STACK \
3255 : /*out*/ "=r" (_res) \
3256 : /*in*/ "r" (&_argvec[2]) \
3257 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3259 lval = (__typeof__(lval)) _res; \
3262 #define CALL_FN_W_W(lval, orig, arg1) \
3264 volatile OrigFn _orig = (orig); \
3265 volatile unsigned long _argvec[3+1]; \
3266 volatile unsigned long _res; \
3267 /* _argvec[0] holds current r2 across the call */ \
3268 _argvec[1] = (unsigned long)_orig.r2; \
3269 _argvec[2] = (unsigned long)_orig.nraddr; \
3270 _argvec[2+1] = (unsigned long)arg1; \
3272 VALGRIND_ALIGN_STACK \
3274 "std 2,-16(12)\n\t" /* save tocptr */ \
3275 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3276 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3277 "ld 12, 0(12)\n\t" /* target->r12 */ \
3278 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3281 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3282 VALGRIND_RESTORE_STACK \
3283 : /*out*/ "=r" (_res) \
3284 : /*in*/ "r" (&_argvec[2]) \
3285 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3287 lval = (__typeof__(lval)) _res; \
3290 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
3292 volatile OrigFn _orig = (orig); \
3293 volatile unsigned long _argvec[3+2]; \
3294 volatile unsigned long _res; \
3295 /* _argvec[0] holds current r2 across the call */ \
3296 _argvec[1] = (unsigned long)_orig.r2; \
3297 _argvec[2] = (unsigned long)_orig.nraddr; \
3298 _argvec[2+1] = (unsigned long)arg1; \
3299 _argvec[2+2] = (unsigned long)arg2; \
3301 VALGRIND_ALIGN_STACK \
3303 "std 2,-16(12)\n\t" /* save tocptr */ \
3304 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3305 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3306 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3307 "ld 12, 0(12)\n\t" /* target->r12 */ \
3308 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3311 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3312 VALGRIND_RESTORE_STACK \
3313 : /*out*/ "=r" (_res) \
3314 : /*in*/ "r" (&_argvec[2]) \
3315 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3317 lval = (__typeof__(lval)) _res; \
3320 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
3322 volatile OrigFn _orig = (orig); \
3323 volatile unsigned long _argvec[3+3]; \
3324 volatile unsigned long _res; \
3325 /* _argvec[0] holds current r2 across the call */ \
3326 _argvec[1] = (unsigned long)_orig.r2; \
3327 _argvec[2] = (unsigned long)_orig.nraddr; \
3328 _argvec[2+1] = (unsigned long)arg1; \
3329 _argvec[2+2] = (unsigned long)arg2; \
3330 _argvec[2+3] = (unsigned long)arg3; \
3332 VALGRIND_ALIGN_STACK \
3334 "std 2,-16(12)\n\t" /* save tocptr */ \
3335 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3336 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3337 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3338 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3339 "ld 12, 0(12)\n\t" /* target->r12 */ \
3340 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3343 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3344 VALGRIND_RESTORE_STACK \
3345 : /*out*/ "=r" (_res) \
3346 : /*in*/ "r" (&_argvec[2]) \
3347 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3349 lval = (__typeof__(lval)) _res; \
3352 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
3354 volatile OrigFn _orig = (orig); \
3355 volatile unsigned long _argvec[3+4]; \
3356 volatile unsigned long _res; \
3357 /* _argvec[0] holds current r2 across the call */ \
3358 _argvec[1] = (unsigned long)_orig.r2; \
3359 _argvec[2] = (unsigned long)_orig.nraddr; \
3360 _argvec[2+1] = (unsigned long)arg1; \
3361 _argvec[2+2] = (unsigned long)arg2; \
3362 _argvec[2+3] = (unsigned long)arg3; \
3363 _argvec[2+4] = (unsigned long)arg4; \
3365 VALGRIND_ALIGN_STACK \
3367 "std 2,-16(12)\n\t" /* save tocptr */ \
3368 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3369 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3370 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3371 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3372 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3373 "ld 12, 0(12)\n\t" /* target->r12 */ \
3374 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3377 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3378 VALGRIND_RESTORE_STACK \
3379 : /*out*/ "=r" (_res) \
3380 : /*in*/ "r" (&_argvec[2]) \
3381 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3383 lval = (__typeof__(lval)) _res; \
3386 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
3388 volatile OrigFn _orig = (orig); \
3389 volatile unsigned long _argvec[3+5]; \
3390 volatile unsigned long _res; \
3391 /* _argvec[0] holds current r2 across the call */ \
3392 _argvec[1] = (unsigned long)_orig.r2; \
3393 _argvec[2] = (unsigned long)_orig.nraddr; \
3394 _argvec[2+1] = (unsigned long)arg1; \
3395 _argvec[2+2] = (unsigned long)arg2; \
3396 _argvec[2+3] = (unsigned long)arg3; \
3397 _argvec[2+4] = (unsigned long)arg4; \
3398 _argvec[2+5] = (unsigned long)arg5; \
3400 VALGRIND_ALIGN_STACK \
3402 "std 2,-16(12)\n\t" /* save tocptr */ \
3403 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3404 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3405 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3406 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3407 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3408 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3409 "ld 12, 0(12)\n\t" /* target->r12 */ \
3410 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3413 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3414 VALGRIND_RESTORE_STACK \
3415 : /*out*/ "=r" (_res) \
3416 : /*in*/ "r" (&_argvec[2]) \
3417 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3419 lval = (__typeof__(lval)) _res; \
3422 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
3424 volatile OrigFn _orig = (orig); \
3425 volatile unsigned long _argvec[3+6]; \
3426 volatile unsigned long _res; \
3427 /* _argvec[0] holds current r2 across the call */ \
3428 _argvec[1] = (unsigned long)_orig.r2; \
3429 _argvec[2] = (unsigned long)_orig.nraddr; \
3430 _argvec[2+1] = (unsigned long)arg1; \
3431 _argvec[2+2] = (unsigned long)arg2; \
3432 _argvec[2+3] = (unsigned long)arg3; \
3433 _argvec[2+4] = (unsigned long)arg4; \
3434 _argvec[2+5] = (unsigned long)arg5; \
3435 _argvec[2+6] = (unsigned long)arg6; \
3437 VALGRIND_ALIGN_STACK \
3439 "std 2,-16(12)\n\t" /* save tocptr */ \
3440 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3441 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3442 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3443 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3444 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3445 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3446 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3447 "ld 12, 0(12)\n\t" /* target->r12 */ \
3448 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3451 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3452 VALGRIND_RESTORE_STACK \
3453 : /*out*/ "=r" (_res) \
3454 : /*in*/ "r" (&_argvec[2]) \
3455 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3457 lval = (__typeof__(lval)) _res; \
3460 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3463 volatile OrigFn _orig = (orig); \
3464 volatile unsigned long _argvec[3+7]; \
3465 volatile unsigned long _res; \
3466 /* _argvec[0] holds current r2 across the call */ \
3467 _argvec[1] = (unsigned long)_orig.r2; \
3468 _argvec[2] = (unsigned long)_orig.nraddr; \
3469 _argvec[2+1] = (unsigned long)arg1; \
3470 _argvec[2+2] = (unsigned long)arg2; \
3471 _argvec[2+3] = (unsigned long)arg3; \
3472 _argvec[2+4] = (unsigned long)arg4; \
3473 _argvec[2+5] = (unsigned long)arg5; \
3474 _argvec[2+6] = (unsigned long)arg6; \
3475 _argvec[2+7] = (unsigned long)arg7; \
3477 VALGRIND_ALIGN_STACK \
3479 "std 2,-16(12)\n\t" /* save tocptr */ \
3480 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3481 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3482 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3483 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3484 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3485 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3486 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3487 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3488 "ld 12, 0(12)\n\t" /* target->r12 */ \
3489 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3492 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3493 VALGRIND_RESTORE_STACK \
3494 : /*out*/ "=r" (_res) \
3495 : /*in*/ "r" (&_argvec[2]) \
3496 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3498 lval = (__typeof__(lval)) _res; \
3501 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3504 volatile OrigFn _orig = (orig); \
3505 volatile unsigned long _argvec[3+8]; \
3506 volatile unsigned long _res; \
3507 /* _argvec[0] holds current r2 across the call */ \
3508 _argvec[1] = (unsigned long)_orig.r2; \
3509 _argvec[2] = (unsigned long)_orig.nraddr; \
3510 _argvec[2+1] = (unsigned long)arg1; \
3511 _argvec[2+2] = (unsigned long)arg2; \
3512 _argvec[2+3] = (unsigned long)arg3; \
3513 _argvec[2+4] = (unsigned long)arg4; \
3514 _argvec[2+5] = (unsigned long)arg5; \
3515 _argvec[2+6] = (unsigned long)arg6; \
3516 _argvec[2+7] = (unsigned long)arg7; \
3517 _argvec[2+8] = (unsigned long)arg8; \
3519 VALGRIND_ALIGN_STACK \
3521 "std 2,-16(12)\n\t" /* save tocptr */ \
3522 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3523 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3524 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3525 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3526 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3527 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3528 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3529 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3530 "ld 10, 64(12)\n\t" /* arg8->r10 */ \
3531 "ld 12, 0(12)\n\t" /* target->r12 */ \
3532 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3535 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3536 VALGRIND_RESTORE_STACK \
3537 : /*out*/ "=r" (_res) \
3538 : /*in*/ "r" (&_argvec[2]) \
3539 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3541 lval = (__typeof__(lval)) _res; \
3544 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3547 volatile OrigFn _orig = (orig); \
3548 volatile unsigned long _argvec[3+9]; \
3549 volatile unsigned long _res; \
3550 /* _argvec[0] holds current r2 across the call */ \
3551 _argvec[1] = (unsigned long)_orig.r2; \
3552 _argvec[2] = (unsigned long)_orig.nraddr; \
3553 _argvec[2+1] = (unsigned long)arg1; \
3554 _argvec[2+2] = (unsigned long)arg2; \
3555 _argvec[2+3] = (unsigned long)arg3; \
3556 _argvec[2+4] = (unsigned long)arg4; \
3557 _argvec[2+5] = (unsigned long)arg5; \
3558 _argvec[2+6] = (unsigned long)arg6; \
3559 _argvec[2+7] = (unsigned long)arg7; \
3560 _argvec[2+8] = (unsigned long)arg8; \
3561 _argvec[2+9] = (unsigned long)arg9; \
3563 VALGRIND_ALIGN_STACK \
3565 "std 2,-16(12)\n\t" /* save tocptr */ \
3566 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3567 "addi 1,1,-128\n\t" /* expand stack frame */ \
3572 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3573 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3574 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3575 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3576 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3577 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3578 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3579 "ld 10, 64(12)\n\t" /* arg8->r10 */ \
3580 "ld 12, 0(12)\n\t" /* target->r12 */ \
3581 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3584 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3585 VALGRIND_RESTORE_STACK \
3586 : /*out*/ "=r" (_res) \
3587 : /*in*/ "r" (&_argvec[2]) \
3588 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3590 lval = (__typeof__(lval)) _res; \
3593 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3594 arg7,arg8,arg9,arg10) \
3596 volatile OrigFn _orig = (orig); \
3597 volatile unsigned long _argvec[3+10]; \
3598 volatile unsigned long _res; \
3599 /* _argvec[0] holds current r2 across the call */ \
3600 _argvec[1] = (unsigned long)_orig.r2; \
3601 _argvec[2] = (unsigned long)_orig.nraddr; \
3602 _argvec[2+1] = (unsigned long)arg1; \
3603 _argvec[2+2] = (unsigned long)arg2; \
3604 _argvec[2+3] = (unsigned long)arg3; \
3605 _argvec[2+4] = (unsigned long)arg4; \
3606 _argvec[2+5] = (unsigned long)arg5; \
3607 _argvec[2+6] = (unsigned long)arg6; \
3608 _argvec[2+7] = (unsigned long)arg7; \
3609 _argvec[2+8] = (unsigned long)arg8; \
3610 _argvec[2+9] = (unsigned long)arg9; \
3611 _argvec[2+10] = (unsigned long)arg10; \
3613 VALGRIND_ALIGN_STACK \
3615 "std 2,-16(12)\n\t" /* save tocptr */ \
3616 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3617 "addi 1,1,-128\n\t" /* expand stack frame */ \
3620 "std 3,104(1)\n\t" \
3625 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3626 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3627 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3628 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3629 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3630 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3631 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3632 "ld 10, 64(12)\n\t" /* arg8->r10 */ \
3633 "ld 12, 0(12)\n\t" /* target->r12 */ \
3634 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3637 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3638 VALGRIND_RESTORE_STACK \
3639 : /*out*/ "=r" (_res) \
3640 : /*in*/ "r" (&_argvec[2]) \
3641 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3643 lval = (__typeof__(lval)) _res; \
3646 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3647 arg7,arg8,arg9,arg10,arg11) \
3649 volatile OrigFn _orig = (orig); \
3650 volatile unsigned long _argvec[3+11]; \
3651 volatile unsigned long _res; \
3652 /* _argvec[0] holds current r2 across the call */ \
3653 _argvec[1] = (unsigned long)_orig.r2; \
3654 _argvec[2] = (unsigned long)_orig.nraddr; \
3655 _argvec[2+1] = (unsigned long)arg1; \
3656 _argvec[2+2] = (unsigned long)arg2; \
3657 _argvec[2+3] = (unsigned long)arg3; \
3658 _argvec[2+4] = (unsigned long)arg4; \
3659 _argvec[2+5] = (unsigned long)arg5; \
3660 _argvec[2+6] = (unsigned long)arg6; \
3661 _argvec[2+7] = (unsigned long)arg7; \
3662 _argvec[2+8] = (unsigned long)arg8; \
3663 _argvec[2+9] = (unsigned long)arg9; \
3664 _argvec[2+10] = (unsigned long)arg10; \
3665 _argvec[2+11] = (unsigned long)arg11; \
3667 VALGRIND_ALIGN_STACK \
3669 "std 2,-16(12)\n\t" /* save tocptr */ \
3670 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3671 "addi 1,1,-144\n\t" /* expand stack frame */ \
3674 "std 3,112(1)\n\t" \
3677 "std 3,104(1)\n\t" \
3682 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3683 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3684 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3685 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3686 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3687 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3688 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3689 "ld 10, 64(12)\n\t" /* arg8->r10 */ \
3690 "ld 12, 0(12)\n\t" /* target->r12 */ \
3691 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3694 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3695 VALGRIND_RESTORE_STACK \
3696 : /*out*/ "=r" (_res) \
3697 : /*in*/ "r" (&_argvec[2]) \
3698 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3700 lval = (__typeof__(lval)) _res; \
3703 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3704 arg7,arg8,arg9,arg10,arg11,arg12) \
3706 volatile OrigFn _orig = (orig); \
3707 volatile unsigned long _argvec[3+12]; \
3708 volatile unsigned long _res; \
3709 /* _argvec[0] holds current r2 across the call */ \
3710 _argvec[1] = (unsigned long)_orig.r2; \
3711 _argvec[2] = (unsigned long)_orig.nraddr; \
3712 _argvec[2+1] = (unsigned long)arg1; \
3713 _argvec[2+2] = (unsigned long)arg2; \
3714 _argvec[2+3] = (unsigned long)arg3; \
3715 _argvec[2+4] = (unsigned long)arg4; \
3716 _argvec[2+5] = (unsigned long)arg5; \
3717 _argvec[2+6] = (unsigned long)arg6; \
3718 _argvec[2+7] = (unsigned long)arg7; \
3719 _argvec[2+8] = (unsigned long)arg8; \
3720 _argvec[2+9] = (unsigned long)arg9; \
3721 _argvec[2+10] = (unsigned long)arg10; \
3722 _argvec[2+11] = (unsigned long)arg11; \
3723 _argvec[2+12] = (unsigned long)arg12; \
3725 VALGRIND_ALIGN_STACK \
3727 "std 2,-16(12)\n\t" /* save tocptr */ \
3728 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \
3729 "addi 1,1,-144\n\t" /* expand stack frame */ \
3732 "std 3,120(1)\n\t" \
3735 "std 3,112(1)\n\t" \
3738 "std 3,104(1)\n\t" \
3743 "ld 3, 8(12)\n\t" /* arg1->r3 */ \
3744 "ld 4, 16(12)\n\t" /* arg2->r4 */ \
3745 "ld 5, 24(12)\n\t" /* arg3->r5 */ \
3746 "ld 6, 32(12)\n\t" /* arg4->r6 */ \
3747 "ld 7, 40(12)\n\t" /* arg5->r7 */ \
3748 "ld 8, 48(12)\n\t" /* arg6->r8 */ \
3749 "ld 9, 56(12)\n\t" /* arg7->r9 */ \
3750 "ld 10, 64(12)\n\t" /* arg8->r10 */ \
3751 "ld 12, 0(12)\n\t" /* target->r12 */ \
3752 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \
3755 "ld 2,-16(12)\n\t" /* restore tocptr */ \
3756 VALGRIND_RESTORE_STACK \
3757 : /*out*/ "=r" (_res) \
3758 : /*in*/ "r" (&_argvec[2]) \
3759 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \
3761 lval = (__typeof__(lval)) _res; \
3764 #endif /* PLAT_ppc64le_linux */
3766 /* ------------------------- arm-linux ------------------------- */
3768 #if defined(PLAT_arm_linux)
3770 /* These regs are trashed by the hidden call. */
3771 #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4", "r12", "r14"
3773 /* Macros to save and align the stack before making a function
3774 call and restore it afterwards as gcc may not keep the stack
3775 pointer aligned if it doesn't realise calls are being made
3776 to other functions. */
3778 /* This is a bit tricky. We store the original stack pointer in r10
3779 as it is callee-saves. gcc doesn't allow the use of r11 for some
3780 reason. Also, we can't directly "bic" the stack pointer in thumb
3781 mode since r13 isn't an allowed register number in that context.
3782 So use r4 as a temporary, since that is about to get trashed
3783 anyway, just after each use of this macro. Side effect is we need
3784 to be very careful about any future changes, since
3785 VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
3786 #define VALGRIND_ALIGN_STACK \
3789 "bic r4, r4, #7\n\t" \
3791 #define VALGRIND_RESTORE_STACK \
3794 /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
3797 #define CALL_FN_W_v(lval, orig) \
3799 volatile OrigFn _orig = (orig); \
3800 volatile unsigned long _argvec[1]; \
3801 volatile unsigned long _res; \
3802 _argvec[0] = (unsigned long)_orig.nraddr; \
3804 VALGRIND_ALIGN_STACK \
3805 "ldr r4, [%1] \n\t" /* target->r4 */ \
3806 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3807 VALGRIND_RESTORE_STACK \
3809 : /*out*/ "=r" (_res) \
3810 : /*in*/ "0" (&_argvec[0]) \
3811 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3813 lval = (__typeof__(lval)) _res; \
3816 #define CALL_FN_W_W(lval, orig, arg1) \
3818 volatile OrigFn _orig = (orig); \
3819 volatile unsigned long _argvec[2]; \
3820 volatile unsigned long _res; \
3821 _argvec[0] = (unsigned long)_orig.nraddr; \
3822 _argvec[1] = (unsigned long)(arg1); \
3824 VALGRIND_ALIGN_STACK \
3825 "ldr r0, [%1, #4] \n\t" \
3826 "ldr r4, [%1] \n\t" /* target->r4 */ \
3827 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3828 VALGRIND_RESTORE_STACK \
3830 : /*out*/ "=r" (_res) \
3831 : /*in*/ "0" (&_argvec[0]) \
3832 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3834 lval = (__typeof__(lval)) _res; \
3837 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
3839 volatile OrigFn _orig = (orig); \
3840 volatile unsigned long _argvec[3]; \
3841 volatile unsigned long _res; \
3842 _argvec[0] = (unsigned long)_orig.nraddr; \
3843 _argvec[1] = (unsigned long)(arg1); \
3844 _argvec[2] = (unsigned long)(arg2); \
3846 VALGRIND_ALIGN_STACK \
3847 "ldr r0, [%1, #4] \n\t" \
3848 "ldr r1, [%1, #8] \n\t" \
3849 "ldr r4, [%1] \n\t" /* target->r4 */ \
3850 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3851 VALGRIND_RESTORE_STACK \
3853 : /*out*/ "=r" (_res) \
3854 : /*in*/ "0" (&_argvec[0]) \
3855 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3857 lval = (__typeof__(lval)) _res; \
3860 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
3862 volatile OrigFn _orig = (orig); \
3863 volatile unsigned long _argvec[4]; \
3864 volatile unsigned long _res; \
3865 _argvec[0] = (unsigned long)_orig.nraddr; \
3866 _argvec[1] = (unsigned long)(arg1); \
3867 _argvec[2] = (unsigned long)(arg2); \
3868 _argvec[3] = (unsigned long)(arg3); \
3870 VALGRIND_ALIGN_STACK \
3871 "ldr r0, [%1, #4] \n\t" \
3872 "ldr r1, [%1, #8] \n\t" \
3873 "ldr r2, [%1, #12] \n\t" \
3874 "ldr r4, [%1] \n\t" /* target->r4 */ \
3875 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3876 VALGRIND_RESTORE_STACK \
3878 : /*out*/ "=r" (_res) \
3879 : /*in*/ "0" (&_argvec[0]) \
3880 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3882 lval = (__typeof__(lval)) _res; \
3885 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
3887 volatile OrigFn _orig = (orig); \
3888 volatile unsigned long _argvec[5]; \
3889 volatile unsigned long _res; \
3890 _argvec[0] = (unsigned long)_orig.nraddr; \
3891 _argvec[1] = (unsigned long)(arg1); \
3892 _argvec[2] = (unsigned long)(arg2); \
3893 _argvec[3] = (unsigned long)(arg3); \
3894 _argvec[4] = (unsigned long)(arg4); \
3896 VALGRIND_ALIGN_STACK \
3897 "ldr r0, [%1, #4] \n\t" \
3898 "ldr r1, [%1, #8] \n\t" \
3899 "ldr r2, [%1, #12] \n\t" \
3900 "ldr r3, [%1, #16] \n\t" \
3901 "ldr r4, [%1] \n\t" /* target->r4 */ \
3902 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3903 VALGRIND_RESTORE_STACK \
3905 : /*out*/ "=r" (_res) \
3906 : /*in*/ "0" (&_argvec[0]) \
3907 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3909 lval = (__typeof__(lval)) _res; \
3912 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
3914 volatile OrigFn _orig = (orig); \
3915 volatile unsigned long _argvec[6]; \
3916 volatile unsigned long _res; \
3917 _argvec[0] = (unsigned long)_orig.nraddr; \
3918 _argvec[1] = (unsigned long)(arg1); \
3919 _argvec[2] = (unsigned long)(arg2); \
3920 _argvec[3] = (unsigned long)(arg3); \
3921 _argvec[4] = (unsigned long)(arg4); \
3922 _argvec[5] = (unsigned long)(arg5); \
3924 VALGRIND_ALIGN_STACK \
3925 "sub sp, sp, #4 \n\t" \
3926 "ldr r0, [%1, #20] \n\t" \
3928 "ldr r0, [%1, #4] \n\t" \
3929 "ldr r1, [%1, #8] \n\t" \
3930 "ldr r2, [%1, #12] \n\t" \
3931 "ldr r3, [%1, #16] \n\t" \
3932 "ldr r4, [%1] \n\t" /* target->r4 */ \
3933 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3934 VALGRIND_RESTORE_STACK \
3936 : /*out*/ "=r" (_res) \
3937 : /*in*/ "0" (&_argvec[0]) \
3938 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3940 lval = (__typeof__(lval)) _res; \
3943 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
3945 volatile OrigFn _orig = (orig); \
3946 volatile unsigned long _argvec[7]; \
3947 volatile unsigned long _res; \
3948 _argvec[0] = (unsigned long)_orig.nraddr; \
3949 _argvec[1] = (unsigned long)(arg1); \
3950 _argvec[2] = (unsigned long)(arg2); \
3951 _argvec[3] = (unsigned long)(arg3); \
3952 _argvec[4] = (unsigned long)(arg4); \
3953 _argvec[5] = (unsigned long)(arg5); \
3954 _argvec[6] = (unsigned long)(arg6); \
3956 VALGRIND_ALIGN_STACK \
3957 "ldr r0, [%1, #20] \n\t" \
3958 "ldr r1, [%1, #24] \n\t" \
3959 "push {r0, r1} \n\t" \
3960 "ldr r0, [%1, #4] \n\t" \
3961 "ldr r1, [%1, #8] \n\t" \
3962 "ldr r2, [%1, #12] \n\t" \
3963 "ldr r3, [%1, #16] \n\t" \
3964 "ldr r4, [%1] \n\t" /* target->r4 */ \
3965 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3966 VALGRIND_RESTORE_STACK \
3968 : /*out*/ "=r" (_res) \
3969 : /*in*/ "0" (&_argvec[0]) \
3970 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
3972 lval = (__typeof__(lval)) _res; \
3975 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3978 volatile OrigFn _orig = (orig); \
3979 volatile unsigned long _argvec[8]; \
3980 volatile unsigned long _res; \
3981 _argvec[0] = (unsigned long)_orig.nraddr; \
3982 _argvec[1] = (unsigned long)(arg1); \
3983 _argvec[2] = (unsigned long)(arg2); \
3984 _argvec[3] = (unsigned long)(arg3); \
3985 _argvec[4] = (unsigned long)(arg4); \
3986 _argvec[5] = (unsigned long)(arg5); \
3987 _argvec[6] = (unsigned long)(arg6); \
3988 _argvec[7] = (unsigned long)(arg7); \
3990 VALGRIND_ALIGN_STACK \
3991 "sub sp, sp, #4 \n\t" \
3992 "ldr r0, [%1, #20] \n\t" \
3993 "ldr r1, [%1, #24] \n\t" \
3994 "ldr r2, [%1, #28] \n\t" \
3995 "push {r0, r1, r2} \n\t" \
3996 "ldr r0, [%1, #4] \n\t" \
3997 "ldr r1, [%1, #8] \n\t" \
3998 "ldr r2, [%1, #12] \n\t" \
3999 "ldr r3, [%1, #16] \n\t" \
4000 "ldr r4, [%1] \n\t" /* target->r4 */ \
4001 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4002 VALGRIND_RESTORE_STACK \
4004 : /*out*/ "=r" (_res) \
4005 : /*in*/ "0" (&_argvec[0]) \
4006 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4008 lval = (__typeof__(lval)) _res; \
4011 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4014 volatile OrigFn _orig = (orig); \
4015 volatile unsigned long _argvec[9]; \
4016 volatile unsigned long _res; \
4017 _argvec[0] = (unsigned long)_orig.nraddr; \
4018 _argvec[1] = (unsigned long)(arg1); \
4019 _argvec[2] = (unsigned long)(arg2); \
4020 _argvec[3] = (unsigned long)(arg3); \
4021 _argvec[4] = (unsigned long)(arg4); \
4022 _argvec[5] = (unsigned long)(arg5); \
4023 _argvec[6] = (unsigned long)(arg6); \
4024 _argvec[7] = (unsigned long)(arg7); \
4025 _argvec[8] = (unsigned long)(arg8); \
4027 VALGRIND_ALIGN_STACK \
4028 "ldr r0, [%1, #20] \n\t" \
4029 "ldr r1, [%1, #24] \n\t" \
4030 "ldr r2, [%1, #28] \n\t" \
4031 "ldr r3, [%1, #32] \n\t" \
4032 "push {r0, r1, r2, r3} \n\t" \
4033 "ldr r0, [%1, #4] \n\t" \
4034 "ldr r1, [%1, #8] \n\t" \
4035 "ldr r2, [%1, #12] \n\t" \
4036 "ldr r3, [%1, #16] \n\t" \
4037 "ldr r4, [%1] \n\t" /* target->r4 */ \
4038 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4039 VALGRIND_RESTORE_STACK \
4041 : /*out*/ "=r" (_res) \
4042 : /*in*/ "0" (&_argvec[0]) \
4043 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4045 lval = (__typeof__(lval)) _res; \
4048 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4051 volatile OrigFn _orig = (orig); \
4052 volatile unsigned long _argvec[10]; \
4053 volatile unsigned long _res; \
4054 _argvec[0] = (unsigned long)_orig.nraddr; \
4055 _argvec[1] = (unsigned long)(arg1); \
4056 _argvec[2] = (unsigned long)(arg2); \
4057 _argvec[3] = (unsigned long)(arg3); \
4058 _argvec[4] = (unsigned long)(arg4); \
4059 _argvec[5] = (unsigned long)(arg5); \
4060 _argvec[6] = (unsigned long)(arg6); \
4061 _argvec[7] = (unsigned long)(arg7); \
4062 _argvec[8] = (unsigned long)(arg8); \
4063 _argvec[9] = (unsigned long)(arg9); \
4065 VALGRIND_ALIGN_STACK \
4066 "sub sp, sp, #4 \n\t" \
4067 "ldr r0, [%1, #20] \n\t" \
4068 "ldr r1, [%1, #24] \n\t" \
4069 "ldr r2, [%1, #28] \n\t" \
4070 "ldr r3, [%1, #32] \n\t" \
4071 "ldr r4, [%1, #36] \n\t" \
4072 "push {r0, r1, r2, r3, r4} \n\t" \
4073 "ldr r0, [%1, #4] \n\t" \
4074 "ldr r1, [%1, #8] \n\t" \
4075 "ldr r2, [%1, #12] \n\t" \
4076 "ldr r3, [%1, #16] \n\t" \
4077 "ldr r4, [%1] \n\t" /* target->r4 */ \
4078 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4079 VALGRIND_RESTORE_STACK \
4081 : /*out*/ "=r" (_res) \
4082 : /*in*/ "0" (&_argvec[0]) \
4083 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4085 lval = (__typeof__(lval)) _res; \
4088 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4089 arg7,arg8,arg9,arg10) \
4091 volatile OrigFn _orig = (orig); \
4092 volatile unsigned long _argvec[11]; \
4093 volatile unsigned long _res; \
4094 _argvec[0] = (unsigned long)_orig.nraddr; \
4095 _argvec[1] = (unsigned long)(arg1); \
4096 _argvec[2] = (unsigned long)(arg2); \
4097 _argvec[3] = (unsigned long)(arg3); \
4098 _argvec[4] = (unsigned long)(arg4); \
4099 _argvec[5] = (unsigned long)(arg5); \
4100 _argvec[6] = (unsigned long)(arg6); \
4101 _argvec[7] = (unsigned long)(arg7); \
4102 _argvec[8] = (unsigned long)(arg8); \
4103 _argvec[9] = (unsigned long)(arg9); \
4104 _argvec[10] = (unsigned long)(arg10); \
4106 VALGRIND_ALIGN_STACK \
4107 "ldr r0, [%1, #40] \n\t" \
4109 "ldr r0, [%1, #20] \n\t" \
4110 "ldr r1, [%1, #24] \n\t" \
4111 "ldr r2, [%1, #28] \n\t" \
4112 "ldr r3, [%1, #32] \n\t" \
4113 "ldr r4, [%1, #36] \n\t" \
4114 "push {r0, r1, r2, r3, r4} \n\t" \
4115 "ldr r0, [%1, #4] \n\t" \
4116 "ldr r1, [%1, #8] \n\t" \
4117 "ldr r2, [%1, #12] \n\t" \
4118 "ldr r3, [%1, #16] \n\t" \
4119 "ldr r4, [%1] \n\t" /* target->r4 */ \
4120 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4121 VALGRIND_RESTORE_STACK \
4123 : /*out*/ "=r" (_res) \
4124 : /*in*/ "0" (&_argvec[0]) \
4125 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4127 lval = (__typeof__(lval)) _res; \
4130 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
4131 arg6,arg7,arg8,arg9,arg10, \
4134 volatile OrigFn _orig = (orig); \
4135 volatile unsigned long _argvec[12]; \
4136 volatile unsigned long _res; \
4137 _argvec[0] = (unsigned long)_orig.nraddr; \
4138 _argvec[1] = (unsigned long)(arg1); \
4139 _argvec[2] = (unsigned long)(arg2); \
4140 _argvec[3] = (unsigned long)(arg3); \
4141 _argvec[4] = (unsigned long)(arg4); \
4142 _argvec[5] = (unsigned long)(arg5); \
4143 _argvec[6] = (unsigned long)(arg6); \
4144 _argvec[7] = (unsigned long)(arg7); \
4145 _argvec[8] = (unsigned long)(arg8); \
4146 _argvec[9] = (unsigned long)(arg9); \
4147 _argvec[10] = (unsigned long)(arg10); \
4148 _argvec[11] = (unsigned long)(arg11); \
4150 VALGRIND_ALIGN_STACK \
4151 "sub sp, sp, #4 \n\t" \
4152 "ldr r0, [%1, #40] \n\t" \
4153 "ldr r1, [%1, #44] \n\t" \
4154 "push {r0, r1} \n\t" \
4155 "ldr r0, [%1, #20] \n\t" \
4156 "ldr r1, [%1, #24] \n\t" \
4157 "ldr r2, [%1, #28] \n\t" \
4158 "ldr r3, [%1, #32] \n\t" \
4159 "ldr r4, [%1, #36] \n\t" \
4160 "push {r0, r1, r2, r3, r4} \n\t" \
4161 "ldr r0, [%1, #4] \n\t" \
4162 "ldr r1, [%1, #8] \n\t" \
4163 "ldr r2, [%1, #12] \n\t" \
4164 "ldr r3, [%1, #16] \n\t" \
4165 "ldr r4, [%1] \n\t" /* target->r4 */ \
4166 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4167 VALGRIND_RESTORE_STACK \
4169 : /*out*/ "=r" (_res) \
4170 : /*in*/ "0" (&_argvec[0]) \
4171 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4173 lval = (__typeof__(lval)) _res; \
4176 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
4177 arg6,arg7,arg8,arg9,arg10, \
4180 volatile OrigFn _orig = (orig); \
4181 volatile unsigned long _argvec[13]; \
4182 volatile unsigned long _res; \
4183 _argvec[0] = (unsigned long)_orig.nraddr; \
4184 _argvec[1] = (unsigned long)(arg1); \
4185 _argvec[2] = (unsigned long)(arg2); \
4186 _argvec[3] = (unsigned long)(arg3); \
4187 _argvec[4] = (unsigned long)(arg4); \
4188 _argvec[5] = (unsigned long)(arg5); \
4189 _argvec[6] = (unsigned long)(arg6); \
4190 _argvec[7] = (unsigned long)(arg7); \
4191 _argvec[8] = (unsigned long)(arg8); \
4192 _argvec[9] = (unsigned long)(arg9); \
4193 _argvec[10] = (unsigned long)(arg10); \
4194 _argvec[11] = (unsigned long)(arg11); \
4195 _argvec[12] = (unsigned long)(arg12); \
4197 VALGRIND_ALIGN_STACK \
4198 "ldr r0, [%1, #40] \n\t" \
4199 "ldr r1, [%1, #44] \n\t" \
4200 "ldr r2, [%1, #48] \n\t" \
4201 "push {r0, r1, r2} \n\t" \
4202 "ldr r0, [%1, #20] \n\t" \
4203 "ldr r1, [%1, #24] \n\t" \
4204 "ldr r2, [%1, #28] \n\t" \
4205 "ldr r3, [%1, #32] \n\t" \
4206 "ldr r4, [%1, #36] \n\t" \
4207 "push {r0, r1, r2, r3, r4} \n\t" \
4208 "ldr r0, [%1, #4] \n\t" \
4209 "ldr r1, [%1, #8] \n\t" \
4210 "ldr r2, [%1, #12] \n\t" \
4211 "ldr r3, [%1, #16] \n\t" \
4212 "ldr r4, [%1] \n\t" /* target->r4 */ \
4213 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
4214 VALGRIND_RESTORE_STACK \
4216 : /*out*/ "=r" (_res) \
4217 : /*in*/ "0" (&_argvec[0]) \
4218 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \
4220 lval = (__typeof__(lval)) _res; \
4223 #endif /* PLAT_arm_linux */
4225 /* ------------------------ arm64-linux ------------------------ */
4227 #if defined(PLAT_arm64_linux)
4229 /* These regs are trashed by the hidden call. */
4230 #define __CALLER_SAVED_REGS \
4231 "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9", \
4232 "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \
4233 "x18", "x19", "x20", "x30", \
4234 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
4235 "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \
4236 "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \
4237 "v26", "v27", "v28", "v29", "v30", "v31"
4239 /* x21 is callee-saved, so we can use it to save and restore SP around
4241 #define VALGRIND_ALIGN_STACK \
4243 "bic sp, x21, #15\n\t"
4244 #define VALGRIND_RESTORE_STACK \
4247 /* These CALL_FN_ macros assume that on arm64-linux,
4248 sizeof(unsigned long) == 8. */
4250 #define CALL_FN_W_v(lval, orig) \
4252 volatile OrigFn _orig = (orig); \
4253 volatile unsigned long _argvec[1]; \
4254 volatile unsigned long _res; \
4255 _argvec[0] = (unsigned long)_orig.nraddr; \
4257 VALGRIND_ALIGN_STACK \
4258 "ldr x8, [%1] \n\t" /* target->x8 */ \
4259 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4260 VALGRIND_RESTORE_STACK \
4262 : /*out*/ "=r" (_res) \
4263 : /*in*/ "0" (&_argvec[0]) \
4264 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4266 lval = (__typeof__(lval)) _res; \
4269 #define CALL_FN_W_W(lval, orig, arg1) \
4271 volatile OrigFn _orig = (orig); \
4272 volatile unsigned long _argvec[2]; \
4273 volatile unsigned long _res; \
4274 _argvec[0] = (unsigned long)_orig.nraddr; \
4275 _argvec[1] = (unsigned long)(arg1); \
4277 VALGRIND_ALIGN_STACK \
4278 "ldr x0, [%1, #8] \n\t" \
4279 "ldr x8, [%1] \n\t" /* target->x8 */ \
4280 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4281 VALGRIND_RESTORE_STACK \
4283 : /*out*/ "=r" (_res) \
4284 : /*in*/ "0" (&_argvec[0]) \
4285 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4287 lval = (__typeof__(lval)) _res; \
4290 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
4292 volatile OrigFn _orig = (orig); \
4293 volatile unsigned long _argvec[3]; \
4294 volatile unsigned long _res; \
4295 _argvec[0] = (unsigned long)_orig.nraddr; \
4296 _argvec[1] = (unsigned long)(arg1); \
4297 _argvec[2] = (unsigned long)(arg2); \
4299 VALGRIND_ALIGN_STACK \
4300 "ldr x0, [%1, #8] \n\t" \
4301 "ldr x1, [%1, #16] \n\t" \
4302 "ldr x8, [%1] \n\t" /* target->x8 */ \
4303 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4304 VALGRIND_RESTORE_STACK \
4306 : /*out*/ "=r" (_res) \
4307 : /*in*/ "0" (&_argvec[0]) \
4308 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4310 lval = (__typeof__(lval)) _res; \
4313 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
4315 volatile OrigFn _orig = (orig); \
4316 volatile unsigned long _argvec[4]; \
4317 volatile unsigned long _res; \
4318 _argvec[0] = (unsigned long)_orig.nraddr; \
4319 _argvec[1] = (unsigned long)(arg1); \
4320 _argvec[2] = (unsigned long)(arg2); \
4321 _argvec[3] = (unsigned long)(arg3); \
4323 VALGRIND_ALIGN_STACK \
4324 "ldr x0, [%1, #8] \n\t" \
4325 "ldr x1, [%1, #16] \n\t" \
4326 "ldr x2, [%1, #24] \n\t" \
4327 "ldr x8, [%1] \n\t" /* target->x8 */ \
4328 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4329 VALGRIND_RESTORE_STACK \
4331 : /*out*/ "=r" (_res) \
4332 : /*in*/ "0" (&_argvec[0]) \
4333 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4335 lval = (__typeof__(lval)) _res; \
4338 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
4340 volatile OrigFn _orig = (orig); \
4341 volatile unsigned long _argvec[5]; \
4342 volatile unsigned long _res; \
4343 _argvec[0] = (unsigned long)_orig.nraddr; \
4344 _argvec[1] = (unsigned long)(arg1); \
4345 _argvec[2] = (unsigned long)(arg2); \
4346 _argvec[3] = (unsigned long)(arg3); \
4347 _argvec[4] = (unsigned long)(arg4); \
4349 VALGRIND_ALIGN_STACK \
4350 "ldr x0, [%1, #8] \n\t" \
4351 "ldr x1, [%1, #16] \n\t" \
4352 "ldr x2, [%1, #24] \n\t" \
4353 "ldr x3, [%1, #32] \n\t" \
4354 "ldr x8, [%1] \n\t" /* target->x8 */ \
4355 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4356 VALGRIND_RESTORE_STACK \
4358 : /*out*/ "=r" (_res) \
4359 : /*in*/ "0" (&_argvec[0]) \
4360 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4362 lval = (__typeof__(lval)) _res; \
4365 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
4367 volatile OrigFn _orig = (orig); \
4368 volatile unsigned long _argvec[6]; \
4369 volatile unsigned long _res; \
4370 _argvec[0] = (unsigned long)_orig.nraddr; \
4371 _argvec[1] = (unsigned long)(arg1); \
4372 _argvec[2] = (unsigned long)(arg2); \
4373 _argvec[3] = (unsigned long)(arg3); \
4374 _argvec[4] = (unsigned long)(arg4); \
4375 _argvec[5] = (unsigned long)(arg5); \
4377 VALGRIND_ALIGN_STACK \
4378 "ldr x0, [%1, #8] \n\t" \
4379 "ldr x1, [%1, #16] \n\t" \
4380 "ldr x2, [%1, #24] \n\t" \
4381 "ldr x3, [%1, #32] \n\t" \
4382 "ldr x4, [%1, #40] \n\t" \
4383 "ldr x8, [%1] \n\t" /* target->x8 */ \
4384 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4385 VALGRIND_RESTORE_STACK \
4387 : /*out*/ "=r" (_res) \
4388 : /*in*/ "0" (&_argvec[0]) \
4389 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4391 lval = (__typeof__(lval)) _res; \
4394 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
4396 volatile OrigFn _orig = (orig); \
4397 volatile unsigned long _argvec[7]; \
4398 volatile unsigned long _res; \
4399 _argvec[0] = (unsigned long)_orig.nraddr; \
4400 _argvec[1] = (unsigned long)(arg1); \
4401 _argvec[2] = (unsigned long)(arg2); \
4402 _argvec[3] = (unsigned long)(arg3); \
4403 _argvec[4] = (unsigned long)(arg4); \
4404 _argvec[5] = (unsigned long)(arg5); \
4405 _argvec[6] = (unsigned long)(arg6); \
4407 VALGRIND_ALIGN_STACK \
4408 "ldr x0, [%1, #8] \n\t" \
4409 "ldr x1, [%1, #16] \n\t" \
4410 "ldr x2, [%1, #24] \n\t" \
4411 "ldr x3, [%1, #32] \n\t" \
4412 "ldr x4, [%1, #40] \n\t" \
4413 "ldr x5, [%1, #48] \n\t" \
4414 "ldr x8, [%1] \n\t" /* target->x8 */ \
4415 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4416 VALGRIND_RESTORE_STACK \
4418 : /*out*/ "=r" (_res) \
4419 : /*in*/ "0" (&_argvec[0]) \
4420 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4422 lval = (__typeof__(lval)) _res; \
4425 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4428 volatile OrigFn _orig = (orig); \
4429 volatile unsigned long _argvec[8]; \
4430 volatile unsigned long _res; \
4431 _argvec[0] = (unsigned long)_orig.nraddr; \
4432 _argvec[1] = (unsigned long)(arg1); \
4433 _argvec[2] = (unsigned long)(arg2); \
4434 _argvec[3] = (unsigned long)(arg3); \
4435 _argvec[4] = (unsigned long)(arg4); \
4436 _argvec[5] = (unsigned long)(arg5); \
4437 _argvec[6] = (unsigned long)(arg6); \
4438 _argvec[7] = (unsigned long)(arg7); \
4440 VALGRIND_ALIGN_STACK \
4441 "ldr x0, [%1, #8] \n\t" \
4442 "ldr x1, [%1, #16] \n\t" \
4443 "ldr x2, [%1, #24] \n\t" \
4444 "ldr x3, [%1, #32] \n\t" \
4445 "ldr x4, [%1, #40] \n\t" \
4446 "ldr x5, [%1, #48] \n\t" \
4447 "ldr x6, [%1, #56] \n\t" \
4448 "ldr x8, [%1] \n\t" /* target->x8 */ \
4449 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4450 VALGRIND_RESTORE_STACK \
4452 : /*out*/ "=r" (_res) \
4453 : /*in*/ "0" (&_argvec[0]) \
4454 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4456 lval = (__typeof__(lval)) _res; \
4459 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4462 volatile OrigFn _orig = (orig); \
4463 volatile unsigned long _argvec[9]; \
4464 volatile unsigned long _res; \
4465 _argvec[0] = (unsigned long)_orig.nraddr; \
4466 _argvec[1] = (unsigned long)(arg1); \
4467 _argvec[2] = (unsigned long)(arg2); \
4468 _argvec[3] = (unsigned long)(arg3); \
4469 _argvec[4] = (unsigned long)(arg4); \
4470 _argvec[5] = (unsigned long)(arg5); \
4471 _argvec[6] = (unsigned long)(arg6); \
4472 _argvec[7] = (unsigned long)(arg7); \
4473 _argvec[8] = (unsigned long)(arg8); \
4475 VALGRIND_ALIGN_STACK \
4476 "ldr x0, [%1, #8] \n\t" \
4477 "ldr x1, [%1, #16] \n\t" \
4478 "ldr x2, [%1, #24] \n\t" \
4479 "ldr x3, [%1, #32] \n\t" \
4480 "ldr x4, [%1, #40] \n\t" \
4481 "ldr x5, [%1, #48] \n\t" \
4482 "ldr x6, [%1, #56] \n\t" \
4483 "ldr x7, [%1, #64] \n\t" \
4484 "ldr x8, [%1] \n\t" /* target->x8 */ \
4485 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4486 VALGRIND_RESTORE_STACK \
4488 : /*out*/ "=r" (_res) \
4489 : /*in*/ "0" (&_argvec[0]) \
4490 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4492 lval = (__typeof__(lval)) _res; \
4495 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4498 volatile OrigFn _orig = (orig); \
4499 volatile unsigned long _argvec[10]; \
4500 volatile unsigned long _res; \
4501 _argvec[0] = (unsigned long)_orig.nraddr; \
4502 _argvec[1] = (unsigned long)(arg1); \
4503 _argvec[2] = (unsigned long)(arg2); \
4504 _argvec[3] = (unsigned long)(arg3); \
4505 _argvec[4] = (unsigned long)(arg4); \
4506 _argvec[5] = (unsigned long)(arg5); \
4507 _argvec[6] = (unsigned long)(arg6); \
4508 _argvec[7] = (unsigned long)(arg7); \
4509 _argvec[8] = (unsigned long)(arg8); \
4510 _argvec[9] = (unsigned long)(arg9); \
4512 VALGRIND_ALIGN_STACK \
4513 "sub sp, sp, #0x20 \n\t" \
4514 "ldr x0, [%1, #8] \n\t" \
4515 "ldr x1, [%1, #16] \n\t" \
4516 "ldr x2, [%1, #24] \n\t" \
4517 "ldr x3, [%1, #32] \n\t" \
4518 "ldr x4, [%1, #40] \n\t" \
4519 "ldr x5, [%1, #48] \n\t" \
4520 "ldr x6, [%1, #56] \n\t" \
4521 "ldr x7, [%1, #64] \n\t" \
4522 "ldr x8, [%1, #72] \n\t" \
4523 "str x8, [sp, #0] \n\t" \
4524 "ldr x8, [%1] \n\t" /* target->x8 */ \
4525 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4526 VALGRIND_RESTORE_STACK \
4528 : /*out*/ "=r" (_res) \
4529 : /*in*/ "0" (&_argvec[0]) \
4530 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4532 lval = (__typeof__(lval)) _res; \
4535 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4536 arg7,arg8,arg9,arg10) \
4538 volatile OrigFn _orig = (orig); \
4539 volatile unsigned long _argvec[11]; \
4540 volatile unsigned long _res; \
4541 _argvec[0] = (unsigned long)_orig.nraddr; \
4542 _argvec[1] = (unsigned long)(arg1); \
4543 _argvec[2] = (unsigned long)(arg2); \
4544 _argvec[3] = (unsigned long)(arg3); \
4545 _argvec[4] = (unsigned long)(arg4); \
4546 _argvec[5] = (unsigned long)(arg5); \
4547 _argvec[6] = (unsigned long)(arg6); \
4548 _argvec[7] = (unsigned long)(arg7); \
4549 _argvec[8] = (unsigned long)(arg8); \
4550 _argvec[9] = (unsigned long)(arg9); \
4551 _argvec[10] = (unsigned long)(arg10); \
4553 VALGRIND_ALIGN_STACK \
4554 "sub sp, sp, #0x20 \n\t" \
4555 "ldr x0, [%1, #8] \n\t" \
4556 "ldr x1, [%1, #16] \n\t" \
4557 "ldr x2, [%1, #24] \n\t" \
4558 "ldr x3, [%1, #32] \n\t" \
4559 "ldr x4, [%1, #40] \n\t" \
4560 "ldr x5, [%1, #48] \n\t" \
4561 "ldr x6, [%1, #56] \n\t" \
4562 "ldr x7, [%1, #64] \n\t" \
4563 "ldr x8, [%1, #72] \n\t" \
4564 "str x8, [sp, #0] \n\t" \
4565 "ldr x8, [%1, #80] \n\t" \
4566 "str x8, [sp, #8] \n\t" \
4567 "ldr x8, [%1] \n\t" /* target->x8 */ \
4568 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4569 VALGRIND_RESTORE_STACK \
4571 : /*out*/ "=r" (_res) \
4572 : /*in*/ "0" (&_argvec[0]) \
4573 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4575 lval = (__typeof__(lval)) _res; \
4578 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4579 arg7,arg8,arg9,arg10,arg11) \
4581 volatile OrigFn _orig = (orig); \
4582 volatile unsigned long _argvec[12]; \
4583 volatile unsigned long _res; \
4584 _argvec[0] = (unsigned long)_orig.nraddr; \
4585 _argvec[1] = (unsigned long)(arg1); \
4586 _argvec[2] = (unsigned long)(arg2); \
4587 _argvec[3] = (unsigned long)(arg3); \
4588 _argvec[4] = (unsigned long)(arg4); \
4589 _argvec[5] = (unsigned long)(arg5); \
4590 _argvec[6] = (unsigned long)(arg6); \
4591 _argvec[7] = (unsigned long)(arg7); \
4592 _argvec[8] = (unsigned long)(arg8); \
4593 _argvec[9] = (unsigned long)(arg9); \
4594 _argvec[10] = (unsigned long)(arg10); \
4595 _argvec[11] = (unsigned long)(arg11); \
4597 VALGRIND_ALIGN_STACK \
4598 "sub sp, sp, #0x30 \n\t" \
4599 "ldr x0, [%1, #8] \n\t" \
4600 "ldr x1, [%1, #16] \n\t" \
4601 "ldr x2, [%1, #24] \n\t" \
4602 "ldr x3, [%1, #32] \n\t" \
4603 "ldr x4, [%1, #40] \n\t" \
4604 "ldr x5, [%1, #48] \n\t" \
4605 "ldr x6, [%1, #56] \n\t" \
4606 "ldr x7, [%1, #64] \n\t" \
4607 "ldr x8, [%1, #72] \n\t" \
4608 "str x8, [sp, #0] \n\t" \
4609 "ldr x8, [%1, #80] \n\t" \
4610 "str x8, [sp, #8] \n\t" \
4611 "ldr x8, [%1, #88] \n\t" \
4612 "str x8, [sp, #16] \n\t" \
4613 "ldr x8, [%1] \n\t" /* target->x8 */ \
4614 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4615 VALGRIND_RESTORE_STACK \
4617 : /*out*/ "=r" (_res) \
4618 : /*in*/ "0" (&_argvec[0]) \
4619 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4621 lval = (__typeof__(lval)) _res; \
4624 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
4625 arg7,arg8,arg9,arg10,arg11, \
4628 volatile OrigFn _orig = (orig); \
4629 volatile unsigned long _argvec[13]; \
4630 volatile unsigned long _res; \
4631 _argvec[0] = (unsigned long)_orig.nraddr; \
4632 _argvec[1] = (unsigned long)(arg1); \
4633 _argvec[2] = (unsigned long)(arg2); \
4634 _argvec[3] = (unsigned long)(arg3); \
4635 _argvec[4] = (unsigned long)(arg4); \
4636 _argvec[5] = (unsigned long)(arg5); \
4637 _argvec[6] = (unsigned long)(arg6); \
4638 _argvec[7] = (unsigned long)(arg7); \
4639 _argvec[8] = (unsigned long)(arg8); \
4640 _argvec[9] = (unsigned long)(arg9); \
4641 _argvec[10] = (unsigned long)(arg10); \
4642 _argvec[11] = (unsigned long)(arg11); \
4643 _argvec[12] = (unsigned long)(arg12); \
4645 VALGRIND_ALIGN_STACK \
4646 "sub sp, sp, #0x30 \n\t" \
4647 "ldr x0, [%1, #8] \n\t" \
4648 "ldr x1, [%1, #16] \n\t" \
4649 "ldr x2, [%1, #24] \n\t" \
4650 "ldr x3, [%1, #32] \n\t" \
4651 "ldr x4, [%1, #40] \n\t" \
4652 "ldr x5, [%1, #48] \n\t" \
4653 "ldr x6, [%1, #56] \n\t" \
4654 "ldr x7, [%1, #64] \n\t" \
4655 "ldr x8, [%1, #72] \n\t" \
4656 "str x8, [sp, #0] \n\t" \
4657 "ldr x8, [%1, #80] \n\t" \
4658 "str x8, [sp, #8] \n\t" \
4659 "ldr x8, [%1, #88] \n\t" \
4660 "str x8, [sp, #16] \n\t" \
4661 "ldr x8, [%1, #96] \n\t" \
4662 "str x8, [sp, #24] \n\t" \
4663 "ldr x8, [%1] \n\t" /* target->x8 */ \
4664 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \
4665 VALGRIND_RESTORE_STACK \
4667 : /*out*/ "=r" (_res) \
4668 : /*in*/ "0" (&_argvec[0]) \
4669 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \
4671 lval = (__typeof__(lval)) _res; \
4674 #endif /* PLAT_arm64_linux */
4676 /* ------------------------- s390x-linux ------------------------- */
4678 #if defined(PLAT_s390x_linux)
4680 /* Similar workaround as amd64 (see above), but we use r11 as frame
4681 pointer and save the old r11 in r7. r11 might be used for
4682 argvec, therefore we copy argvec in r1 since r1 is clobbered
4683 after the call anyway. */
4684 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
4685 # define __FRAME_POINTER \
4686 ,"d"(__builtin_dwarf_cfa())
4687 # define VALGRIND_CFI_PROLOGUE \
4688 ".cfi_remember_state\n\t" \
4689 "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \
4692 ".cfi_def_cfa r11, 0\n\t"
4693 # define VALGRIND_CFI_EPILOGUE \
4695 ".cfi_restore_state\n\t"
4697 # define __FRAME_POINTER
4698 # define VALGRIND_CFI_PROLOGUE \
4700 # define VALGRIND_CFI_EPILOGUE
4703 /* Nb: On s390 the stack pointer is properly aligned *at all times*
4704 according to the s390 GCC maintainer. (The ABI specification is not
4705 precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
4706 VALGRIND_RESTORE_STACK are not defined here. */
4708 /* These regs are trashed by the hidden call. Note that we overwrite
4709 r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
4710 function a proper return address. All others are ABI defined call
4712 #if defined(__VX__) || defined(__S390_VX__)
4713 #define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \
4714 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
4715 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
4716 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
4717 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
4719 #define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \
4720 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"
4723 /* Nb: Although r11 is modified in the asm snippets below (inside
4724 VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
4726 (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
4728 (2) GCC will complain that r11 cannot appear inside a clobber section,
4729 when compiled with -O -fno-omit-frame-pointer
4732 #define CALL_FN_W_v(lval, orig) \
4734 volatile OrigFn _orig = (orig); \
4735 volatile unsigned long _argvec[1]; \
4736 volatile unsigned long _res; \
4737 _argvec[0] = (unsigned long)_orig.nraddr; \
4739 VALGRIND_CFI_PROLOGUE \
4740 "aghi 15,-160\n\t" \
4741 "lg 1, 0(1)\n\t" /* target->r1 */ \
4742 VALGRIND_CALL_NOREDIR_R1 \
4744 VALGRIND_CFI_EPILOGUE \
4746 : /*out*/ "=d" (_res) \
4747 : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
4748 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
4750 lval = (__typeof__(lval)) _res; \
4753 /* The call abi has the arguments in r2-r6 and stack */
4754 #define CALL_FN_W_W(lval, orig, arg1) \
4756 volatile OrigFn _orig = (orig); \
4757 volatile unsigned long _argvec[2]; \
4758 volatile unsigned long _res; \
4759 _argvec[0] = (unsigned long)_orig.nraddr; \
4760 _argvec[1] = (unsigned long)arg1; \
4762 VALGRIND_CFI_PROLOGUE \
4763 "aghi 15,-160\n\t" \
4766 VALGRIND_CALL_NOREDIR_R1 \
4768 VALGRIND_CFI_EPILOGUE \
4770 : /*out*/ "=d" (_res) \
4771 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4772 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
4774 lval = (__typeof__(lval)) _res; \
4777 #define CALL_FN_W_WW(lval, orig, arg1, arg2) \
4779 volatile OrigFn _orig = (orig); \
4780 volatile unsigned long _argvec[3]; \
4781 volatile unsigned long _res; \
4782 _argvec[0] = (unsigned long)_orig.nraddr; \
4783 _argvec[1] = (unsigned long)arg1; \
4784 _argvec[2] = (unsigned long)arg2; \
4786 VALGRIND_CFI_PROLOGUE \
4787 "aghi 15,-160\n\t" \
4791 VALGRIND_CALL_NOREDIR_R1 \
4793 VALGRIND_CFI_EPILOGUE \
4795 : /*out*/ "=d" (_res) \
4796 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4797 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
4799 lval = (__typeof__(lval)) _res; \
4802 #define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \
4804 volatile OrigFn _orig = (orig); \
4805 volatile unsigned long _argvec[4]; \
4806 volatile unsigned long _res; \
4807 _argvec[0] = (unsigned long)_orig.nraddr; \
4808 _argvec[1] = (unsigned long)arg1; \
4809 _argvec[2] = (unsigned long)arg2; \
4810 _argvec[3] = (unsigned long)arg3; \
4812 VALGRIND_CFI_PROLOGUE \
4813 "aghi 15,-160\n\t" \
4818 VALGRIND_CALL_NOREDIR_R1 \
4820 VALGRIND_CFI_EPILOGUE \
4822 : /*out*/ "=d" (_res) \
4823 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4824 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
4826 lval = (__typeof__(lval)) _res; \
4829 #define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \
4831 volatile OrigFn _orig = (orig); \
4832 volatile unsigned long _argvec[5]; \
4833 volatile unsigned long _res; \
4834 _argvec[0] = (unsigned long)_orig.nraddr; \
4835 _argvec[1] = (unsigned long)arg1; \
4836 _argvec[2] = (unsigned long)arg2; \
4837 _argvec[3] = (unsigned long)arg3; \
4838 _argvec[4] = (unsigned long)arg4; \
4840 VALGRIND_CFI_PROLOGUE \
4841 "aghi 15,-160\n\t" \
4847 VALGRIND_CALL_NOREDIR_R1 \
4849 VALGRIND_CFI_EPILOGUE \
4851 : /*out*/ "=d" (_res) \
4852 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4853 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
4855 lval = (__typeof__(lval)) _res; \
4858 #define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \
4860 volatile OrigFn _orig = (orig); \
4861 volatile unsigned long _argvec[6]; \
4862 volatile unsigned long _res; \
4863 _argvec[0] = (unsigned long)_orig.nraddr; \
4864 _argvec[1] = (unsigned long)arg1; \
4865 _argvec[2] = (unsigned long)arg2; \
4866 _argvec[3] = (unsigned long)arg3; \
4867 _argvec[4] = (unsigned long)arg4; \
4868 _argvec[5] = (unsigned long)arg5; \
4870 VALGRIND_CFI_PROLOGUE \
4871 "aghi 15,-160\n\t" \
4878 VALGRIND_CALL_NOREDIR_R1 \
4880 VALGRIND_CFI_EPILOGUE \
4882 : /*out*/ "=d" (_res) \
4883 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4884 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
4886 lval = (__typeof__(lval)) _res; \
4889 #define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
4892 volatile OrigFn _orig = (orig); \
4893 volatile unsigned long _argvec[7]; \
4894 volatile unsigned long _res; \
4895 _argvec[0] = (unsigned long)_orig.nraddr; \
4896 _argvec[1] = (unsigned long)arg1; \
4897 _argvec[2] = (unsigned long)arg2; \
4898 _argvec[3] = (unsigned long)arg3; \
4899 _argvec[4] = (unsigned long)arg4; \
4900 _argvec[5] = (unsigned long)arg5; \
4901 _argvec[6] = (unsigned long)arg6; \
4903 VALGRIND_CFI_PROLOGUE \
4904 "aghi 15,-168\n\t" \
4910 "mvc 160(8,15), 48(1)\n\t" \
4912 VALGRIND_CALL_NOREDIR_R1 \
4914 VALGRIND_CFI_EPILOGUE \
4916 : /*out*/ "=d" (_res) \
4917 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4918 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
4920 lval = (__typeof__(lval)) _res; \
4923 #define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
4926 volatile OrigFn _orig = (orig); \
4927 volatile unsigned long _argvec[8]; \
4928 volatile unsigned long _res; \
4929 _argvec[0] = (unsigned long)_orig.nraddr; \
4930 _argvec[1] = (unsigned long)arg1; \
4931 _argvec[2] = (unsigned long)arg2; \
4932 _argvec[3] = (unsigned long)arg3; \
4933 _argvec[4] = (unsigned long)arg4; \
4934 _argvec[5] = (unsigned long)arg5; \
4935 _argvec[6] = (unsigned long)arg6; \
4936 _argvec[7] = (unsigned long)arg7; \
4938 VALGRIND_CFI_PROLOGUE \
4939 "aghi 15,-176\n\t" \
4945 "mvc 160(8,15), 48(1)\n\t" \
4946 "mvc 168(8,15), 56(1)\n\t" \
4948 VALGRIND_CALL_NOREDIR_R1 \
4950 VALGRIND_CFI_EPILOGUE \
4952 : /*out*/ "=d" (_res) \
4953 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4954 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
4956 lval = (__typeof__(lval)) _res; \
4959 #define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
4962 volatile OrigFn _orig = (orig); \
4963 volatile unsigned long _argvec[9]; \
4964 volatile unsigned long _res; \
4965 _argvec[0] = (unsigned long)_orig.nraddr; \
4966 _argvec[1] = (unsigned long)arg1; \
4967 _argvec[2] = (unsigned long)arg2; \
4968 _argvec[3] = (unsigned long)arg3; \
4969 _argvec[4] = (unsigned long)arg4; \
4970 _argvec[5] = (unsigned long)arg5; \
4971 _argvec[6] = (unsigned long)arg6; \
4972 _argvec[7] = (unsigned long)arg7; \
4973 _argvec[8] = (unsigned long)arg8; \
4975 VALGRIND_CFI_PROLOGUE \
4976 "aghi 15,-184\n\t" \
4982 "mvc 160(8,15), 48(1)\n\t" \
4983 "mvc 168(8,15), 56(1)\n\t" \
4984 "mvc 176(8,15), 64(1)\n\t" \
4986 VALGRIND_CALL_NOREDIR_R1 \
4988 VALGRIND_CFI_EPILOGUE \
4990 : /*out*/ "=d" (_res) \
4991 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
4992 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
4994 lval = (__typeof__(lval)) _res; \
4997 #define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
4998 arg6, arg7 ,arg8, arg9) \
5000 volatile OrigFn _orig = (orig); \
5001 volatile unsigned long _argvec[10]; \
5002 volatile unsigned long _res; \
5003 _argvec[0] = (unsigned long)_orig.nraddr; \
5004 _argvec[1] = (unsigned long)arg1; \
5005 _argvec[2] = (unsigned long)arg2; \
5006 _argvec[3] = (unsigned long)arg3; \
5007 _argvec[4] = (unsigned long)arg4; \
5008 _argvec[5] = (unsigned long)arg5; \
5009 _argvec[6] = (unsigned long)arg6; \
5010 _argvec[7] = (unsigned long)arg7; \
5011 _argvec[8] = (unsigned long)arg8; \
5012 _argvec[9] = (unsigned long)arg9; \
5014 VALGRIND_CFI_PROLOGUE \
5015 "aghi 15,-192\n\t" \
5021 "mvc 160(8,15), 48(1)\n\t" \
5022 "mvc 168(8,15), 56(1)\n\t" \
5023 "mvc 176(8,15), 64(1)\n\t" \
5024 "mvc 184(8,15), 72(1)\n\t" \
5026 VALGRIND_CALL_NOREDIR_R1 \
5028 VALGRIND_CFI_EPILOGUE \
5030 : /*out*/ "=d" (_res) \
5031 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
5032 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
5034 lval = (__typeof__(lval)) _res; \
5037 #define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
5038 arg6, arg7 ,arg8, arg9, arg10) \
5040 volatile OrigFn _orig = (orig); \
5041 volatile unsigned long _argvec[11]; \
5042 volatile unsigned long _res; \
5043 _argvec[0] = (unsigned long)_orig.nraddr; \
5044 _argvec[1] = (unsigned long)arg1; \
5045 _argvec[2] = (unsigned long)arg2; \
5046 _argvec[3] = (unsigned long)arg3; \
5047 _argvec[4] = (unsigned long)arg4; \
5048 _argvec[5] = (unsigned long)arg5; \
5049 _argvec[6] = (unsigned long)arg6; \
5050 _argvec[7] = (unsigned long)arg7; \
5051 _argvec[8] = (unsigned long)arg8; \
5052 _argvec[9] = (unsigned long)arg9; \
5053 _argvec[10] = (unsigned long)arg10; \
5055 VALGRIND_CFI_PROLOGUE \
5056 "aghi 15,-200\n\t" \
5062 "mvc 160(8,15), 48(1)\n\t" \
5063 "mvc 168(8,15), 56(1)\n\t" \
5064 "mvc 176(8,15), 64(1)\n\t" \
5065 "mvc 184(8,15), 72(1)\n\t" \
5066 "mvc 192(8,15), 80(1)\n\t" \
5068 VALGRIND_CALL_NOREDIR_R1 \
5070 VALGRIND_CFI_EPILOGUE \
5072 : /*out*/ "=d" (_res) \
5073 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
5074 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
5076 lval = (__typeof__(lval)) _res; \
5079 #define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
5080 arg6, arg7 ,arg8, arg9, arg10, arg11) \
5082 volatile OrigFn _orig = (orig); \
5083 volatile unsigned long _argvec[12]; \
5084 volatile unsigned long _res; \
5085 _argvec[0] = (unsigned long)_orig.nraddr; \
5086 _argvec[1] = (unsigned long)arg1; \
5087 _argvec[2] = (unsigned long)arg2; \
5088 _argvec[3] = (unsigned long)arg3; \
5089 _argvec[4] = (unsigned long)arg4; \
5090 _argvec[5] = (unsigned long)arg5; \
5091 _argvec[6] = (unsigned long)arg6; \
5092 _argvec[7] = (unsigned long)arg7; \
5093 _argvec[8] = (unsigned long)arg8; \
5094 _argvec[9] = (unsigned long)arg9; \
5095 _argvec[10] = (unsigned long)arg10; \
5096 _argvec[11] = (unsigned long)arg11; \
5098 VALGRIND_CFI_PROLOGUE \
5099 "aghi 15,-208\n\t" \
5105 "mvc 160(8,15), 48(1)\n\t" \
5106 "mvc 168(8,15), 56(1)\n\t" \
5107 "mvc 176(8,15), 64(1)\n\t" \
5108 "mvc 184(8,15), 72(1)\n\t" \
5109 "mvc 192(8,15), 80(1)\n\t" \
5110 "mvc 200(8,15), 88(1)\n\t" \
5112 VALGRIND_CALL_NOREDIR_R1 \
5114 VALGRIND_CFI_EPILOGUE \
5116 : /*out*/ "=d" (_res) \
5117 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
5118 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
5120 lval = (__typeof__(lval)) _res; \
5123 #define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
5124 arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
5126 volatile OrigFn _orig = (orig); \
5127 volatile unsigned long _argvec[13]; \
5128 volatile unsigned long _res; \
5129 _argvec[0] = (unsigned long)_orig.nraddr; \
5130 _argvec[1] = (unsigned long)arg1; \
5131 _argvec[2] = (unsigned long)arg2; \
5132 _argvec[3] = (unsigned long)arg3; \
5133 _argvec[4] = (unsigned long)arg4; \
5134 _argvec[5] = (unsigned long)arg5; \
5135 _argvec[6] = (unsigned long)arg6; \
5136 _argvec[7] = (unsigned long)arg7; \
5137 _argvec[8] = (unsigned long)arg8; \
5138 _argvec[9] = (unsigned long)arg9; \
5139 _argvec[10] = (unsigned long)arg10; \
5140 _argvec[11] = (unsigned long)arg11; \
5141 _argvec[12] = (unsigned long)arg12; \
5143 VALGRIND_CFI_PROLOGUE \
5144 "aghi 15,-216\n\t" \
5150 "mvc 160(8,15), 48(1)\n\t" \
5151 "mvc 168(8,15), 56(1)\n\t" \
5152 "mvc 176(8,15), 64(1)\n\t" \
5153 "mvc 184(8,15), 72(1)\n\t" \
5154 "mvc 192(8,15), 80(1)\n\t" \
5155 "mvc 200(8,15), 88(1)\n\t" \
5156 "mvc 208(8,15), 96(1)\n\t" \
5158 VALGRIND_CALL_NOREDIR_R1 \
5160 VALGRIND_CFI_EPILOGUE \
5162 : /*out*/ "=d" (_res) \
5163 : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
5164 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
5166 lval = (__typeof__(lval)) _res; \
5170 #endif /* PLAT_s390x_linux */
5172 /* ------------------------- mips32-linux ----------------------- */
5174 #if defined(PLAT_mips32_linux)
5176 /* These regs are trashed by the hidden call. */
5177 #define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \
5178 "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
5181 /* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
5184 #define CALL_FN_W_v(lval, orig) \
5186 volatile OrigFn _orig = (orig); \
5187 volatile unsigned long _argvec[1]; \
5188 volatile unsigned long _res; \
5189 _argvec[0] = (unsigned long)_orig.nraddr; \
5191 "subu $29, $29, 8 \n\t" \
5192 "sw $28, 0($29) \n\t" \
5193 "sw $31, 4($29) \n\t" \
5194 "subu $29, $29, 16 \n\t" \
5195 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5196 VALGRIND_CALL_NOREDIR_T9 \
5197 "addu $29, $29, 16\n\t" \
5198 "lw $28, 0($29) \n\t" \
5199 "lw $31, 4($29) \n\t" \
5200 "addu $29, $29, 8 \n\t" \
5202 : /*out*/ "=r" (_res) \
5203 : /*in*/ "0" (&_argvec[0]) \
5204 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5206 lval = (__typeof__(lval)) _res; \
5209 #define CALL_FN_W_W(lval, orig, arg1) \
5211 volatile OrigFn _orig = (orig); \
5212 volatile unsigned long _argvec[2]; \
5213 volatile unsigned long _res; \
5214 _argvec[0] = (unsigned long)_orig.nraddr; \
5215 _argvec[1] = (unsigned long)(arg1); \
5217 "subu $29, $29, 8 \n\t" \
5218 "sw $28, 0($29) \n\t" \
5219 "sw $31, 4($29) \n\t" \
5220 "subu $29, $29, 16 \n\t" \
5221 "lw $4, 4(%1) \n\t" /* arg1*/ \
5222 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5223 VALGRIND_CALL_NOREDIR_T9 \
5224 "addu $29, $29, 16 \n\t" \
5225 "lw $28, 0($29) \n\t" \
5226 "lw $31, 4($29) \n\t" \
5227 "addu $29, $29, 8 \n\t" \
5229 : /*out*/ "=r" (_res) \
5230 : /*in*/ "0" (&_argvec[0]) \
5231 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5233 lval = (__typeof__(lval)) _res; \
5236 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
5238 volatile OrigFn _orig = (orig); \
5239 volatile unsigned long _argvec[3]; \
5240 volatile unsigned long _res; \
5241 _argvec[0] = (unsigned long)_orig.nraddr; \
5242 _argvec[1] = (unsigned long)(arg1); \
5243 _argvec[2] = (unsigned long)(arg2); \
5245 "subu $29, $29, 8 \n\t" \
5246 "sw $28, 0($29) \n\t" \
5247 "sw $31, 4($29) \n\t" \
5248 "subu $29, $29, 16 \n\t" \
5249 "lw $4, 4(%1) \n\t" \
5250 "lw $5, 8(%1) \n\t" \
5251 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5252 VALGRIND_CALL_NOREDIR_T9 \
5253 "addu $29, $29, 16 \n\t" \
5254 "lw $28, 0($29) \n\t" \
5255 "lw $31, 4($29) \n\t" \
5256 "addu $29, $29, 8 \n\t" \
5258 : /*out*/ "=r" (_res) \
5259 : /*in*/ "0" (&_argvec[0]) \
5260 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5262 lval = (__typeof__(lval)) _res; \
5265 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
5267 volatile OrigFn _orig = (orig); \
5268 volatile unsigned long _argvec[4]; \
5269 volatile unsigned long _res; \
5270 _argvec[0] = (unsigned long)_orig.nraddr; \
5271 _argvec[1] = (unsigned long)(arg1); \
5272 _argvec[2] = (unsigned long)(arg2); \
5273 _argvec[3] = (unsigned long)(arg3); \
5275 "subu $29, $29, 8 \n\t" \
5276 "sw $28, 0($29) \n\t" \
5277 "sw $31, 4($29) \n\t" \
5278 "subu $29, $29, 16 \n\t" \
5279 "lw $4, 4(%1) \n\t" \
5280 "lw $5, 8(%1) \n\t" \
5281 "lw $6, 12(%1) \n\t" \
5282 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5283 VALGRIND_CALL_NOREDIR_T9 \
5284 "addu $29, $29, 16 \n\t" \
5285 "lw $28, 0($29) \n\t" \
5286 "lw $31, 4($29) \n\t" \
5287 "addu $29, $29, 8 \n\t" \
5289 : /*out*/ "=r" (_res) \
5290 : /*in*/ "0" (&_argvec[0]) \
5291 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5293 lval = (__typeof__(lval)) _res; \
5296 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
5298 volatile OrigFn _orig = (orig); \
5299 volatile unsigned long _argvec[5]; \
5300 volatile unsigned long _res; \
5301 _argvec[0] = (unsigned long)_orig.nraddr; \
5302 _argvec[1] = (unsigned long)(arg1); \
5303 _argvec[2] = (unsigned long)(arg2); \
5304 _argvec[3] = (unsigned long)(arg3); \
5305 _argvec[4] = (unsigned long)(arg4); \
5307 "subu $29, $29, 8 \n\t" \
5308 "sw $28, 0($29) \n\t" \
5309 "sw $31, 4($29) \n\t" \
5310 "subu $29, $29, 16 \n\t" \
5311 "lw $4, 4(%1) \n\t" \
5312 "lw $5, 8(%1) \n\t" \
5313 "lw $6, 12(%1) \n\t" \
5314 "lw $7, 16(%1) \n\t" \
5315 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5316 VALGRIND_CALL_NOREDIR_T9 \
5317 "addu $29, $29, 16 \n\t" \
5318 "lw $28, 0($29) \n\t" \
5319 "lw $31, 4($29) \n\t" \
5320 "addu $29, $29, 8 \n\t" \
5322 : /*out*/ "=r" (_res) \
5323 : /*in*/ "0" (&_argvec[0]) \
5324 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5326 lval = (__typeof__(lval)) _res; \
5329 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
5331 volatile OrigFn _orig = (orig); \
5332 volatile unsigned long _argvec[6]; \
5333 volatile unsigned long _res; \
5334 _argvec[0] = (unsigned long)_orig.nraddr; \
5335 _argvec[1] = (unsigned long)(arg1); \
5336 _argvec[2] = (unsigned long)(arg2); \
5337 _argvec[3] = (unsigned long)(arg3); \
5338 _argvec[4] = (unsigned long)(arg4); \
5339 _argvec[5] = (unsigned long)(arg5); \
5341 "subu $29, $29, 8 \n\t" \
5342 "sw $28, 0($29) \n\t" \
5343 "sw $31, 4($29) \n\t" \
5344 "lw $4, 20(%1) \n\t" \
5345 "subu $29, $29, 24\n\t" \
5346 "sw $4, 16($29) \n\t" \
5347 "lw $4, 4(%1) \n\t" \
5348 "lw $5, 8(%1) \n\t" \
5349 "lw $6, 12(%1) \n\t" \
5350 "lw $7, 16(%1) \n\t" \
5351 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5352 VALGRIND_CALL_NOREDIR_T9 \
5353 "addu $29, $29, 24 \n\t" \
5354 "lw $28, 0($29) \n\t" \
5355 "lw $31, 4($29) \n\t" \
5356 "addu $29, $29, 8 \n\t" \
5358 : /*out*/ "=r" (_res) \
5359 : /*in*/ "0" (&_argvec[0]) \
5360 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5362 lval = (__typeof__(lval)) _res; \
5364 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
5366 volatile OrigFn _orig = (orig); \
5367 volatile unsigned long _argvec[7]; \
5368 volatile unsigned long _res; \
5369 _argvec[0] = (unsigned long)_orig.nraddr; \
5370 _argvec[1] = (unsigned long)(arg1); \
5371 _argvec[2] = (unsigned long)(arg2); \
5372 _argvec[3] = (unsigned long)(arg3); \
5373 _argvec[4] = (unsigned long)(arg4); \
5374 _argvec[5] = (unsigned long)(arg5); \
5375 _argvec[6] = (unsigned long)(arg6); \
5377 "subu $29, $29, 8 \n\t" \
5378 "sw $28, 0($29) \n\t" \
5379 "sw $31, 4($29) \n\t" \
5380 "lw $4, 20(%1) \n\t" \
5381 "subu $29, $29, 32\n\t" \
5382 "sw $4, 16($29) \n\t" \
5383 "lw $4, 24(%1) \n\t" \
5385 "sw $4, 20($29) \n\t" \
5386 "lw $4, 4(%1) \n\t" \
5387 "lw $5, 8(%1) \n\t" \
5388 "lw $6, 12(%1) \n\t" \
5389 "lw $7, 16(%1) \n\t" \
5390 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5391 VALGRIND_CALL_NOREDIR_T9 \
5392 "addu $29, $29, 32 \n\t" \
5393 "lw $28, 0($29) \n\t" \
5394 "lw $31, 4($29) \n\t" \
5395 "addu $29, $29, 8 \n\t" \
5397 : /*out*/ "=r" (_res) \
5398 : /*in*/ "0" (&_argvec[0]) \
5399 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5401 lval = (__typeof__(lval)) _res; \
5404 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5407 volatile OrigFn _orig = (orig); \
5408 volatile unsigned long _argvec[8]; \
5409 volatile unsigned long _res; \
5410 _argvec[0] = (unsigned long)_orig.nraddr; \
5411 _argvec[1] = (unsigned long)(arg1); \
5412 _argvec[2] = (unsigned long)(arg2); \
5413 _argvec[3] = (unsigned long)(arg3); \
5414 _argvec[4] = (unsigned long)(arg4); \
5415 _argvec[5] = (unsigned long)(arg5); \
5416 _argvec[6] = (unsigned long)(arg6); \
5417 _argvec[7] = (unsigned long)(arg7); \
5419 "subu $29, $29, 8 \n\t" \
5420 "sw $28, 0($29) \n\t" \
5421 "sw $31, 4($29) \n\t" \
5422 "lw $4, 20(%1) \n\t" \
5423 "subu $29, $29, 32\n\t" \
5424 "sw $4, 16($29) \n\t" \
5425 "lw $4, 24(%1) \n\t" \
5426 "sw $4, 20($29) \n\t" \
5427 "lw $4, 28(%1) \n\t" \
5428 "sw $4, 24($29) \n\t" \
5429 "lw $4, 4(%1) \n\t" \
5430 "lw $5, 8(%1) \n\t" \
5431 "lw $6, 12(%1) \n\t" \
5432 "lw $7, 16(%1) \n\t" \
5433 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5434 VALGRIND_CALL_NOREDIR_T9 \
5435 "addu $29, $29, 32 \n\t" \
5436 "lw $28, 0($29) \n\t" \
5437 "lw $31, 4($29) \n\t" \
5438 "addu $29, $29, 8 \n\t" \
5440 : /*out*/ "=r" (_res) \
5441 : /*in*/ "0" (&_argvec[0]) \
5442 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5444 lval = (__typeof__(lval)) _res; \
5447 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5450 volatile OrigFn _orig = (orig); \
5451 volatile unsigned long _argvec[9]; \
5452 volatile unsigned long _res; \
5453 _argvec[0] = (unsigned long)_orig.nraddr; \
5454 _argvec[1] = (unsigned long)(arg1); \
5455 _argvec[2] = (unsigned long)(arg2); \
5456 _argvec[3] = (unsigned long)(arg3); \
5457 _argvec[4] = (unsigned long)(arg4); \
5458 _argvec[5] = (unsigned long)(arg5); \
5459 _argvec[6] = (unsigned long)(arg6); \
5460 _argvec[7] = (unsigned long)(arg7); \
5461 _argvec[8] = (unsigned long)(arg8); \
5463 "subu $29, $29, 8 \n\t" \
5464 "sw $28, 0($29) \n\t" \
5465 "sw $31, 4($29) \n\t" \
5466 "lw $4, 20(%1) \n\t" \
5467 "subu $29, $29, 40\n\t" \
5468 "sw $4, 16($29) \n\t" \
5469 "lw $4, 24(%1) \n\t" \
5470 "sw $4, 20($29) \n\t" \
5471 "lw $4, 28(%1) \n\t" \
5472 "sw $4, 24($29) \n\t" \
5473 "lw $4, 32(%1) \n\t" \
5474 "sw $4, 28($29) \n\t" \
5475 "lw $4, 4(%1) \n\t" \
5476 "lw $5, 8(%1) \n\t" \
5477 "lw $6, 12(%1) \n\t" \
5478 "lw $7, 16(%1) \n\t" \
5479 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5480 VALGRIND_CALL_NOREDIR_T9 \
5481 "addu $29, $29, 40 \n\t" \
5482 "lw $28, 0($29) \n\t" \
5483 "lw $31, 4($29) \n\t" \
5484 "addu $29, $29, 8 \n\t" \
5486 : /*out*/ "=r" (_res) \
5487 : /*in*/ "0" (&_argvec[0]) \
5488 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5490 lval = (__typeof__(lval)) _res; \
5493 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5496 volatile OrigFn _orig = (orig); \
5497 volatile unsigned long _argvec[10]; \
5498 volatile unsigned long _res; \
5499 _argvec[0] = (unsigned long)_orig.nraddr; \
5500 _argvec[1] = (unsigned long)(arg1); \
5501 _argvec[2] = (unsigned long)(arg2); \
5502 _argvec[3] = (unsigned long)(arg3); \
5503 _argvec[4] = (unsigned long)(arg4); \
5504 _argvec[5] = (unsigned long)(arg5); \
5505 _argvec[6] = (unsigned long)(arg6); \
5506 _argvec[7] = (unsigned long)(arg7); \
5507 _argvec[8] = (unsigned long)(arg8); \
5508 _argvec[9] = (unsigned long)(arg9); \
5510 "subu $29, $29, 8 \n\t" \
5511 "sw $28, 0($29) \n\t" \
5512 "sw $31, 4($29) \n\t" \
5513 "lw $4, 20(%1) \n\t" \
5514 "subu $29, $29, 40\n\t" \
5515 "sw $4, 16($29) \n\t" \
5516 "lw $4, 24(%1) \n\t" \
5517 "sw $4, 20($29) \n\t" \
5518 "lw $4, 28(%1) \n\t" \
5519 "sw $4, 24($29) \n\t" \
5520 "lw $4, 32(%1) \n\t" \
5521 "sw $4, 28($29) \n\t" \
5522 "lw $4, 36(%1) \n\t" \
5523 "sw $4, 32($29) \n\t" \
5524 "lw $4, 4(%1) \n\t" \
5525 "lw $5, 8(%1) \n\t" \
5526 "lw $6, 12(%1) \n\t" \
5527 "lw $7, 16(%1) \n\t" \
5528 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5529 VALGRIND_CALL_NOREDIR_T9 \
5530 "addu $29, $29, 40 \n\t" \
5531 "lw $28, 0($29) \n\t" \
5532 "lw $31, 4($29) \n\t" \
5533 "addu $29, $29, 8 \n\t" \
5535 : /*out*/ "=r" (_res) \
5536 : /*in*/ "0" (&_argvec[0]) \
5537 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5539 lval = (__typeof__(lval)) _res; \
5542 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5543 arg7,arg8,arg9,arg10) \
5545 volatile OrigFn _orig = (orig); \
5546 volatile unsigned long _argvec[11]; \
5547 volatile unsigned long _res; \
5548 _argvec[0] = (unsigned long)_orig.nraddr; \
5549 _argvec[1] = (unsigned long)(arg1); \
5550 _argvec[2] = (unsigned long)(arg2); \
5551 _argvec[3] = (unsigned long)(arg3); \
5552 _argvec[4] = (unsigned long)(arg4); \
5553 _argvec[5] = (unsigned long)(arg5); \
5554 _argvec[6] = (unsigned long)(arg6); \
5555 _argvec[7] = (unsigned long)(arg7); \
5556 _argvec[8] = (unsigned long)(arg8); \
5557 _argvec[9] = (unsigned long)(arg9); \
5558 _argvec[10] = (unsigned long)(arg10); \
5560 "subu $29, $29, 8 \n\t" \
5561 "sw $28, 0($29) \n\t" \
5562 "sw $31, 4($29) \n\t" \
5563 "lw $4, 20(%1) \n\t" \
5564 "subu $29, $29, 48\n\t" \
5565 "sw $4, 16($29) \n\t" \
5566 "lw $4, 24(%1) \n\t" \
5567 "sw $4, 20($29) \n\t" \
5568 "lw $4, 28(%1) \n\t" \
5569 "sw $4, 24($29) \n\t" \
5570 "lw $4, 32(%1) \n\t" \
5571 "sw $4, 28($29) \n\t" \
5572 "lw $4, 36(%1) \n\t" \
5573 "sw $4, 32($29) \n\t" \
5574 "lw $4, 40(%1) \n\t" \
5575 "sw $4, 36($29) \n\t" \
5576 "lw $4, 4(%1) \n\t" \
5577 "lw $5, 8(%1) \n\t" \
5578 "lw $6, 12(%1) \n\t" \
5579 "lw $7, 16(%1) \n\t" \
5580 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5581 VALGRIND_CALL_NOREDIR_T9 \
5582 "addu $29, $29, 48 \n\t" \
5583 "lw $28, 0($29) \n\t" \
5584 "lw $31, 4($29) \n\t" \
5585 "addu $29, $29, 8 \n\t" \
5587 : /*out*/ "=r" (_res) \
5588 : /*in*/ "0" (&_argvec[0]) \
5589 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5591 lval = (__typeof__(lval)) _res; \
5594 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
5595 arg6,arg7,arg8,arg9,arg10, \
5598 volatile OrigFn _orig = (orig); \
5599 volatile unsigned long _argvec[12]; \
5600 volatile unsigned long _res; \
5601 _argvec[0] = (unsigned long)_orig.nraddr; \
5602 _argvec[1] = (unsigned long)(arg1); \
5603 _argvec[2] = (unsigned long)(arg2); \
5604 _argvec[3] = (unsigned long)(arg3); \
5605 _argvec[4] = (unsigned long)(arg4); \
5606 _argvec[5] = (unsigned long)(arg5); \
5607 _argvec[6] = (unsigned long)(arg6); \
5608 _argvec[7] = (unsigned long)(arg7); \
5609 _argvec[8] = (unsigned long)(arg8); \
5610 _argvec[9] = (unsigned long)(arg9); \
5611 _argvec[10] = (unsigned long)(arg10); \
5612 _argvec[11] = (unsigned long)(arg11); \
5614 "subu $29, $29, 8 \n\t" \
5615 "sw $28, 0($29) \n\t" \
5616 "sw $31, 4($29) \n\t" \
5617 "lw $4, 20(%1) \n\t" \
5618 "subu $29, $29, 48\n\t" \
5619 "sw $4, 16($29) \n\t" \
5620 "lw $4, 24(%1) \n\t" \
5621 "sw $4, 20($29) \n\t" \
5622 "lw $4, 28(%1) \n\t" \
5623 "sw $4, 24($29) \n\t" \
5624 "lw $4, 32(%1) \n\t" \
5625 "sw $4, 28($29) \n\t" \
5626 "lw $4, 36(%1) \n\t" \
5627 "sw $4, 32($29) \n\t" \
5628 "lw $4, 40(%1) \n\t" \
5629 "sw $4, 36($29) \n\t" \
5630 "lw $4, 44(%1) \n\t" \
5631 "sw $4, 40($29) \n\t" \
5632 "lw $4, 4(%1) \n\t" \
5633 "lw $5, 8(%1) \n\t" \
5634 "lw $6, 12(%1) \n\t" \
5635 "lw $7, 16(%1) \n\t" \
5636 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5637 VALGRIND_CALL_NOREDIR_T9 \
5638 "addu $29, $29, 48 \n\t" \
5639 "lw $28, 0($29) \n\t" \
5640 "lw $31, 4($29) \n\t" \
5641 "addu $29, $29, 8 \n\t" \
5643 : /*out*/ "=r" (_res) \
5644 : /*in*/ "0" (&_argvec[0]) \
5645 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5647 lval = (__typeof__(lval)) _res; \
5650 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
5651 arg6,arg7,arg8,arg9,arg10, \
5654 volatile OrigFn _orig = (orig); \
5655 volatile unsigned long _argvec[13]; \
5656 volatile unsigned long _res; \
5657 _argvec[0] = (unsigned long)_orig.nraddr; \
5658 _argvec[1] = (unsigned long)(arg1); \
5659 _argvec[2] = (unsigned long)(arg2); \
5660 _argvec[3] = (unsigned long)(arg3); \
5661 _argvec[4] = (unsigned long)(arg4); \
5662 _argvec[5] = (unsigned long)(arg5); \
5663 _argvec[6] = (unsigned long)(arg6); \
5664 _argvec[7] = (unsigned long)(arg7); \
5665 _argvec[8] = (unsigned long)(arg8); \
5666 _argvec[9] = (unsigned long)(arg9); \
5667 _argvec[10] = (unsigned long)(arg10); \
5668 _argvec[11] = (unsigned long)(arg11); \
5669 _argvec[12] = (unsigned long)(arg12); \
5671 "subu $29, $29, 8 \n\t" \
5672 "sw $28, 0($29) \n\t" \
5673 "sw $31, 4($29) \n\t" \
5674 "lw $4, 20(%1) \n\t" \
5675 "subu $29, $29, 56\n\t" \
5676 "sw $4, 16($29) \n\t" \
5677 "lw $4, 24(%1) \n\t" \
5678 "sw $4, 20($29) \n\t" \
5679 "lw $4, 28(%1) \n\t" \
5680 "sw $4, 24($29) \n\t" \
5681 "lw $4, 32(%1) \n\t" \
5682 "sw $4, 28($29) \n\t" \
5683 "lw $4, 36(%1) \n\t" \
5684 "sw $4, 32($29) \n\t" \
5685 "lw $4, 40(%1) \n\t" \
5686 "sw $4, 36($29) \n\t" \
5687 "lw $4, 44(%1) \n\t" \
5688 "sw $4, 40($29) \n\t" \
5689 "lw $4, 48(%1) \n\t" \
5690 "sw $4, 44($29) \n\t" \
5691 "lw $4, 4(%1) \n\t" \
5692 "lw $5, 8(%1) \n\t" \
5693 "lw $6, 12(%1) \n\t" \
5694 "lw $7, 16(%1) \n\t" \
5695 "lw $25, 0(%1) \n\t" /* target->t9 */ \
5696 VALGRIND_CALL_NOREDIR_T9 \
5697 "addu $29, $29, 56 \n\t" \
5698 "lw $28, 0($29) \n\t" \
5699 "lw $31, 4($29) \n\t" \
5700 "addu $29, $29, 8 \n\t" \
5702 : /*out*/ "=r" (_res) \
5703 : /*in*/ "r" (&_argvec[0]) \
5704 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5706 lval = (__typeof__(lval)) _res; \
5709 #endif /* PLAT_mips32_linux */
5711 /* ------------------------- nanomips-linux -------------------- */
5713 #if defined(PLAT_nanomips_linux)
5715 /* These regs are trashed by the hidden call. */
5716 #define __CALLER_SAVED_REGS "$t4", "$t5", "$a0", "$a1", "$a2", \
5717 "$a3", "$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3", \
5720 /* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
5723 #define CALL_FN_W_v(lval, orig) \
5725 volatile OrigFn _orig = (orig); \
5726 volatile unsigned long _argvec[1]; \
5727 volatile unsigned long _res; \
5728 _argvec[0] = (unsigned long)_orig.nraddr; \
5730 "lw $t9, 0(%1)\n\t" \
5731 VALGRIND_CALL_NOREDIR_T9 \
5733 : /*out*/ "=r" (_res) \
5734 : /*in*/ "r" (&_argvec[0]) \
5735 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5737 lval = (__typeof__(lval)) _res; \
5740 #define CALL_FN_W_W(lval, orig, arg1) \
5742 volatile OrigFn _orig = (orig); \
5743 volatile unsigned long _argvec[2]; \
5744 volatile unsigned long _res; \
5745 _argvec[0] = (unsigned long)_orig.nraddr; \
5746 _argvec[1] = (unsigned long)(arg1); \
5748 "lw $t9, 0(%1)\n\t" \
5749 "lw $a0, 4(%1)\n\t" \
5750 VALGRIND_CALL_NOREDIR_T9 \
5752 : /*out*/ "=r" (_res) \
5753 : /*in*/ "r" (&_argvec[0]) \
5754 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5756 lval = (__typeof__(lval)) _res; \
5759 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
5761 volatile OrigFn _orig = (orig); \
5762 volatile unsigned long _argvec[3]; \
5763 volatile unsigned long _res; \
5764 _argvec[0] = (unsigned long)_orig.nraddr; \
5765 _argvec[1] = (unsigned long)(arg1); \
5766 _argvec[2] = (unsigned long)(arg2); \
5768 "lw $t9, 0(%1)\n\t" \
5769 "lw $a0, 4(%1)\n\t" \
5770 "lw $a1, 8(%1)\n\t" \
5771 VALGRIND_CALL_NOREDIR_T9 \
5773 : /*out*/ "=r" (_res) \
5774 : /*in*/ "r" (&_argvec[0]) \
5775 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5777 lval = (__typeof__(lval)) _res; \
5780 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
5782 volatile OrigFn _orig = (orig); \
5783 volatile unsigned long _argvec[4]; \
5784 volatile unsigned long _res; \
5785 _argvec[0] = (unsigned long)_orig.nraddr; \
5786 _argvec[1] = (unsigned long)(arg1); \
5787 _argvec[2] = (unsigned long)(arg2); \
5788 _argvec[3] = (unsigned long)(arg3); \
5790 "lw $t9, 0(%1)\n\t" \
5791 "lw $a0, 4(%1)\n\t" \
5792 "lw $a1, 8(%1)\n\t" \
5793 "lw $a2,12(%1)\n\t" \
5794 VALGRIND_CALL_NOREDIR_T9 \
5796 : /*out*/ "=r" (_res) \
5797 : /*in*/ "r" (&_argvec[0]) \
5798 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5800 lval = (__typeof__(lval)) _res; \
5803 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
5805 volatile OrigFn _orig = (orig); \
5806 volatile unsigned long _argvec[5]; \
5807 volatile unsigned long _res; \
5808 _argvec[0] = (unsigned long)_orig.nraddr; \
5809 _argvec[1] = (unsigned long)(arg1); \
5810 _argvec[2] = (unsigned long)(arg2); \
5811 _argvec[3] = (unsigned long)(arg3); \
5812 _argvec[4] = (unsigned long)(arg4); \
5814 "lw $t9, 0(%1)\n\t" \
5815 "lw $a0, 4(%1)\n\t" \
5816 "lw $a1, 8(%1)\n\t" \
5817 "lw $a2,12(%1)\n\t" \
5818 "lw $a3,16(%1)\n\t" \
5819 VALGRIND_CALL_NOREDIR_T9 \
5821 : /*out*/ "=r" (_res) \
5822 : /*in*/ "r" (&_argvec[0]) \
5823 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5825 lval = (__typeof__(lval)) _res; \
5828 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
5830 volatile OrigFn _orig = (orig); \
5831 volatile unsigned long _argvec[6]; \
5832 volatile unsigned long _res; \
5833 _argvec[0] = (unsigned long)_orig.nraddr; \
5834 _argvec[1] = (unsigned long)(arg1); \
5835 _argvec[2] = (unsigned long)(arg2); \
5836 _argvec[3] = (unsigned long)(arg3); \
5837 _argvec[4] = (unsigned long)(arg4); \
5838 _argvec[5] = (unsigned long)(arg5); \
5840 "lw $t9, 0(%1)\n\t" \
5841 "lw $a0, 4(%1)\n\t" \
5842 "lw $a1, 8(%1)\n\t" \
5843 "lw $a2,12(%1)\n\t" \
5844 "lw $a3,16(%1)\n\t" \
5845 "lw $a4,20(%1)\n\t" \
5846 VALGRIND_CALL_NOREDIR_T9 \
5848 : /*out*/ "=r" (_res) \
5849 : /*in*/ "r" (&_argvec[0]) \
5850 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5852 lval = (__typeof__(lval)) _res; \
5854 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
5856 volatile OrigFn _orig = (orig); \
5857 volatile unsigned long _argvec[7]; \
5858 volatile unsigned long _res; \
5859 _argvec[0] = (unsigned long)_orig.nraddr; \
5860 _argvec[1] = (unsigned long)(arg1); \
5861 _argvec[2] = (unsigned long)(arg2); \
5862 _argvec[3] = (unsigned long)(arg3); \
5863 _argvec[4] = (unsigned long)(arg4); \
5864 _argvec[5] = (unsigned long)(arg5); \
5865 _argvec[6] = (unsigned long)(arg6); \
5867 "lw $t9, 0(%1)\n\t" \
5868 "lw $a0, 4(%1)\n\t" \
5869 "lw $a1, 8(%1)\n\t" \
5870 "lw $a2,12(%1)\n\t" \
5871 "lw $a3,16(%1)\n\t" \
5872 "lw $a4,20(%1)\n\t" \
5873 "lw $a5,24(%1)\n\t" \
5874 VALGRIND_CALL_NOREDIR_T9 \
5876 : /*out*/ "=r" (_res) \
5877 : /*in*/ "r" (&_argvec[0]) \
5878 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5880 lval = (__typeof__(lval)) _res; \
5883 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5886 volatile OrigFn _orig = (orig); \
5887 volatile unsigned long _argvec[8]; \
5888 volatile unsigned long _res; \
5889 _argvec[0] = (unsigned long)_orig.nraddr; \
5890 _argvec[1] = (unsigned long)(arg1); \
5891 _argvec[2] = (unsigned long)(arg2); \
5892 _argvec[3] = (unsigned long)(arg3); \
5893 _argvec[4] = (unsigned long)(arg4); \
5894 _argvec[5] = (unsigned long)(arg5); \
5895 _argvec[6] = (unsigned long)(arg6); \
5896 _argvec[7] = (unsigned long)(arg7); \
5898 "lw $t9, 0(%1)\n\t" \
5899 "lw $a0, 4(%1)\n\t" \
5900 "lw $a1, 8(%1)\n\t" \
5901 "lw $a2,12(%1)\n\t" \
5902 "lw $a3,16(%1)\n\t" \
5903 "lw $a4,20(%1)\n\t" \
5904 "lw $a5,24(%1)\n\t" \
5905 "lw $a6,28(%1)\n\t" \
5906 VALGRIND_CALL_NOREDIR_T9 \
5908 : /*out*/ "=r" (_res) \
5909 : /*in*/ "r" (&_argvec[0]) \
5910 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5912 lval = (__typeof__(lval)) _res; \
5915 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5918 volatile OrigFn _orig = (orig); \
5919 volatile unsigned long _argvec[9]; \
5920 volatile unsigned long _res; \
5921 _argvec[0] = (unsigned long)_orig.nraddr; \
5922 _argvec[1] = (unsigned long)(arg1); \
5923 _argvec[2] = (unsigned long)(arg2); \
5924 _argvec[3] = (unsigned long)(arg3); \
5925 _argvec[4] = (unsigned long)(arg4); \
5926 _argvec[5] = (unsigned long)(arg5); \
5927 _argvec[6] = (unsigned long)(arg6); \
5928 _argvec[7] = (unsigned long)(arg7); \
5929 _argvec[8] = (unsigned long)(arg8); \
5931 "lw $t9, 0(%1)\n\t" \
5932 "lw $a0, 4(%1)\n\t" \
5933 "lw $a1, 8(%1)\n\t" \
5934 "lw $a2,12(%1)\n\t" \
5935 "lw $a3,16(%1)\n\t" \
5936 "lw $a4,20(%1)\n\t" \
5937 "lw $a5,24(%1)\n\t" \
5938 "lw $a6,28(%1)\n\t" \
5939 "lw $a7,32(%1)\n\t" \
5940 VALGRIND_CALL_NOREDIR_T9 \
5942 : /*out*/ "=r" (_res) \
5943 : /*in*/ "r" (&_argvec[0]) \
5944 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5946 lval = (__typeof__(lval)) _res; \
5949 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5952 volatile OrigFn _orig = (orig); \
5953 volatile unsigned long _argvec[10]; \
5954 volatile unsigned long _res; \
5955 _argvec[0] = (unsigned long)_orig.nraddr; \
5956 _argvec[1] = (unsigned long)(arg1); \
5957 _argvec[2] = (unsigned long)(arg2); \
5958 _argvec[3] = (unsigned long)(arg3); \
5959 _argvec[4] = (unsigned long)(arg4); \
5960 _argvec[5] = (unsigned long)(arg5); \
5961 _argvec[6] = (unsigned long)(arg6); \
5962 _argvec[7] = (unsigned long)(arg7); \
5963 _argvec[8] = (unsigned long)(arg8); \
5964 _argvec[9] = (unsigned long)(arg9); \
5966 "addiu $sp, $sp, -16 \n\t" \
5967 "lw $t9,36(%1) \n\t" \
5968 "sw $t9, 0($sp) \n\t" \
5969 "lw $t9, 0(%1) \n\t" \
5970 "lw $a0, 4(%1) \n\t" \
5971 "lw $a1, 8(%1) \n\t" \
5972 "lw $a2,12(%1) \n\t" \
5973 "lw $a3,16(%1) \n\t" \
5974 "lw $a4,20(%1) \n\t" \
5975 "lw $a5,24(%1) \n\t" \
5976 "lw $a6,28(%1) \n\t" \
5977 "lw $a7,32(%1) \n\t" \
5978 VALGRIND_CALL_NOREDIR_T9 \
5979 "move %0, $a0 \n\t" \
5980 "addiu $sp, $sp, 16 \n\t" \
5981 : /*out*/ "=r" (_res) \
5982 : /*in*/ "r" (&_argvec[0]) \
5983 : /*trash*/ "memory", __CALLER_SAVED_REGS \
5985 lval = (__typeof__(lval)) _res; \
5988 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
5989 arg7,arg8,arg9,arg10) \
5991 volatile OrigFn _orig = (orig); \
5992 volatile unsigned long _argvec[11]; \
5993 volatile unsigned long _res; \
5994 _argvec[0] = (unsigned long)_orig.nraddr; \
5995 _argvec[1] = (unsigned long)(arg1); \
5996 _argvec[2] = (unsigned long)(arg2); \
5997 _argvec[3] = (unsigned long)(arg3); \
5998 _argvec[4] = (unsigned long)(arg4); \
5999 _argvec[5] = (unsigned long)(arg5); \
6000 _argvec[6] = (unsigned long)(arg6); \
6001 _argvec[7] = (unsigned long)(arg7); \
6002 _argvec[8] = (unsigned long)(arg8); \
6003 _argvec[9] = (unsigned long)(arg9); \
6004 _argvec[10] = (unsigned long)(arg10); \
6006 "addiu $sp, $sp, -16 \n\t" \
6007 "lw $t9,36(%1) \n\t" \
6008 "sw $t9, 0($sp) \n\t" \
6009 "lw $t9,40(%1) \n\t" \
6010 "sw $t9, 4($sp) \n\t" \
6011 "lw $t9, 0(%1) \n\t" \
6012 "lw $a0, 4(%1) \n\t" \
6013 "lw $a1, 8(%1) \n\t" \
6014 "lw $a2,12(%1) \n\t" \
6015 "lw $a3,16(%1) \n\t" \
6016 "lw $a4,20(%1) \n\t" \
6017 "lw $a5,24(%1) \n\t" \
6018 "lw $a6,28(%1) \n\t" \
6019 "lw $a7,32(%1) \n\t" \
6020 VALGRIND_CALL_NOREDIR_T9 \
6021 "move %0, $a0 \n\t" \
6022 "addiu $sp, $sp, 16 \n\t" \
6023 : /*out*/ "=r" (_res) \
6024 : /*in*/ "r" (&_argvec[0]) \
6025 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6027 lval = (__typeof__(lval)) _res; \
6030 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
6031 arg6,arg7,arg8,arg9,arg10, \
6034 volatile OrigFn _orig = (orig); \
6035 volatile unsigned long _argvec[12]; \
6036 volatile unsigned long _res; \
6037 _argvec[0] = (unsigned long)_orig.nraddr; \
6038 _argvec[1] = (unsigned long)(arg1); \
6039 _argvec[2] = (unsigned long)(arg2); \
6040 _argvec[3] = (unsigned long)(arg3); \
6041 _argvec[4] = (unsigned long)(arg4); \
6042 _argvec[5] = (unsigned long)(arg5); \
6043 _argvec[6] = (unsigned long)(arg6); \
6044 _argvec[7] = (unsigned long)(arg7); \
6045 _argvec[8] = (unsigned long)(arg8); \
6046 _argvec[9] = (unsigned long)(arg9); \
6047 _argvec[10] = (unsigned long)(arg10); \
6048 _argvec[11] = (unsigned long)(arg11); \
6050 "addiu $sp, $sp, -16 \n\t" \
6051 "lw $t9,36(%1) \n\t" \
6052 "sw $t9, 0($sp) \n\t" \
6053 "lw $t9,40(%1) \n\t" \
6054 "sw $t9, 4($sp) \n\t" \
6055 "lw $t9,44(%1) \n\t" \
6056 "sw $t9, 8($sp) \n\t" \
6057 "lw $t9, 0(%1) \n\t" \
6058 "lw $a0, 4(%1) \n\t" \
6059 "lw $a1, 8(%1) \n\t" \
6060 "lw $a2,12(%1) \n\t" \
6061 "lw $a3,16(%1) \n\t" \
6062 "lw $a4,20(%1) \n\t" \
6063 "lw $a5,24(%1) \n\t" \
6064 "lw $a6,28(%1) \n\t" \
6065 "lw $a7,32(%1) \n\t" \
6066 VALGRIND_CALL_NOREDIR_T9 \
6067 "move %0, $a0 \n\t" \
6068 "addiu $sp, $sp, 16 \n\t" \
6069 : /*out*/ "=r" (_res) \
6070 : /*in*/ "r" (&_argvec[0]) \
6071 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6073 lval = (__typeof__(lval)) _res; \
6076 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
6077 arg6,arg7,arg8,arg9,arg10, \
6080 volatile OrigFn _orig = (orig); \
6081 volatile unsigned long _argvec[13]; \
6082 volatile unsigned long _res; \
6083 _argvec[0] = (unsigned long)_orig.nraddr; \
6084 _argvec[1] = (unsigned long)(arg1); \
6085 _argvec[2] = (unsigned long)(arg2); \
6086 _argvec[3] = (unsigned long)(arg3); \
6087 _argvec[4] = (unsigned long)(arg4); \
6088 _argvec[5] = (unsigned long)(arg5); \
6089 _argvec[6] = (unsigned long)(arg6); \
6090 _argvec[7] = (unsigned long)(arg7); \
6091 _argvec[8] = (unsigned long)(arg8); \
6092 _argvec[9] = (unsigned long)(arg9); \
6093 _argvec[10] = (unsigned long)(arg10); \
6094 _argvec[11] = (unsigned long)(arg11); \
6095 _argvec[12] = (unsigned long)(arg12); \
6097 "addiu $sp, $sp, -16 \n\t" \
6098 "lw $t9,36(%1) \n\t" \
6099 "sw $t9, 0($sp) \n\t" \
6100 "lw $t9,40(%1) \n\t" \
6101 "sw $t9, 4($sp) \n\t" \
6102 "lw $t9,44(%1) \n\t" \
6103 "sw $t9, 8($sp) \n\t" \
6104 "lw $t9,48(%1) \n\t" \
6105 "sw $t9,12($sp) \n\t" \
6106 "lw $t9, 0(%1) \n\t" \
6107 "lw $a0, 4(%1) \n\t" \
6108 "lw $a1, 8(%1) \n\t" \
6109 "lw $a2,12(%1) \n\t" \
6110 "lw $a3,16(%1) \n\t" \
6111 "lw $a4,20(%1) \n\t" \
6112 "lw $a5,24(%1) \n\t" \
6113 "lw $a6,28(%1) \n\t" \
6114 "lw $a7,32(%1) \n\t" \
6115 VALGRIND_CALL_NOREDIR_T9 \
6116 "move %0, $a0 \n\t" \
6117 "addiu $sp, $sp, 16 \n\t" \
6118 : /*out*/ "=r" (_res) \
6119 : /*in*/ "r" (&_argvec[0]) \
6120 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6122 lval = (__typeof__(lval)) _res; \
6125 #endif /* PLAT_nanomips_linux */
6127 /* ------------------------- mips64-linux ------------------------- */
6129 #if defined(PLAT_mips64_linux)
6131 /* These regs are trashed by the hidden call. */
6132 #define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \
6133 "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
6136 /* These CALL_FN_ macros assume that on mips64-linux,
6137 sizeof(long long) == 8. */
6139 #define MIPS64_LONG2REG_CAST(x) ((long long)(long)x)
6141 #define CALL_FN_W_v(lval, orig) \
6143 volatile OrigFn _orig = (orig); \
6144 volatile unsigned long long _argvec[1]; \
6145 volatile unsigned long long _res; \
6146 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6148 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6149 VALGRIND_CALL_NOREDIR_T9 \
6151 : /*out*/ "=r" (_res) \
6152 : /*in*/ "0" (&_argvec[0]) \
6153 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6155 lval = (__typeof__(lval)) (long)_res; \
6158 #define CALL_FN_W_W(lval, orig, arg1) \
6160 volatile OrigFn _orig = (orig); \
6161 volatile unsigned long long _argvec[2]; \
6162 volatile unsigned long long _res; \
6163 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6164 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6166 "ld $4, 8(%1)\n\t" /* arg1*/ \
6167 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6168 VALGRIND_CALL_NOREDIR_T9 \
6170 : /*out*/ "=r" (_res) \
6171 : /*in*/ "r" (&_argvec[0]) \
6172 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6174 lval = (__typeof__(lval)) (long)_res; \
6177 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
6179 volatile OrigFn _orig = (orig); \
6180 volatile unsigned long long _argvec[3]; \
6181 volatile unsigned long long _res; \
6182 _argvec[0] = _orig.nraddr; \
6183 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6184 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6186 "ld $4, 8(%1)\n\t" \
6187 "ld $5, 16(%1)\n\t" \
6188 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6189 VALGRIND_CALL_NOREDIR_T9 \
6191 : /*out*/ "=r" (_res) \
6192 : /*in*/ "r" (&_argvec[0]) \
6193 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6195 lval = (__typeof__(lval)) (long)_res; \
6199 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
6201 volatile OrigFn _orig = (orig); \
6202 volatile unsigned long long _argvec[4]; \
6203 volatile unsigned long long _res; \
6204 _argvec[0] = _orig.nraddr; \
6205 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6206 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6207 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6209 "ld $4, 8(%1)\n\t" \
6210 "ld $5, 16(%1)\n\t" \
6211 "ld $6, 24(%1)\n\t" \
6212 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6213 VALGRIND_CALL_NOREDIR_T9 \
6215 : /*out*/ "=r" (_res) \
6216 : /*in*/ "r" (&_argvec[0]) \
6217 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6219 lval = (__typeof__(lval)) (long)_res; \
6222 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
6224 volatile OrigFn _orig = (orig); \
6225 volatile unsigned long long _argvec[5]; \
6226 volatile unsigned long long _res; \
6227 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6228 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6229 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6230 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6231 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6233 "ld $4, 8(%1)\n\t" \
6234 "ld $5, 16(%1)\n\t" \
6235 "ld $6, 24(%1)\n\t" \
6236 "ld $7, 32(%1)\n\t" \
6237 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6238 VALGRIND_CALL_NOREDIR_T9 \
6240 : /*out*/ "=r" (_res) \
6241 : /*in*/ "r" (&_argvec[0]) \
6242 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6244 lval = (__typeof__(lval)) (long)_res; \
6247 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
6249 volatile OrigFn _orig = (orig); \
6250 volatile unsigned long long _argvec[6]; \
6251 volatile unsigned long long _res; \
6252 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6253 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6254 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6255 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6256 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6257 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6259 "ld $4, 8(%1)\n\t" \
6260 "ld $5, 16(%1)\n\t" \
6261 "ld $6, 24(%1)\n\t" \
6262 "ld $7, 32(%1)\n\t" \
6263 "ld $8, 40(%1)\n\t" \
6264 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6265 VALGRIND_CALL_NOREDIR_T9 \
6267 : /*out*/ "=r" (_res) \
6268 : /*in*/ "r" (&_argvec[0]) \
6269 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6271 lval = (__typeof__(lval)) (long)_res; \
6274 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
6276 volatile OrigFn _orig = (orig); \
6277 volatile unsigned long long _argvec[7]; \
6278 volatile unsigned long long _res; \
6279 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6280 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6281 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6282 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6283 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6284 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6285 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6287 "ld $4, 8(%1)\n\t" \
6288 "ld $5, 16(%1)\n\t" \
6289 "ld $6, 24(%1)\n\t" \
6290 "ld $7, 32(%1)\n\t" \
6291 "ld $8, 40(%1)\n\t" \
6292 "ld $9, 48(%1)\n\t" \
6293 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6294 VALGRIND_CALL_NOREDIR_T9 \
6296 : /*out*/ "=r" (_res) \
6297 : /*in*/ "r" (&_argvec[0]) \
6298 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6300 lval = (__typeof__(lval)) (long)_res; \
6303 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
6306 volatile OrigFn _orig = (orig); \
6307 volatile unsigned long long _argvec[8]; \
6308 volatile unsigned long long _res; \
6309 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6310 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6311 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6312 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6313 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6314 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6315 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6316 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6318 "ld $4, 8(%1)\n\t" \
6319 "ld $5, 16(%1)\n\t" \
6320 "ld $6, 24(%1)\n\t" \
6321 "ld $7, 32(%1)\n\t" \
6322 "ld $8, 40(%1)\n\t" \
6323 "ld $9, 48(%1)\n\t" \
6324 "ld $10, 56(%1)\n\t" \
6325 "ld $25, 0(%1) \n\t" /* target->t9 */ \
6326 VALGRIND_CALL_NOREDIR_T9 \
6328 : /*out*/ "=r" (_res) \
6329 : /*in*/ "r" (&_argvec[0]) \
6330 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6332 lval = (__typeof__(lval)) (long)_res; \
6335 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
6338 volatile OrigFn _orig = (orig); \
6339 volatile unsigned long long _argvec[9]; \
6340 volatile unsigned long long _res; \
6341 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6342 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6343 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6344 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6345 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6346 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6347 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6348 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6349 _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
6351 "ld $4, 8(%1)\n\t" \
6352 "ld $5, 16(%1)\n\t" \
6353 "ld $6, 24(%1)\n\t" \
6354 "ld $7, 32(%1)\n\t" \
6355 "ld $8, 40(%1)\n\t" \
6356 "ld $9, 48(%1)\n\t" \
6357 "ld $10, 56(%1)\n\t" \
6358 "ld $11, 64(%1)\n\t" \
6359 "ld $25, 0(%1) \n\t" /* target->t9 */ \
6360 VALGRIND_CALL_NOREDIR_T9 \
6362 : /*out*/ "=r" (_res) \
6363 : /*in*/ "r" (&_argvec[0]) \
6364 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6366 lval = (__typeof__(lval)) (long)_res; \
6369 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
6372 volatile OrigFn _orig = (orig); \
6373 volatile unsigned long long _argvec[10]; \
6374 volatile unsigned long long _res; \
6375 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6376 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6377 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6378 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6379 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6380 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6381 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6382 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6383 _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
6384 _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
6386 "dsubu $29, $29, 8\n\t" \
6387 "ld $4, 72(%1)\n\t" \
6388 "sd $4, 0($29)\n\t" \
6389 "ld $4, 8(%1)\n\t" \
6390 "ld $5, 16(%1)\n\t" \
6391 "ld $6, 24(%1)\n\t" \
6392 "ld $7, 32(%1)\n\t" \
6393 "ld $8, 40(%1)\n\t" \
6394 "ld $9, 48(%1)\n\t" \
6395 "ld $10, 56(%1)\n\t" \
6396 "ld $11, 64(%1)\n\t" \
6397 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6398 VALGRIND_CALL_NOREDIR_T9 \
6399 "daddu $29, $29, 8\n\t" \
6401 : /*out*/ "=r" (_res) \
6402 : /*in*/ "r" (&_argvec[0]) \
6403 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6405 lval = (__typeof__(lval)) (long)_res; \
6408 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
6409 arg7,arg8,arg9,arg10) \
6411 volatile OrigFn _orig = (orig); \
6412 volatile unsigned long long _argvec[11]; \
6413 volatile unsigned long long _res; \
6414 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6415 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6416 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6417 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6418 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6419 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6420 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6421 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6422 _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
6423 _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
6424 _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
6426 "dsubu $29, $29, 16\n\t" \
6427 "ld $4, 72(%1)\n\t" \
6428 "sd $4, 0($29)\n\t" \
6429 "ld $4, 80(%1)\n\t" \
6430 "sd $4, 8($29)\n\t" \
6431 "ld $4, 8(%1)\n\t" \
6432 "ld $5, 16(%1)\n\t" \
6433 "ld $6, 24(%1)\n\t" \
6434 "ld $7, 32(%1)\n\t" \
6435 "ld $8, 40(%1)\n\t" \
6436 "ld $9, 48(%1)\n\t" \
6437 "ld $10, 56(%1)\n\t" \
6438 "ld $11, 64(%1)\n\t" \
6439 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6440 VALGRIND_CALL_NOREDIR_T9 \
6441 "daddu $29, $29, 16\n\t" \
6443 : /*out*/ "=r" (_res) \
6444 : /*in*/ "r" (&_argvec[0]) \
6445 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6447 lval = (__typeof__(lval)) (long)_res; \
6450 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
6451 arg6,arg7,arg8,arg9,arg10, \
6454 volatile OrigFn _orig = (orig); \
6455 volatile unsigned long long _argvec[12]; \
6456 volatile unsigned long long _res; \
6457 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6458 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6459 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6460 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6461 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6462 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6463 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6464 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6465 _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
6466 _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
6467 _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
6468 _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \
6470 "dsubu $29, $29, 24\n\t" \
6471 "ld $4, 72(%1)\n\t" \
6472 "sd $4, 0($29)\n\t" \
6473 "ld $4, 80(%1)\n\t" \
6474 "sd $4, 8($29)\n\t" \
6475 "ld $4, 88(%1)\n\t" \
6476 "sd $4, 16($29)\n\t" \
6477 "ld $4, 8(%1)\n\t" \
6478 "ld $5, 16(%1)\n\t" \
6479 "ld $6, 24(%1)\n\t" \
6480 "ld $7, 32(%1)\n\t" \
6481 "ld $8, 40(%1)\n\t" \
6482 "ld $9, 48(%1)\n\t" \
6483 "ld $10, 56(%1)\n\t" \
6484 "ld $11, 64(%1)\n\t" \
6485 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6486 VALGRIND_CALL_NOREDIR_T9 \
6487 "daddu $29, $29, 24\n\t" \
6489 : /*out*/ "=r" (_res) \
6490 : /*in*/ "r" (&_argvec[0]) \
6491 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6493 lval = (__typeof__(lval)) (long)_res; \
6496 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
6497 arg6,arg7,arg8,arg9,arg10, \
6500 volatile OrigFn _orig = (orig); \
6501 volatile unsigned long long _argvec[13]; \
6502 volatile unsigned long long _res; \
6503 _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
6504 _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
6505 _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
6506 _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
6507 _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
6508 _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
6509 _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
6510 _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
6511 _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
6512 _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
6513 _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
6514 _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \
6515 _argvec[12] = MIPS64_LONG2REG_CAST(arg12); \
6517 "dsubu $29, $29, 32\n\t" \
6518 "ld $4, 72(%1)\n\t" \
6519 "sd $4, 0($29)\n\t" \
6520 "ld $4, 80(%1)\n\t" \
6521 "sd $4, 8($29)\n\t" \
6522 "ld $4, 88(%1)\n\t" \
6523 "sd $4, 16($29)\n\t" \
6524 "ld $4, 96(%1)\n\t" \
6525 "sd $4, 24($29)\n\t" \
6526 "ld $4, 8(%1)\n\t" \
6527 "ld $5, 16(%1)\n\t" \
6528 "ld $6, 24(%1)\n\t" \
6529 "ld $7, 32(%1)\n\t" \
6530 "ld $8, 40(%1)\n\t" \
6531 "ld $9, 48(%1)\n\t" \
6532 "ld $10, 56(%1)\n\t" \
6533 "ld $11, 64(%1)\n\t" \
6534 "ld $25, 0(%1)\n\t" /* target->t9 */ \
6535 VALGRIND_CALL_NOREDIR_T9 \
6536 "daddu $29, $29, 32\n\t" \
6538 : /*out*/ "=r" (_res) \
6539 : /*in*/ "r" (&_argvec[0]) \
6540 : /*trash*/ "memory", __CALLER_SAVED_REGS \
6542 lval = (__typeof__(lval)) (long)_res; \
6545 #endif /* PLAT_mips64_linux */
6547 /* ------------------------------------------------------------------ */
6548 /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
6550 /* ------------------------------------------------------------------ */
6552 /* Some request codes. There are many more of these, but most are not
6553 exposed to end-user view. These are the public ones, all of the
6554 form 0x1000 + small_number.
6556 Core ones are in the range 0x00000000--0x0000ffff. The non-public
6557 ones start at 0x2000.
6560 /* These macros are used by tools -- they must be public, but don't
6561 embed them into other programs. */
6562 #define VG_USERREQ_TOOL_BASE(a,b) \
6563 ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
6564 #define VG_IS_TOOL_USERREQ(a, b, v) \
6565 (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
6567 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
6568 This enum comprises an ABI exported by Valgrind to programs
6569 which use client requests. DO NOT CHANGE THE NUMERIC VALUES OF THESE
6570 ENTRIES, NOR DELETE ANY -- add new ones at the end of the most
6573 enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
6574 VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
6576 /* These allow any function to be called from the simulated
6577 CPU but run on the real CPU. Nb: the first arg passed to
6578 the function is always the ThreadId of the running
6579 thread! So CLIENT_CALL0 actually requires a 1 arg
6581 VG_USERREQ__CLIENT_CALL0 = 0x1101,
6582 VG_USERREQ__CLIENT_CALL1 = 0x1102,
6583 VG_USERREQ__CLIENT_CALL2 = 0x1103,
6584 VG_USERREQ__CLIENT_CALL3 = 0x1104,
6586 /* Can be useful in regression testing suites -- eg. can
6587 send Valgrind's output to /dev/null and still count
6589 VG_USERREQ__COUNT_ERRORS = 0x1201,
6591 /* Allows the client program and/or gdbserver to execute a monitor
6593 VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
6595 /* Allows the client program to change a dynamic command line
6597 VG_USERREQ__CLO_CHANGE = 0x1203,
6599 /* These are useful and can be interpreted by any tool that
6600 tracks malloc() et al, by using vg_replace_malloc.c. */
6601 VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
6602 VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
6603 VG_USERREQ__FREELIKE_BLOCK = 0x1302,
6604 /* Memory pool support. */
6605 VG_USERREQ__CREATE_MEMPOOL = 0x1303,
6606 VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
6607 VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
6608 VG_USERREQ__MEMPOOL_FREE = 0x1306,
6609 VG_USERREQ__MEMPOOL_TRIM = 0x1307,
6610 VG_USERREQ__MOVE_MEMPOOL = 0x1308,
6611 VG_USERREQ__MEMPOOL_CHANGE = 0x1309,
6612 VG_USERREQ__MEMPOOL_EXISTS = 0x130a,
6614 /* Allow printfs to valgrind log. */
6615 /* The first two pass the va_list argument by value, which
6616 assumes it is the same size as or smaller than a UWord,
6617 which generally isn't the case. Hence are deprecated.
6618 The second two pass the vargs by reference and so are
6619 immune to this problem. */
6620 /* both :: char* fmt, va_list vargs (DEPRECATED) */
6621 VG_USERREQ__PRINTF = 0x1401,
6622 VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
6623 /* both :: char* fmt, va_list* vargs */
6624 VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
6625 VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
6627 /* Stack support. */
6628 VG_USERREQ__STACK_REGISTER = 0x1501,
6629 VG_USERREQ__STACK_DEREGISTER = 0x1502,
6630 VG_USERREQ__STACK_CHANGE = 0x1503,
6633 VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
6635 /* Querying of debug info. */
6636 VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
6638 /* Disable/enable error reporting level. Takes a single
6639 Word arg which is the delta to this thread's error
6640 disablement indicator. Hence 1 disables or further
6641 disables errors, and -1 moves back towards enablement.
6642 Other values are not allowed. */
6643 VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801,
6645 /* Some requests used for Valgrind internal, such as
6646 self-test or self-hosting. */
6647 /* Initialise IR injection */
6648 VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901,
6649 /* Used by Inner Valgrind to inform Outer Valgrind where to
6650 find the list of inner guest threads */
6651 VG_USERREQ__INNER_THREADS = 0x1902
6654 #if !defined(__GNUC__)
6655 # define __extension__ /* */
6659 /* Returns the number of Valgrinds this code is running under. That
6660 is, 0 if running natively, 1 if running under Valgrind, 2 if
6661 running under Valgrind which is running under another Valgrind,
6663 #define RUNNING_ON_VALGRIND \
6664 (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \
6665 VG_USERREQ__RUNNING_ON_VALGRIND, \
6669 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
6670 _qzz_len - 1]. Useful if you are debugging a JITter or some such,
6671 since it provides a way to make sure valgrind will retranslate the
6672 invalidated area. Returns no value. */
6673 #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
6674 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \
6675 _qzz_addr, _qzz_len, 0, 0, 0)
6677 #define VALGRIND_INNER_THREADS(_qzz_addr) \
6678 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS, \
6679 _qzz_addr, 0, 0, 0, 0)
6682 /* These requests are for getting Valgrind itself to print something.
6683 Possibly with a backtrace. This is a really ugly hack. The return value
6684 is the number of characters printed, excluding the "**<pid>** " part at the
6685 start and the backtrace (if present). */
6687 #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
6688 /* Modern GCC will optimize the static routine out if unused,
6689 and unused attribute will shut down warnings about it. */
6690 static int VALGRIND_PRINTF(const char *format, ...)
6691 __attribute__((format(__printf__, 1, 2), __unused__));
6694 #if defined(_MSC_VER)
6697 VALGRIND_PRINTF(const char *format, ...)
6699 #if !IS_ENABLED(CONFIG_VALGRIND)
6702 #else /* CONFIG_VALGRIND */
6703 #if defined(_MSC_VER) || defined(__MINGW64__)
6706 unsigned long _qzz_res;
6709 va_start(vargs, format);
6710 #if defined(_MSC_VER) || defined(__MINGW64__)
6711 _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
6712 VG_USERREQ__PRINTF_VALIST_BY_REF,
6717 _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
6718 VG_USERREQ__PRINTF_VALIST_BY_REF,
6719 (unsigned long)format,
6720 (unsigned long)&vargs,
6724 return (int)_qzz_res;
6725 #endif /* CONFIG_VALGRIND */
6728 #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
6729 static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
6730 __attribute__((format(__printf__, 1, 2), __unused__));
6733 #if defined(_MSC_VER)
6736 VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
6738 #if !IS_ENABLED(CONFIG_VALGRIND)
6741 #else /* CONFIG_VALGRIND */
6742 #if defined(_MSC_VER) || defined(__MINGW64__)
6745 unsigned long _qzz_res;
6748 va_start(vargs, format);
6749 #if defined(_MSC_VER) || defined(__MINGW64__)
6750 _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
6751 VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
6756 _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
6757 VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
6758 (unsigned long)format,
6759 (unsigned long)&vargs,
6763 return (int)_qzz_res;
6764 #endif /* CONFIG_VALGRIND */
6768 /* These requests allow control to move from the simulated CPU to the
6769 real CPU, calling an arbitrary function.
6771 Note that the current ThreadId is inserted as the first argument.
6774 VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
6776 requires f to have this signature:
6778 Word f(Word tid, Word arg1, Word arg2)
6780 where "Word" is a word-sized type.
6782 Note that these client requests are not entirely reliable. For example,
6783 if you call a function with them that subsequently calls printf(),
6784 there's a high chance Valgrind will crash. Generally, your prospects of
6785 these working are made higher if the called function does not refer to
6786 any global variables, and does not refer to any libc or other functions
6787 (printf et al). Any kind of entanglement with libc or dynamic linking is
6788 likely to have a bad outcome, for tricky reasons which we've grappled
6789 with a lot in the past.
6791 #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
6792 VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
6793 VG_USERREQ__CLIENT_CALL0, \
6797 #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
6798 VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
6799 VG_USERREQ__CLIENT_CALL1, \
6803 #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
6804 VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
6805 VG_USERREQ__CLIENT_CALL2, \
6807 _qyy_arg1, _qyy_arg2, 0, 0)
6809 #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
6810 VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
6811 VG_USERREQ__CLIENT_CALL3, \
6813 _qyy_arg1, _qyy_arg2, \
6817 /* Counts the number of errors that have been recorded by a tool. Nb:
6818 the tool must record the errors with VG_(maybe_record_error)() or
6819 VG_(unique_error)() for them to be counted. */
6820 #define VALGRIND_COUNT_ERRORS \
6821 (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \
6822 0 /* default return */, \
6823 VG_USERREQ__COUNT_ERRORS, \
6826 /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
6827 when heap blocks are allocated in order to give accurate results. This
6828 happens automatically for the standard allocator functions such as
6829 malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
6832 But if your program uses a custom allocator, this doesn't automatically
6833 happen, and Valgrind will not do as well. For example, if you allocate
6834 superblocks with mmap() and then allocates chunks of the superblocks, all
6835 Valgrind's observations will be at the mmap() level and it won't know that
6836 the chunks should be considered separate entities. In Memcheck's case,
6837 that means you probably won't get heap block overrun detection (because
6838 there won't be redzones marked as unaddressable) and you definitely won't
6839 get any leak detection.
6841 The following client requests allow a custom allocator to be annotated so
6842 that it can be handled accurately by Valgrind.
6844 VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
6845 by a malloc()-like function. For Memcheck (an illustrative case), this
6848 - It records that the block has been allocated. This means any addresses
6849 within the block mentioned in error messages will be
6850 identified as belonging to the block. It also means that if the block
6851 isn't freed it will be detected by the leak checker.
6853 - It marks the block as being addressable and undefined (if 'is_zeroed' is
6854 not set), or addressable and defined (if 'is_zeroed' is set). This
6855 controls how accesses to the block by the program are handled.
6857 'addr' is the start of the usable block (ie. after any
6858 redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator
6859 can apply redzones -- these are blocks of padding at the start and end of
6860 each block. Adding redzones is recommended as it makes it much more likely
6861 Valgrind will spot block overruns. `is_zeroed' indicates if the memory is
6862 zeroed (or filled with another predictable value), as is the case for
6865 VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
6866 heap block -- that will be used by the client program -- is allocated.
6867 It's best to put it at the outermost level of the allocator if possible;
6868 for example, if you have a function my_alloc() which calls
6869 internal_alloc(), and the client request is put inside internal_alloc(),
6870 stack traces relating to the heap block will contain entries for both
6871 my_alloc() and internal_alloc(), which is probably not what you want.
6873 For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
6874 custom blocks from within a heap block, B, that has been allocated with
6875 malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
6876 -- the custom blocks will take precedence.
6878 VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For
6879 Memcheck, it does two things:
6881 - It records that the block has been deallocated. This assumes that the
6882 block was annotated as having been allocated via
6883 VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
6885 - It marks the block as being unaddressable.
6887 VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
6888 heap block is deallocated.
6890 VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
6891 Memcheck, it does four things:
6893 - It records that the size of a block has been changed. This assumes that
6894 the block was annotated as having been allocated via
6895 VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
6897 - If the block shrunk, it marks the freed memory as being unaddressable.
6899 - If the block grew, it marks the new area as undefined and defines a red
6900 zone past the end of the new block.
6902 - The V-bits of the overlap between the old and the new block are preserved.
6904 VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
6905 and before deallocation of the old block.
6907 In many cases, these three client requests will not be enough to get your
6908 allocator working well with Memcheck. More specifically, if your allocator
6909 writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
6910 will be necessary to mark the memory as addressable just before the zeroing
6911 occurs, otherwise you'll get a lot of invalid write errors. For example,
6912 you'll need to do this if your allocator recycles freed blocks, but it
6913 zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
6914 Alternatively, if your allocator reuses freed blocks for allocator-internal
6915 data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
6917 Really, what's happening is a blurring of the lines between the client
6918 program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
6919 memory should be considered unaddressable to the client program, but the
6920 allocator knows more than the rest of the client program and so may be able
6921 to safely access it. Extra client requests are necessary for Valgrind to
6922 understand the distinction between the allocator and the rest of the
6925 Ignored if addr == 0.
6927 #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
6928 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \
6929 addr, sizeB, rzB, is_zeroed, 0)
6931 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
6932 Ignored if addr == 0.
6934 #define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \
6935 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \
6936 addr, oldSizeB, newSizeB, rzB, 0)
6938 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
6939 Ignored if addr == 0.
6941 #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
6942 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \
6945 /* Create a memory pool. */
6946 #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
6947 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
6948 pool, rzB, is_zeroed, 0, 0)
6950 /* Create a memory pool with some flags specifying extended behaviour.
6951 When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL.
6953 The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory
6954 associated with the pool using VALGRIND_MEMPOOL_ALLOC will be used
6955 by the application as superblocks to dole out MALLOC_LIKE blocks using
6956 VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels"
6957 pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC.
6958 The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK.
6959 Note that the association between the pool and the second level blocks
6960 is implicit : second level blocks will be located inside first level
6961 blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag
6962 for such 2 levels pools, as otherwise valgrind will detect overlapping
6963 memory blocks, and will abort execution (e.g. during leak search).
6965 Such a meta pool can also be marked as an 'auto free' pool using the flag
6966 VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the
6967 VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE
6968 will automatically free the second level blocks that are contained
6969 inside the first level block freed with VALGRIND_MEMPOOL_FREE.
6970 In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls
6971 to VALGRIND_FREELIKE_BLOCK for all the second level blocks included
6972 in the first level block.
6973 Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag
6974 without the VALGRIND_MEMPOOL_METAPOOL flag.
6976 #define VALGRIND_MEMPOOL_AUTO_FREE 1
6977 #define VALGRIND_MEMPOOL_METAPOOL 2
6978 #define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags) \
6979 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
6980 pool, rzB, is_zeroed, flags, 0)
6982 /* Destroy a memory pool. */
6983 #define VALGRIND_DESTROY_MEMPOOL(pool) \
6984 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \
6987 /* Associate a piece of memory with a memory pool. */
6988 #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
6989 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \
6990 pool, addr, size, 0, 0)
6992 /* Disassociate a piece of memory from a memory pool. */
6993 #define VALGRIND_MEMPOOL_FREE(pool, addr) \
6994 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \
6995 pool, addr, 0, 0, 0)
6997 /* Disassociate any pieces outside a particular range. */
6998 #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
6999 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \
7000 pool, addr, size, 0, 0)
7002 /* Resize and/or move a piece associated with a memory pool. */
7003 #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
7004 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \
7005 poolA, poolB, 0, 0, 0)
7007 /* Resize and/or move a piece associated with a memory pool. */
7008 #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
7009 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \
7010 pool, addrA, addrB, size, 0)
7012 /* Return 1 if a mempool exists, else 0. */
7013 #define VALGRIND_MEMPOOL_EXISTS(pool) \
7014 (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
7015 VG_USERREQ__MEMPOOL_EXISTS, \
7018 /* Mark a piece of memory as being a stack. Returns a stack id.
7019 start is the lowest addressable stack byte, end is the highest
7020 addressable stack byte. */
7021 #define VALGRIND_STACK_REGISTER(start, end) \
7022 (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
7023 VG_USERREQ__STACK_REGISTER, \
7024 start, end, 0, 0, 0)
7026 /* Unmark the piece of memory associated with a stack id as being a
7028 #define VALGRIND_STACK_DEREGISTER(id) \
7029 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
7032 /* Change the start and end address of the stack id.
7033 start is the new lowest addressable stack byte, end is the new highest
7034 addressable stack byte. */
7035 #define VALGRIND_STACK_CHANGE(id, start, end) \
7036 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \
7037 id, start, end, 0, 0)
7039 /* Load PDB debug info for Wine PE image_map. */
7040 #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \
7041 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
7042 fd, ptr, total_size, delta, 0)
7044 /* Map a code address to a source file name and line number. buf64
7045 must point to a 64-byte buffer in the caller's address space. The
7046 result will be dumped in there and is guaranteed to be zero
7047 terminated. If no info is found, the first byte is set to zero. */
7048 #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \
7049 (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
7050 VG_USERREQ__MAP_IP_TO_SRCLOC, \
7051 addr, buf64, 0, 0, 0)
7053 /* Disable error reporting for this thread. Behaves in a stack like
7054 way, so you can safely call this multiple times provided that
7055 VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
7056 to re-enable reporting. The first call of this macro disables
7057 reporting. Subsequent calls have no effect except to increase the
7058 number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
7059 reporting. Child threads do not inherit this setting from their
7060 parents -- they are always created with reporting enabled. */
7061 #define VALGRIND_DISABLE_ERROR_REPORTING \
7062 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
7065 /* Re-enable error reporting, as per comments on
7066 VALGRIND_DISABLE_ERROR_REPORTING. */
7067 #define VALGRIND_ENABLE_ERROR_REPORTING \
7068 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
7071 /* Execute a monitor command from the client program.
7072 If a connection is opened with GDB, the output will be sent
7073 according to the output mode set for vgdb.
7074 If no connection is opened, output will go to the log output.
7075 Returns 1 if command not recognised, 0 otherwise. */
7076 #define VALGRIND_MONITOR_COMMAND(command) \
7077 VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \
7078 command, 0, 0, 0, 0)
7081 /* Change the value of a dynamic command line option.
7082 Note that unknown or not dynamically changeable options
7083 will cause a warning message to be output. */
7084 #define VALGRIND_CLO_CHANGE(option) \
7085 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CLO_CHANGE, \
7089 #undef PLAT_x86_darwin
7090 #undef PLAT_amd64_darwin
7091 #undef PLAT_x86_win32
7092 #undef PLAT_amd64_win64
7093 #undef PLAT_x86_linux
7094 #undef PLAT_amd64_linux
7095 #undef PLAT_ppc32_linux
7096 #undef PLAT_ppc64be_linux
7097 #undef PLAT_ppc64le_linux
7098 #undef PLAT_arm_linux
7099 #undef PLAT_s390x_linux
7100 #undef PLAT_mips32_linux
7101 #undef PLAT_mips64_linux
7102 #undef PLAT_nanomips_linux
7103 #undef PLAT_x86_solaris
7104 #undef PLAT_amd64_solaris
7106 #endif /* __VALGRIND_H */