NDDEM
valgrind.h
Go to the documentation of this file.
1 /* -*- c -*-
2  ----------------------------------------------------------------
3 
4  Notice that the following BSD-style license applies to this one
5  file (valgrind.h) only. The rest of Valgrind is licensed under the
6  terms of the GNU General Public License, version 2, unless
7  otherwise indicated. See the COPYING file in the source
8  distribution for details.
9 
10  ----------------------------------------------------------------
11 
12  This file is part of Valgrind, a dynamic binary instrumentation
13  framework.
14 
15  Copyright (C) 2000-2011 Julian Seward. All rights reserved.
16 
17  Redistribution and use in source and binary forms, with or without
18  modification, are permitted provided that the following conditions
19  are met:
20 
21  1. Redistributions of source code must retain the above copyright
22  notice, this list of conditions and the following disclaimer.
23 
24  2. The origin of this software must not be misrepresented; you must
25  not claim that you wrote the original software. If you use this
26  software in a product, an acknowledgment in the product
27  documentation would be appreciated but is not required.
28 
29  3. Altered source versions must be plainly marked as such, and must
30  not be misrepresented as being the original software.
31 
32  4. The name of the author may not be used to endorse or promote
33  products derived from this software without specific prior written
34  permission.
35 
36  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 
48  ----------------------------------------------------------------
49 
50  Notice that the above BSD-style license applies to this one file
51  (valgrind.h) only. The entire rest of Valgrind is licensed under
52  the terms of the GNU General Public License, version 2. See the
53  COPYING file in the source distribution for details.
54 
55  ----------------------------------------------------------------
56 */
57 
58 
59 /* This file is for inclusion into client (your!) code.
60 
61  You can use these macros to manipulate and query Valgrind's
62  execution inside your own programs.
63 
64  The resulting executables will still run without Valgrind, just a
65  little bit more slowly than they otherwise would, but otherwise
66  unchanged. When not running on valgrind, each client request
67  consumes very few (eg. 7) instructions, so the resulting performance
68  loss is negligible unless you plan to execute client requests
69  millions of times per second. Nevertheless, if that is still a
70  problem, you can compile with the NVALGRIND symbol defined (gcc
71  -DNVALGRIND) so that client requests are not even compiled in. */
72 
73 #ifndef __VALGRIND_H
74 #define __VALGRIND_H
75 
76 
77 /* ------------------------------------------------------------------ */
78 /* VERSION NUMBER OF VALGRIND */
79 /* ------------------------------------------------------------------ */
80 
81 /* Specify Valgrind's version number, so that user code can
82  conditionally compile based on our version number. Note that these
83  were introduced at version 3.6 and so do not exist in version 3.5
84  or earlier. The recommended way to use them to check for "version
85  X.Y or later" is (eg)
86 
87 #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \
88  && (__VALGRIND_MAJOR__ > 3 \
89  || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
90 */
91 #define __VALGRIND_MAJOR__ 3
92 #define __VALGRIND_MINOR__ 6
93 
94 
95 #include <stdarg.h>
96 
97 /* Nb: this file might be included in a file compiled with -ansi. So
98  we can't use C++ style "//" comments nor the "asm" keyword (instead
99  use "__asm__"). */
100 
101 /* Derive some tags indicating what the target platform is. Note
102  that in this file we're using the compiler's CPP symbols for
103  identifying architectures, which are different to the ones we use
104  within the rest of Valgrind. Note, __powerpc__ is active for both
105  32 and 64-bit PPC, whereas __powerpc64__ is only active for the
106  latter (on Linux, that is).
107 
108  Misc note: how to find out what's predefined in gcc by default:
109  gcc -Wp,-dM somefile.c
110 */
111 #undef PLAT_x86_darwin
112 #undef PLAT_amd64_darwin
113 #undef PLAT_x86_win32
114 #undef PLAT_x86_linux
115 #undef PLAT_amd64_linux
116 #undef PLAT_ppc32_linux
117 #undef PLAT_ppc64_linux
118 #undef PLAT_arm_linux
119 #undef PLAT_s390x_linux
120 
121 
122 #if defined(__APPLE__) && defined(__i386__)
123 # define PLAT_x86_darwin 1
124 #elif defined(__APPLE__) && defined(__x86_64__)
125 # define PLAT_amd64_darwin 1
126 #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
127  || (defined(_WIN32) && defined(_M_IX86))
128 # define PLAT_x86_win32 1
129 #elif defined(__linux__) && defined(__i386__)
130 # define PLAT_x86_linux 1
131 #elif defined(__linux__) && defined(__x86_64__)
132 # define PLAT_amd64_linux 1
133 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
134 # define PLAT_ppc32_linux 1
135 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
136 # define PLAT_ppc64_linux 1
137 #elif defined(__linux__) && defined(__arm__)
138 # define PLAT_arm_linux 1
139 #elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
140 # define PLAT_s390x_linux 1
141 #else
142 /* If we're not compiling for our target platform, don't generate
143  any inline asms. */
144 # if !defined(NVALGRIND)
145 # define NVALGRIND 1
146 # endif
147 #endif
148 
149 
150 /* ------------------------------------------------------------------ */
151 /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
152 /* in here of use to end-users -- skip to the next section. */
153 /* ------------------------------------------------------------------ */
154 
155 /*
156  * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
157  * request. Accepts both pointers and integers as arguments.
158  *
159  * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
160  * client request that does not return a value.
161 
162  * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
163  * client request and whose value equals the client request result. Accepts
164  * both pointers and integers as arguments. Note that such calls are not
165  * necessarily pure functions -- they may have side effects.
166  */
167 
168 #define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \
169  _zzq_request, _zzq_arg1, _zzq_arg2, \
170  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
171  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \
172  (_zzq_request), (_zzq_arg1), (_zzq_arg2), \
173  (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
174 
175 #define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \
176  _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
177  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
178  (_zzq_request), (_zzq_arg1), (_zzq_arg2), \
179  (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
180 
181 #if defined(NVALGRIND)
182 
183 /* Define NVALGRIND to completely remove the Valgrind magic sequence
184  from the compiled code (analogous to NDEBUG's effects on
185  assert()) */
186 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
187  _zzq_default, _zzq_request, \
188  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
189  (_zzq_default)
190 
191 #else /* ! NVALGRIND */
192 
193 /* The following defines the magic code sequences which the JITter
194  spots and handles magically. Don't look too closely at them as
195  they will rot your brain.
196 
197  The assembly code sequences for all architectures is in this one
198  file. This is because this file must be stand-alone, and we don't
199  want to have multiple files.
200 
201  For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
202  value gets put in the return slot, so that everything works when
203  this is executed not under Valgrind. Args are passed in a memory
204  block, and so there's no intrinsic limit to the number that could
205  be passed, but it's currently five.
206 
207  The macro args are:
208  _zzq_rlval result lvalue
209  _zzq_default default value (result returned when running on real CPU)
210  _zzq_request request code
211  _zzq_arg1..5 request params
212 
213  The other two macros are used to support function wrapping, and are
214  a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
215  guest's NRADDR pseudo-register and whatever other information is
216  needed to safely run the call original from the wrapper: on
217  ppc64-linux, the R2 value at the divert point is also needed. This
218  information is abstracted into a user-visible type, OrigFn.
219 
220  VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
221  guest, but guarantees that the branch instruction will not be
222  redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
223  branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
224  complete inline asm, since it needs to be combined with more magic
225  inline asm stuff to be useful.
226 */
227 
228 /* ------------------------- x86-{linux,darwin} ---------------- */
229 
230 #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
231  || (defined(PLAT_x86_win32) && defined(__GNUC__))
232 
233 typedef
234  struct {
235  unsigned int nraddr; /* where's the code? */
236  }
237  OrigFn;
238 
239 #define __SPECIAL_INSTRUCTION_PREAMBLE \
240  "roll $3, %%edi ; roll $13, %%edi\n\t" \
241  "roll $29, %%edi ; roll $19, %%edi\n\t"
242 
243 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
244  _zzq_default, _zzq_request, \
245  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
246  __extension__ \
247  ({volatile unsigned int _zzq_args[6]; \
248  volatile unsigned int _zzq_result; \
249  _zzq_args[0] = (unsigned int)(_zzq_request); \
250  _zzq_args[1] = (unsigned int)(_zzq_arg1); \
251  _zzq_args[2] = (unsigned int)(_zzq_arg2); \
252  _zzq_args[3] = (unsigned int)(_zzq_arg3); \
253  _zzq_args[4] = (unsigned int)(_zzq_arg4); \
254  _zzq_args[5] = (unsigned int)(_zzq_arg5); \
255  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
256  /* %EDX = client_request ( %EAX ) */ \
257  "xchgl %%ebx,%%ebx" \
258  : "=d" (_zzq_result) \
259  : "a" (&_zzq_args[0]), "0" (_zzq_default) \
260  : "cc", "memory" \
261  ); \
262  _zzq_result; \
263  })
264 
265 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
266  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
267  volatile unsigned int __addr; \
268  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
269  /* %EAX = guest_NRADDR */ \
270  "xchgl %%ecx,%%ecx" \
271  : "=a" (__addr) \
272  : \
273  : "cc", "memory" \
274  ); \
275  _zzq_orig->nraddr = __addr; \
276  }
277 
278 #define VALGRIND_CALL_NOREDIR_EAX \
279  __SPECIAL_INSTRUCTION_PREAMBLE \
280  /* call-noredir *%EAX */ \
281  "xchgl %%edx,%%edx\n\t"
282 #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
283 
284 /* ------------------------- x86-Win32 ------------------------- */
285 
286 #if defined(PLAT_x86_win32) && !defined(__GNUC__)
287 
288 typedef
289  struct {
290  unsigned int nraddr; /* where's the code? */
291  }
292  OrigFn;
293 
294 #if defined(_MSC_VER)
295 
296 #define __SPECIAL_INSTRUCTION_PREAMBLE \
297  __asm rol edi, 3 __asm rol edi, 13 \
298  __asm rol edi, 29 __asm rol edi, 19
299 
300 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
301  _zzq_default, _zzq_request, \
302  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
303  valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \
304  (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \
305  (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \
306  (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
307 
308 static __inline uintptr_t
309 valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
310  uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
311  uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
312  uintptr_t _zzq_arg5)
313 {
314  volatile uintptr_t _zzq_args[6];
315  volatile unsigned int _zzq_result;
316  _zzq_args[0] = (uintptr_t)(_zzq_request);
317  _zzq_args[1] = (uintptr_t)(_zzq_arg1);
318  _zzq_args[2] = (uintptr_t)(_zzq_arg2);
319  _zzq_args[3] = (uintptr_t)(_zzq_arg3);
320  _zzq_args[4] = (uintptr_t)(_zzq_arg4);
321  _zzq_args[5] = (uintptr_t)(_zzq_arg5);
322  __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
323  __SPECIAL_INSTRUCTION_PREAMBLE
324  /* %EDX = client_request ( %EAX ) */
325  __asm xchg ebx,ebx
326  __asm mov _zzq_result, edx
327  }
328  return _zzq_result;
329 }
330 
331 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
332  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
333  volatile unsigned int __addr; \
334  __asm { __SPECIAL_INSTRUCTION_PREAMBLE \
335  /* %EAX = guest_NRADDR */ \
336  __asm xchg ecx,ecx \
337  __asm mov __addr, eax \
338  } \
339  _zzq_orig->nraddr = __addr; \
340  }
341 
342 #define VALGRIND_CALL_NOREDIR_EAX ERROR
343 
344 #else
345 #error Unsupported compiler.
346 #endif
347 
348 #endif /* PLAT_x86_win32 */
349 
350 /* ------------------------ amd64-{linux,darwin} --------------- */
351 
352 #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
353 
354 typedef
355  struct {
356  unsigned long long int nraddr; /* where's the code? */
357  }
358  OrigFn;
359 
360 #define __SPECIAL_INSTRUCTION_PREAMBLE \
361  "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
362  "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
363 
364 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
365  _zzq_default, _zzq_request, \
366  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
367  __extension__ \
368  ({ volatile unsigned long long int _zzq_args[6]; \
369  volatile unsigned long long int _zzq_result; \
370  _zzq_args[0] = (unsigned long long int)(_zzq_request); \
371  _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
372  _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
373  _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
374  _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
375  _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
376  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
377  /* %RDX = client_request ( %RAX ) */ \
378  "xchgq %%rbx,%%rbx" \
379  : "=d" (_zzq_result) \
380  : "a" (&_zzq_args[0]), "0" (_zzq_default) \
381  : "cc", "memory" \
382  ); \
383  _zzq_result; \
384  })
385 
386 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
387  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
388  volatile unsigned long long int __addr; \
389  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
390  /* %RAX = guest_NRADDR */ \
391  "xchgq %%rcx,%%rcx" \
392  : "=a" (__addr) \
393  : \
394  : "cc", "memory" \
395  ); \
396  _zzq_orig->nraddr = __addr; \
397  }
398 
399 #define VALGRIND_CALL_NOREDIR_RAX \
400  __SPECIAL_INSTRUCTION_PREAMBLE \
401  /* call-noredir *%RAX */ \
402  "xchgq %%rdx,%%rdx\n\t"
403 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
404 
405 /* ------------------------ ppc32-linux ------------------------ */
406 
407 #if defined(PLAT_ppc32_linux)
408 
409 typedef
410  struct {
411  unsigned int nraddr; /* where's the code? */
412  }
413  OrigFn;
414 
415 #define __SPECIAL_INSTRUCTION_PREAMBLE \
416  "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
417  "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
418 
419 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
420  _zzq_default, _zzq_request, \
421  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
422  \
423  __extension__ \
424  ({ unsigned int _zzq_args[6]; \
425  unsigned int _zzq_result; \
426  unsigned int* _zzq_ptr; \
427  _zzq_args[0] = (unsigned int)(_zzq_request); \
428  _zzq_args[1] = (unsigned int)(_zzq_arg1); \
429  _zzq_args[2] = (unsigned int)(_zzq_arg2); \
430  _zzq_args[3] = (unsigned int)(_zzq_arg3); \
431  _zzq_args[4] = (unsigned int)(_zzq_arg4); \
432  _zzq_args[5] = (unsigned int)(_zzq_arg5); \
433  _zzq_ptr = _zzq_args; \
434  __asm__ volatile("mr 3,%1\n\t" /*default*/ \
435  "mr 4,%2\n\t" /*ptr*/ \
436  __SPECIAL_INSTRUCTION_PREAMBLE \
437  /* %R3 = client_request ( %R4 ) */ \
438  "or 1,1,1\n\t" \
439  "mr %0,3" /*result*/ \
440  : "=b" (_zzq_result) \
441  : "b" (_zzq_default), "b" (_zzq_ptr) \
442  : "cc", "memory", "r3", "r4"); \
443  _zzq_result; \
444  })
445 
446 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
447  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
448  unsigned int __addr; \
449  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
450  /* %R3 = guest_NRADDR */ \
451  "or 2,2,2\n\t" \
452  "mr %0,3" \
453  : "=b" (__addr) \
454  : \
455  : "cc", "memory", "r3" \
456  ); \
457  _zzq_orig->nraddr = __addr; \
458  }
459 
460 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
461  __SPECIAL_INSTRUCTION_PREAMBLE \
462  /* branch-and-link-to-noredir *%R11 */ \
463  "or 3,3,3\n\t"
464 #endif /* PLAT_ppc32_linux */
465 
466 /* ------------------------ ppc64-linux ------------------------ */
467 
468 #if defined(PLAT_ppc64_linux)
469 
470 typedef
471  struct {
472  unsigned long long int nraddr; /* where's the code? */
473  unsigned long long int r2; /* what tocptr do we need? */
474  }
475  OrigFn;
476 
477 #define __SPECIAL_INSTRUCTION_PREAMBLE \
478  "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
479  "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
480 
481 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
482  _zzq_default, _zzq_request, \
483  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
484  \
485  __extension__ \
486  ({ unsigned long long int _zzq_args[6]; \
487  unsigned long long int _zzq_result; \
488  unsigned long long int* _zzq_ptr; \
489  _zzq_args[0] = (unsigned long long int)(_zzq_request); \
490  _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
491  _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
492  _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
493  _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
494  _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
495  _zzq_ptr = _zzq_args; \
496  __asm__ volatile("mr 3,%1\n\t" /*default*/ \
497  "mr 4,%2\n\t" /*ptr*/ \
498  __SPECIAL_INSTRUCTION_PREAMBLE \
499  /* %R3 = client_request ( %R4 ) */ \
500  "or 1,1,1\n\t" \
501  "mr %0,3" /*result*/ \
502  : "=b" (_zzq_result) \
503  : "b" (_zzq_default), "b" (_zzq_ptr) \
504  : "cc", "memory", "r3", "r4"); \
505  _zzq_result; \
506  })
507 
508 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
509  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
510  unsigned long long int __addr; \
511  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
512  /* %R3 = guest_NRADDR */ \
513  "or 2,2,2\n\t" \
514  "mr %0,3" \
515  : "=b" (__addr) \
516  : \
517  : "cc", "memory", "r3" \
518  ); \
519  _zzq_orig->nraddr = __addr; \
520  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
521  /* %R3 = guest_NRADDR_GPR2 */ \
522  "or 4,4,4\n\t" \
523  "mr %0,3" \
524  : "=b" (__addr) \
525  : \
526  : "cc", "memory", "r3" \
527  ); \
528  _zzq_orig->r2 = __addr; \
529  }
530 
531 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
532  __SPECIAL_INSTRUCTION_PREAMBLE \
533  /* branch-and-link-to-noredir *%R11 */ \
534  "or 3,3,3\n\t"
535 
536 #endif /* PLAT_ppc64_linux */
537 
538 /* ------------------------- arm-linux ------------------------- */
539 
540 #if defined(PLAT_arm_linux)
541 
542 typedef
543  struct {
544  unsigned int nraddr; /* where's the code? */
545  }
546  OrigFn;
547 
548 #define __SPECIAL_INSTRUCTION_PREAMBLE \
549  "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \
550  "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
551 
552 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
553  _zzq_default, _zzq_request, \
554  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
555  \
556  __extension__ \
557  ({volatile unsigned int _zzq_args[6]; \
558  volatile unsigned int _zzq_result; \
559  _zzq_args[0] = (unsigned int)(_zzq_request); \
560  _zzq_args[1] = (unsigned int)(_zzq_arg1); \
561  _zzq_args[2] = (unsigned int)(_zzq_arg2); \
562  _zzq_args[3] = (unsigned int)(_zzq_arg3); \
563  _zzq_args[4] = (unsigned int)(_zzq_arg4); \
564  _zzq_args[5] = (unsigned int)(_zzq_arg5); \
565  __asm__ volatile("mov r3, %1\n\t" /*default*/ \
566  "mov r4, %2\n\t" /*ptr*/ \
567  __SPECIAL_INSTRUCTION_PREAMBLE \
568  /* R3 = client_request ( R4 ) */ \
569  "orr r10, r10, r10\n\t" \
570  "mov %0, r3" /*result*/ \
571  : "=r" (_zzq_result) \
572  : "r" (_zzq_default), "r" (&_zzq_args[0]) \
573  : "cc","memory", "r3", "r4"); \
574  _zzq_result; \
575  })
576 
577 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
578  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
579  unsigned int __addr; \
580  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
581  /* R3 = guest_NRADDR */ \
582  "orr r11, r11, r11\n\t" \
583  "mov %0, r3" \
584  : "=r" (__addr) \
585  : \
586  : "cc", "memory", "r3" \
587  ); \
588  _zzq_orig->nraddr = __addr; \
589  }
590 
591 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
592  __SPECIAL_INSTRUCTION_PREAMBLE \
593  /* branch-and-link-to-noredir *%R4 */ \
594  "orr r12, r12, r12\n\t"
595 
596 #endif /* PLAT_arm_linux */
597 
598 /* ------------------------ s390x-linux ------------------------ */
599 
600 #if defined(PLAT_s390x_linux)
601 
602 typedef
603  struct {
604  unsigned long long int nraddr; /* where's the code? */
605  }
606  OrigFn;
607 
608 /* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
609  * code. This detection is implemented in platform specific toIR.c
610  * (e.g. VEX/priv/guest_s390_decoder.c).
611  */
612 #define __SPECIAL_INSTRUCTION_PREAMBLE \
613  "lr 15,15\n\t" \
614  "lr 1,1\n\t" \
615  "lr 2,2\n\t" \
616  "lr 3,3\n\t"
617 
618 #define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
619 #define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
620 #define __CALL_NO_REDIR_CODE "lr 4,4\n\t"
621 
622 #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
623  _zzq_default, _zzq_request, \
624  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
625  __extension__ \
626  ({volatile unsigned long long int _zzq_args[6]; \
627  volatile unsigned long long int _zzq_result; \
628  _zzq_args[0] = (unsigned long long int)(_zzq_request); \
629  _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
630  _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
631  _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
632  _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
633  _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
634  __asm__ volatile(/* r2 = args */ \
635  "lgr 2,%1\n\t" \
636  /* r3 = default */ \
637  "lgr 3,%2\n\t" \
638  __SPECIAL_INSTRUCTION_PREAMBLE \
639  __CLIENT_REQUEST_CODE \
640  /* results = r3 */ \
641  "lgr %0, 3\n\t" \
642  : "=d" (_zzq_result) \
643  : "a" (&_zzq_args[0]), "0" (_zzq_default) \
644  : "cc", "2", "3", "memory" \
645  ); \
646  _zzq_result; \
647  })
648 
649 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
650  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
651  volatile unsigned long long int __addr; \
652  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
653  __GET_NR_CONTEXT_CODE \
654  "lgr %0, 3\n\t" \
655  : "=a" (__addr) \
656  : \
657  : "cc", "3", "memory" \
658  ); \
659  _zzq_orig->nraddr = __addr; \
660  }
661 
662 #define VALGRIND_CALL_NOREDIR_R1 \
663  __SPECIAL_INSTRUCTION_PREAMBLE \
664  __CALL_NO_REDIR_CODE
665 
666 #endif /* PLAT_s390x_linux */
667 
668 /* Insert assembly code for other platforms here... */
669 
670 #endif /* NVALGRIND */
671 
672 
673 /* ------------------------------------------------------------------ */
674 /* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */
675 /* ugly. It's the least-worst tradeoff I can think of. */
676 /* ------------------------------------------------------------------ */
677 
678 /* This section defines magic (a.k.a appalling-hack) macros for doing
679  guaranteed-no-redirection macros, so as to get from function
680  wrappers to the functions they are wrapping. The whole point is to
681  construct standard call sequences, but to do the call itself with a
682  special no-redirect call pseudo-instruction that the JIT
683  understands and handles specially. This section is long and
684  repetitious, and I can't see a way to make it shorter.
685 
686  The naming scheme is as follows:
687 
688  CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
689 
690  'W' stands for "word" and 'v' for "void". Hence there are
691  different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
692  and for each, the possibility of returning a word-typed result, or
693  no result.
694 */
695 
696 /* Use these to write the name of your wrapper. NOTE: duplicates
697  VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts
698  the default behaviour equivalance class tag "0000" into the name.
699  See pub_tool_redir.h for details -- normally you don't need to
700  think about this, though. */
701 
702 /* Use an extra level of macroisation so as to ensure the soname/fnname
703  args are fully macro-expanded before pasting them together. */
704 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
705 
706 #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
707  VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
708 
709 #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
710  VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
711 
712 /* Use this macro from within a wrapper function to collect the
713  context (address and possibly other info) of the original function.
714  Once you have that you can then use it in one of the CALL_FN_
715  macros. The type of the argument _lval is OrigFn. */
716 #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
717 
718 /* Derivatives of the main macros below, for calling functions
719  returning void. */
720 
721 #define CALL_FN_v_v(fnptr) \
722  do { volatile unsigned long _junk; \
723  CALL_FN_W_v(_junk,fnptr); } while (0)
724 
725 #define CALL_FN_v_W(fnptr, arg1) \
726  do { volatile unsigned long _junk; \
727  CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
728 
729 #define CALL_FN_v_WW(fnptr, arg1,arg2) \
730  do { volatile unsigned long _junk; \
731  CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
732 
733 #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \
734  do { volatile unsigned long _junk; \
735  CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
736 
737 #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \
738  do { volatile unsigned long _junk; \
739  CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
740 
741 #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \
742  do { volatile unsigned long _junk; \
743  CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
744 
745 #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \
746  do { volatile unsigned long _junk; \
747  CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
748 
749 #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \
750  do { volatile unsigned long _junk; \
751  CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
752 
753 /* ------------------------- x86-{linux,darwin} ---------------- */
754 
755 #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin)
756 
757 /* These regs are trashed by the hidden call. No need to mention eax
758  as gcc can already see that, plus causes gcc to bomb. */
759 #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
760 
761 /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
762  long) == 4. */
763 
764 #define CALL_FN_W_v(lval, orig) \
765  do { \
766  volatile OrigFn _orig = (orig); \
767  volatile unsigned long _argvec[1]; \
768  volatile unsigned long _res; \
769  _argvec[0] = (unsigned long)_orig.nraddr; \
770  __asm__ volatile( \
771  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
772  VALGRIND_CALL_NOREDIR_EAX \
773  : /*out*/ "=a" (_res) \
774  : /*in*/ "a" (&_argvec[0]) \
775  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
776  ); \
777  lval = (__typeof__(lval)) _res; \
778  } while (0)
779 
780 #define CALL_FN_W_W(lval, orig, arg1) \
781  do { \
782  volatile OrigFn _orig = (orig); \
783  volatile unsigned long _argvec[2]; \
784  volatile unsigned long _res; \
785  _argvec[0] = (unsigned long)_orig.nraddr; \
786  _argvec[1] = (unsigned long)(arg1); \
787  __asm__ volatile( \
788  "subl $12, %%esp\n\t" \
789  "pushl 4(%%eax)\n\t" \
790  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
791  VALGRIND_CALL_NOREDIR_EAX \
792  "addl $16, %%esp\n" \
793  : /*out*/ "=a" (_res) \
794  : /*in*/ "a" (&_argvec[0]) \
795  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
796  ); \
797  lval = (__typeof__(lval)) _res; \
798  } while (0)
799 
800 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
801  do { \
802  volatile OrigFn _orig = (orig); \
803  volatile unsigned long _argvec[3]; \
804  volatile unsigned long _res; \
805  _argvec[0] = (unsigned long)_orig.nraddr; \
806  _argvec[1] = (unsigned long)(arg1); \
807  _argvec[2] = (unsigned long)(arg2); \
808  __asm__ volatile( \
809  "subl $8, %%esp\n\t" \
810  "pushl 8(%%eax)\n\t" \
811  "pushl 4(%%eax)\n\t" \
812  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
813  VALGRIND_CALL_NOREDIR_EAX \
814  "addl $16, %%esp\n" \
815  : /*out*/ "=a" (_res) \
816  : /*in*/ "a" (&_argvec[0]) \
817  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
818  ); \
819  lval = (__typeof__(lval)) _res; \
820  } while (0)
821 
822 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
823  do { \
824  volatile OrigFn _orig = (orig); \
825  volatile unsigned long _argvec[4]; \
826  volatile unsigned long _res; \
827  _argvec[0] = (unsigned long)_orig.nraddr; \
828  _argvec[1] = (unsigned long)(arg1); \
829  _argvec[2] = (unsigned long)(arg2); \
830  _argvec[3] = (unsigned long)(arg3); \
831  __asm__ volatile( \
832  "subl $4, %%esp\n\t" \
833  "pushl 12(%%eax)\n\t" \
834  "pushl 8(%%eax)\n\t" \
835  "pushl 4(%%eax)\n\t" \
836  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
837  VALGRIND_CALL_NOREDIR_EAX \
838  "addl $16, %%esp\n" \
839  : /*out*/ "=a" (_res) \
840  : /*in*/ "a" (&_argvec[0]) \
841  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
842  ); \
843  lval = (__typeof__(lval)) _res; \
844  } while (0)
845 
846 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
847  do { \
848  volatile OrigFn _orig = (orig); \
849  volatile unsigned long _argvec[5]; \
850  volatile unsigned long _res; \
851  _argvec[0] = (unsigned long)_orig.nraddr; \
852  _argvec[1] = (unsigned long)(arg1); \
853  _argvec[2] = (unsigned long)(arg2); \
854  _argvec[3] = (unsigned long)(arg3); \
855  _argvec[4] = (unsigned long)(arg4); \
856  __asm__ volatile( \
857  "pushl 16(%%eax)\n\t" \
858  "pushl 12(%%eax)\n\t" \
859  "pushl 8(%%eax)\n\t" \
860  "pushl 4(%%eax)\n\t" \
861  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
862  VALGRIND_CALL_NOREDIR_EAX \
863  "addl $16, %%esp\n" \
864  : /*out*/ "=a" (_res) \
865  : /*in*/ "a" (&_argvec[0]) \
866  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
867  ); \
868  lval = (__typeof__(lval)) _res; \
869  } while (0)
870 
871 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
872  do { \
873  volatile OrigFn _orig = (orig); \
874  volatile unsigned long _argvec[6]; \
875  volatile unsigned long _res; \
876  _argvec[0] = (unsigned long)_orig.nraddr; \
877  _argvec[1] = (unsigned long)(arg1); \
878  _argvec[2] = (unsigned long)(arg2); \
879  _argvec[3] = (unsigned long)(arg3); \
880  _argvec[4] = (unsigned long)(arg4); \
881  _argvec[5] = (unsigned long)(arg5); \
882  __asm__ volatile( \
883  "subl $12, %%esp\n\t" \
884  "pushl 20(%%eax)\n\t" \
885  "pushl 16(%%eax)\n\t" \
886  "pushl 12(%%eax)\n\t" \
887  "pushl 8(%%eax)\n\t" \
888  "pushl 4(%%eax)\n\t" \
889  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
890  VALGRIND_CALL_NOREDIR_EAX \
891  "addl $32, %%esp\n" \
892  : /*out*/ "=a" (_res) \
893  : /*in*/ "a" (&_argvec[0]) \
894  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
895  ); \
896  lval = (__typeof__(lval)) _res; \
897  } while (0)
898 
899 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
900  do { \
901  volatile OrigFn _orig = (orig); \
902  volatile unsigned long _argvec[7]; \
903  volatile unsigned long _res; \
904  _argvec[0] = (unsigned long)_orig.nraddr; \
905  _argvec[1] = (unsigned long)(arg1); \
906  _argvec[2] = (unsigned long)(arg2); \
907  _argvec[3] = (unsigned long)(arg3); \
908  _argvec[4] = (unsigned long)(arg4); \
909  _argvec[5] = (unsigned long)(arg5); \
910  _argvec[6] = (unsigned long)(arg6); \
911  __asm__ volatile( \
912  "subl $8, %%esp\n\t" \
913  "pushl 24(%%eax)\n\t" \
914  "pushl 20(%%eax)\n\t" \
915  "pushl 16(%%eax)\n\t" \
916  "pushl 12(%%eax)\n\t" \
917  "pushl 8(%%eax)\n\t" \
918  "pushl 4(%%eax)\n\t" \
919  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
920  VALGRIND_CALL_NOREDIR_EAX \
921  "addl $32, %%esp\n" \
922  : /*out*/ "=a" (_res) \
923  : /*in*/ "a" (&_argvec[0]) \
924  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
925  ); \
926  lval = (__typeof__(lval)) _res; \
927  } while (0)
928 
929 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
930  arg7) \
931  do { \
932  volatile OrigFn _orig = (orig); \
933  volatile unsigned long _argvec[8]; \
934  volatile unsigned long _res; \
935  _argvec[0] = (unsigned long)_orig.nraddr; \
936  _argvec[1] = (unsigned long)(arg1); \
937  _argvec[2] = (unsigned long)(arg2); \
938  _argvec[3] = (unsigned long)(arg3); \
939  _argvec[4] = (unsigned long)(arg4); \
940  _argvec[5] = (unsigned long)(arg5); \
941  _argvec[6] = (unsigned long)(arg6); \
942  _argvec[7] = (unsigned long)(arg7); \
943  __asm__ volatile( \
944  "subl $4, %%esp\n\t" \
945  "pushl 28(%%eax)\n\t" \
946  "pushl 24(%%eax)\n\t" \
947  "pushl 20(%%eax)\n\t" \
948  "pushl 16(%%eax)\n\t" \
949  "pushl 12(%%eax)\n\t" \
950  "pushl 8(%%eax)\n\t" \
951  "pushl 4(%%eax)\n\t" \
952  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
953  VALGRIND_CALL_NOREDIR_EAX \
954  "addl $32, %%esp\n" \
955  : /*out*/ "=a" (_res) \
956  : /*in*/ "a" (&_argvec[0]) \
957  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
958  ); \
959  lval = (__typeof__(lval)) _res; \
960  } while (0)
961 
962 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
963  arg7,arg8) \
964  do { \
965  volatile OrigFn _orig = (orig); \
966  volatile unsigned long _argvec[9]; \
967  volatile unsigned long _res; \
968  _argvec[0] = (unsigned long)_orig.nraddr; \
969  _argvec[1] = (unsigned long)(arg1); \
970  _argvec[2] = (unsigned long)(arg2); \
971  _argvec[3] = (unsigned long)(arg3); \
972  _argvec[4] = (unsigned long)(arg4); \
973  _argvec[5] = (unsigned long)(arg5); \
974  _argvec[6] = (unsigned long)(arg6); \
975  _argvec[7] = (unsigned long)(arg7); \
976  _argvec[8] = (unsigned long)(arg8); \
977  __asm__ volatile( \
978  "pushl 32(%%eax)\n\t" \
979  "pushl 28(%%eax)\n\t" \
980  "pushl 24(%%eax)\n\t" \
981  "pushl 20(%%eax)\n\t" \
982  "pushl 16(%%eax)\n\t" \
983  "pushl 12(%%eax)\n\t" \
984  "pushl 8(%%eax)\n\t" \
985  "pushl 4(%%eax)\n\t" \
986  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
987  VALGRIND_CALL_NOREDIR_EAX \
988  "addl $32, %%esp\n" \
989  : /*out*/ "=a" (_res) \
990  : /*in*/ "a" (&_argvec[0]) \
991  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
992  ); \
993  lval = (__typeof__(lval)) _res; \
994  } while (0)
995 
996 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
997  arg7,arg8,arg9) \
998  do { \
999  volatile OrigFn _orig = (orig); \
1000  volatile unsigned long _argvec[10]; \
1001  volatile unsigned long _res; \
1002  _argvec[0] = (unsigned long)_orig.nraddr; \
1003  _argvec[1] = (unsigned long)(arg1); \
1004  _argvec[2] = (unsigned long)(arg2); \
1005  _argvec[3] = (unsigned long)(arg3); \
1006  _argvec[4] = (unsigned long)(arg4); \
1007  _argvec[5] = (unsigned long)(arg5); \
1008  _argvec[6] = (unsigned long)(arg6); \
1009  _argvec[7] = (unsigned long)(arg7); \
1010  _argvec[8] = (unsigned long)(arg8); \
1011  _argvec[9] = (unsigned long)(arg9); \
1012  __asm__ volatile( \
1013  "subl $12, %%esp\n\t" \
1014  "pushl 36(%%eax)\n\t" \
1015  "pushl 32(%%eax)\n\t" \
1016  "pushl 28(%%eax)\n\t" \
1017  "pushl 24(%%eax)\n\t" \
1018  "pushl 20(%%eax)\n\t" \
1019  "pushl 16(%%eax)\n\t" \
1020  "pushl 12(%%eax)\n\t" \
1021  "pushl 8(%%eax)\n\t" \
1022  "pushl 4(%%eax)\n\t" \
1023  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1024  VALGRIND_CALL_NOREDIR_EAX \
1025  "addl $48, %%esp\n" \
1026  : /*out*/ "=a" (_res) \
1027  : /*in*/ "a" (&_argvec[0]) \
1028  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1029  ); \
1030  lval = (__typeof__(lval)) _res; \
1031  } while (0)
1032 
1033 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1034  arg7,arg8,arg9,arg10) \
1035  do { \
1036  volatile OrigFn _orig = (orig); \
1037  volatile unsigned long _argvec[11]; \
1038  volatile unsigned long _res; \
1039  _argvec[0] = (unsigned long)_orig.nraddr; \
1040  _argvec[1] = (unsigned long)(arg1); \
1041  _argvec[2] = (unsigned long)(arg2); \
1042  _argvec[3] = (unsigned long)(arg3); \
1043  _argvec[4] = (unsigned long)(arg4); \
1044  _argvec[5] = (unsigned long)(arg5); \
1045  _argvec[6] = (unsigned long)(arg6); \
1046  _argvec[7] = (unsigned long)(arg7); \
1047  _argvec[8] = (unsigned long)(arg8); \
1048  _argvec[9] = (unsigned long)(arg9); \
1049  _argvec[10] = (unsigned long)(arg10); \
1050  __asm__ volatile( \
1051  "subl $8, %%esp\n\t" \
1052  "pushl 40(%%eax)\n\t" \
1053  "pushl 36(%%eax)\n\t" \
1054  "pushl 32(%%eax)\n\t" \
1055  "pushl 28(%%eax)\n\t" \
1056  "pushl 24(%%eax)\n\t" \
1057  "pushl 20(%%eax)\n\t" \
1058  "pushl 16(%%eax)\n\t" \
1059  "pushl 12(%%eax)\n\t" \
1060  "pushl 8(%%eax)\n\t" \
1061  "pushl 4(%%eax)\n\t" \
1062  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1063  VALGRIND_CALL_NOREDIR_EAX \
1064  "addl $48, %%esp\n" \
1065  : /*out*/ "=a" (_res) \
1066  : /*in*/ "a" (&_argvec[0]) \
1067  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1068  ); \
1069  lval = (__typeof__(lval)) _res; \
1070  } while (0)
1071 
1072 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
1073  arg6,arg7,arg8,arg9,arg10, \
1074  arg11) \
1075  do { \
1076  volatile OrigFn _orig = (orig); \
1077  volatile unsigned long _argvec[12]; \
1078  volatile unsigned long _res; \
1079  _argvec[0] = (unsigned long)_orig.nraddr; \
1080  _argvec[1] = (unsigned long)(arg1); \
1081  _argvec[2] = (unsigned long)(arg2); \
1082  _argvec[3] = (unsigned long)(arg3); \
1083  _argvec[4] = (unsigned long)(arg4); \
1084  _argvec[5] = (unsigned long)(arg5); \
1085  _argvec[6] = (unsigned long)(arg6); \
1086  _argvec[7] = (unsigned long)(arg7); \
1087  _argvec[8] = (unsigned long)(arg8); \
1088  _argvec[9] = (unsigned long)(arg9); \
1089  _argvec[10] = (unsigned long)(arg10); \
1090  _argvec[11] = (unsigned long)(arg11); \
1091  __asm__ volatile( \
1092  "subl $4, %%esp\n\t" \
1093  "pushl 44(%%eax)\n\t" \
1094  "pushl 40(%%eax)\n\t" \
1095  "pushl 36(%%eax)\n\t" \
1096  "pushl 32(%%eax)\n\t" \
1097  "pushl 28(%%eax)\n\t" \
1098  "pushl 24(%%eax)\n\t" \
1099  "pushl 20(%%eax)\n\t" \
1100  "pushl 16(%%eax)\n\t" \
1101  "pushl 12(%%eax)\n\t" \
1102  "pushl 8(%%eax)\n\t" \
1103  "pushl 4(%%eax)\n\t" \
1104  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1105  VALGRIND_CALL_NOREDIR_EAX \
1106  "addl $48, %%esp\n" \
1107  : /*out*/ "=a" (_res) \
1108  : /*in*/ "a" (&_argvec[0]) \
1109  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1110  ); \
1111  lval = (__typeof__(lval)) _res; \
1112  } while (0)
1113 
1114 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
1115  arg6,arg7,arg8,arg9,arg10, \
1116  arg11,arg12) \
1117  do { \
1118  volatile OrigFn _orig = (orig); \
1119  volatile unsigned long _argvec[13]; \
1120  volatile unsigned long _res; \
1121  _argvec[0] = (unsigned long)_orig.nraddr; \
1122  _argvec[1] = (unsigned long)(arg1); \
1123  _argvec[2] = (unsigned long)(arg2); \
1124  _argvec[3] = (unsigned long)(arg3); \
1125  _argvec[4] = (unsigned long)(arg4); \
1126  _argvec[5] = (unsigned long)(arg5); \
1127  _argvec[6] = (unsigned long)(arg6); \
1128  _argvec[7] = (unsigned long)(arg7); \
1129  _argvec[8] = (unsigned long)(arg8); \
1130  _argvec[9] = (unsigned long)(arg9); \
1131  _argvec[10] = (unsigned long)(arg10); \
1132  _argvec[11] = (unsigned long)(arg11); \
1133  _argvec[12] = (unsigned long)(arg12); \
1134  __asm__ volatile( \
1135  "pushl 48(%%eax)\n\t" \
1136  "pushl 44(%%eax)\n\t" \
1137  "pushl 40(%%eax)\n\t" \
1138  "pushl 36(%%eax)\n\t" \
1139  "pushl 32(%%eax)\n\t" \
1140  "pushl 28(%%eax)\n\t" \
1141  "pushl 24(%%eax)\n\t" \
1142  "pushl 20(%%eax)\n\t" \
1143  "pushl 16(%%eax)\n\t" \
1144  "pushl 12(%%eax)\n\t" \
1145  "pushl 8(%%eax)\n\t" \
1146  "pushl 4(%%eax)\n\t" \
1147  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1148  VALGRIND_CALL_NOREDIR_EAX \
1149  "addl $48, %%esp\n" \
1150  : /*out*/ "=a" (_res) \
1151  : /*in*/ "a" (&_argvec[0]) \
1152  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1153  ); \
1154  lval = (__typeof__(lval)) _res; \
1155  } while (0)
1156 
1157 #endif /* PLAT_x86_linux || PLAT_x86_darwin */
1158 
1159 /* ------------------------ amd64-{linux,darwin} --------------- */
1160 
1161 #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
1162 
1163 /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1164 
1165 /* These regs are trashed by the hidden call. */
1166 #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
1167  "rdi", "r8", "r9", "r10", "r11"
1168 
1169 /* This is all pretty complex. It's so as to make stack unwinding
1170  work reliably. See bug 243270. The basic problem is the sub and
1171  add of 128 of %rsp in all of the following macros. If gcc believes
1172  the CFA is in %rsp, then unwinding may fail, because what's at the
1173  CFA is not what gcc "expected" when it constructs the CFIs for the
1174  places where the macros are instantiated.
1175 
1176  But we can't just add a CFI annotation to increase the CFA offset
1177  by 128, to match the sub of 128 from %rsp, because we don't know
1178  whether gcc has chosen %rsp as the CFA at that point, or whether it
1179  has chosen some other register (eg, %rbp). In the latter case,
1180  adding a CFI annotation to change the CFA offset is simply wrong.
1181 
1182  So the solution is to get hold of the CFA using
1183  __builtin_dwarf_cfa(), put it in a known register, and add a
1184  CFI annotation to say what the register is. We choose %rbp for
1185  this (perhaps perversely), because:
1186 
1187  (1) %rbp is already subject to unwinding. If a new register was
1188  chosen then the unwinder would have to unwind it in all stack
1189  traces, which is expensive, and
1190 
1191  (2) %rbp is already subject to precise exception updates in the
1192  JIT. If a new register was chosen, we'd have to have precise
1193  exceptions for it too, which reduces performance of the
1194  generated code.
1195 
1196  However .. one extra complication. We can't just whack the result
1197  of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1198  list of trashed registers at the end of the inline assembly
1199  fragments; gcc won't allow %rbp to appear in that list. Hence
1200  instead we need to stash %rbp in %r15 for the duration of the asm,
1201  and say that %r15 is trashed instead. gcc seems happy to go with
1202  that.
1203 
1204  Oh .. and this all needs to be conditionalised so that it is
1205  unchanged from before this commit, when compiled with older gccs
1206  that don't support __builtin_dwarf_cfa. Furthermore, since
1207  this header file is freestanding, it has to be independent of
1208  config.h, and so the following conditionalisation cannot depend on
1209  configure time checks.
1210 
1211  Although it's not clear from
1212  'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
1213  this expression excludes Darwin.
1214  .cfi directives in Darwin assembly appear to be completely
1215  different and I haven't investigated how they work.
1216 
1217  For even more entertainment value, note we have to use the
1218  completely undocumented __builtin_dwarf_cfa(), which appears to
1219  really compute the CFA, whereas __builtin_frame_address(0) claims
1220  to but actually doesn't. See
1221  https://bugs.kde.org/show_bug.cgi?id=243270#c47
1222 */
1223 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1224 # define __FRAME_POINTER \
1225  ,"r"(__builtin_dwarf_cfa())
1226 # define VALGRIND_CFI_PROLOGUE \
1227  "movq %%rbp, %%r15\n\t" \
1228  "movq %2, %%rbp\n\t" \
1229  ".cfi_remember_state\n\t" \
1230  ".cfi_def_cfa rbp, 0\n\t"
1231 # define VALGRIND_CFI_EPILOGUE \
1232  "movq %%r15, %%rbp\n\t" \
1233  ".cfi_restore_state\n\t"
1234 #else
1235 # define __FRAME_POINTER
1236 # define VALGRIND_CFI_PROLOGUE
1237 # define VALGRIND_CFI_EPILOGUE
1238 #endif
1239 
1240 
1241 /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1242  long) == 8. */
1243 
1244 /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_
1245  macros. In order not to trash the stack redzone, we need to drop
1246  %rsp by 128 before the hidden call, and restore afterwards. The
1247  nastyness is that it is only by luck that the stack still appears
1248  to be unwindable during the hidden call - since then the behaviour
1249  of any routine using this macro does not match what the CFI data
1250  says. Sigh.
1251 
1252  Why is this important? Imagine that a wrapper has a stack
1253  allocated local, and passes to the hidden call, a pointer to it.
1254  Because gcc does not know about the hidden call, it may allocate
1255  that local in the redzone. Unfortunately the hidden call may then
1256  trash it before it comes to use it. So we must step clear of the
1257  redzone, for the duration of the hidden call, to make it safe.
1258 
1259  Probably the same problem afflicts the other redzone-style ABIs too
1260  (ppc64-linux); but for those, the stack is
1261  self describing (none of this CFI nonsense) so at least messing
1262  with the stack pointer doesn't give a danger of non-unwindable
1263  stack. */
1264 
1265 #define CALL_FN_W_v(lval, orig) \
1266  do { \
1267  volatile OrigFn _orig = (orig); \
1268  volatile unsigned long _argvec[1]; \
1269  volatile unsigned long _res; \
1270  _argvec[0] = (unsigned long)_orig.nraddr; \
1271  __asm__ volatile( \
1272  VALGRIND_CFI_PROLOGUE \
1273  "subq $128,%%rsp\n\t" \
1274  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1275  VALGRIND_CALL_NOREDIR_RAX \
1276  "addq $128,%%rsp\n\t" \
1277  VALGRIND_CFI_EPILOGUE \
1278  : /*out*/ "=a" (_res) \
1279  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1280  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1281  ); \
1282  lval = (__typeof__(lval)) _res; \
1283  } while (0)
1284 
1285 #define CALL_FN_W_W(lval, orig, arg1) \
1286  do { \
1287  volatile OrigFn _orig = (orig); \
1288  volatile unsigned long _argvec[2]; \
1289  volatile unsigned long _res; \
1290  _argvec[0] = (unsigned long)_orig.nraddr; \
1291  _argvec[1] = (unsigned long)(arg1); \
1292  __asm__ volatile( \
1293  VALGRIND_CFI_PROLOGUE \
1294  "subq $128,%%rsp\n\t" \
1295  "movq 8(%%rax), %%rdi\n\t" \
1296  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1297  VALGRIND_CALL_NOREDIR_RAX \
1298  "addq $128,%%rsp\n\t" \
1299  VALGRIND_CFI_EPILOGUE \
1300  : /*out*/ "=a" (_res) \
1301  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1302  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1303  ); \
1304  lval = (__typeof__(lval)) _res; \
1305  } while (0)
1306 
1307 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1308  do { \
1309  volatile OrigFn _orig = (orig); \
1310  volatile unsigned long _argvec[3]; \
1311  volatile unsigned long _res; \
1312  _argvec[0] = (unsigned long)_orig.nraddr; \
1313  _argvec[1] = (unsigned long)(arg1); \
1314  _argvec[2] = (unsigned long)(arg2); \
1315  __asm__ volatile( \
1316  VALGRIND_CFI_PROLOGUE \
1317  "subq $128,%%rsp\n\t" \
1318  "movq 16(%%rax), %%rsi\n\t" \
1319  "movq 8(%%rax), %%rdi\n\t" \
1320  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1321  VALGRIND_CALL_NOREDIR_RAX \
1322  "addq $128,%%rsp\n\t" \
1323  VALGRIND_CFI_EPILOGUE \
1324  : /*out*/ "=a" (_res) \
1325  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1326  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1327  ); \
1328  lval = (__typeof__(lval)) _res; \
1329  } while (0)
1330 
1331 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1332  do { \
1333  volatile OrigFn _orig = (orig); \
1334  volatile unsigned long _argvec[4]; \
1335  volatile unsigned long _res; \
1336  _argvec[0] = (unsigned long)_orig.nraddr; \
1337  _argvec[1] = (unsigned long)(arg1); \
1338  _argvec[2] = (unsigned long)(arg2); \
1339  _argvec[3] = (unsigned long)(arg3); \
1340  __asm__ volatile( \
1341  VALGRIND_CFI_PROLOGUE \
1342  "subq $128,%%rsp\n\t" \
1343  "movq 24(%%rax), %%rdx\n\t" \
1344  "movq 16(%%rax), %%rsi\n\t" \
1345  "movq 8(%%rax), %%rdi\n\t" \
1346  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1347  VALGRIND_CALL_NOREDIR_RAX \
1348  "addq $128,%%rsp\n\t" \
1349  VALGRIND_CFI_EPILOGUE \
1350  : /*out*/ "=a" (_res) \
1351  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1352  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1353  ); \
1354  lval = (__typeof__(lval)) _res; \
1355  } while (0)
1356 
1357 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1358  do { \
1359  volatile OrigFn _orig = (orig); \
1360  volatile unsigned long _argvec[5]; \
1361  volatile unsigned long _res; \
1362  _argvec[0] = (unsigned long)_orig.nraddr; \
1363  _argvec[1] = (unsigned long)(arg1); \
1364  _argvec[2] = (unsigned long)(arg2); \
1365  _argvec[3] = (unsigned long)(arg3); \
1366  _argvec[4] = (unsigned long)(arg4); \
1367  __asm__ volatile( \
1368  VALGRIND_CFI_PROLOGUE \
1369  "subq $128,%%rsp\n\t" \
1370  "movq 32(%%rax), %%rcx\n\t" \
1371  "movq 24(%%rax), %%rdx\n\t" \
1372  "movq 16(%%rax), %%rsi\n\t" \
1373  "movq 8(%%rax), %%rdi\n\t" \
1374  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1375  VALGRIND_CALL_NOREDIR_RAX \
1376  "addq $128,%%rsp\n\t" \
1377  VALGRIND_CFI_EPILOGUE \
1378  : /*out*/ "=a" (_res) \
1379  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1380  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1381  ); \
1382  lval = (__typeof__(lval)) _res; \
1383  } while (0)
1384 
1385 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1386  do { \
1387  volatile OrigFn _orig = (orig); \
1388  volatile unsigned long _argvec[6]; \
1389  volatile unsigned long _res; \
1390  _argvec[0] = (unsigned long)_orig.nraddr; \
1391  _argvec[1] = (unsigned long)(arg1); \
1392  _argvec[2] = (unsigned long)(arg2); \
1393  _argvec[3] = (unsigned long)(arg3); \
1394  _argvec[4] = (unsigned long)(arg4); \
1395  _argvec[5] = (unsigned long)(arg5); \
1396  __asm__ volatile( \
1397  VALGRIND_CFI_PROLOGUE \
1398  "subq $128,%%rsp\n\t" \
1399  "movq 40(%%rax), %%r8\n\t" \
1400  "movq 32(%%rax), %%rcx\n\t" \
1401  "movq 24(%%rax), %%rdx\n\t" \
1402  "movq 16(%%rax), %%rsi\n\t" \
1403  "movq 8(%%rax), %%rdi\n\t" \
1404  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1405  VALGRIND_CALL_NOREDIR_RAX \
1406  "addq $128,%%rsp\n\t" \
1407  VALGRIND_CFI_EPILOGUE \
1408  : /*out*/ "=a" (_res) \
1409  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1410  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1411  ); \
1412  lval = (__typeof__(lval)) _res; \
1413  } while (0)
1414 
1415 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1416  do { \
1417  volatile OrigFn _orig = (orig); \
1418  volatile unsigned long _argvec[7]; \
1419  volatile unsigned long _res; \
1420  _argvec[0] = (unsigned long)_orig.nraddr; \
1421  _argvec[1] = (unsigned long)(arg1); \
1422  _argvec[2] = (unsigned long)(arg2); \
1423  _argvec[3] = (unsigned long)(arg3); \
1424  _argvec[4] = (unsigned long)(arg4); \
1425  _argvec[5] = (unsigned long)(arg5); \
1426  _argvec[6] = (unsigned long)(arg6); \
1427  __asm__ volatile( \
1428  VALGRIND_CFI_PROLOGUE \
1429  "subq $128,%%rsp\n\t" \
1430  "movq 48(%%rax), %%r9\n\t" \
1431  "movq 40(%%rax), %%r8\n\t" \
1432  "movq 32(%%rax), %%rcx\n\t" \
1433  "movq 24(%%rax), %%rdx\n\t" \
1434  "movq 16(%%rax), %%rsi\n\t" \
1435  "movq 8(%%rax), %%rdi\n\t" \
1436  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1437  VALGRIND_CALL_NOREDIR_RAX \
1438  "addq $128,%%rsp\n\t" \
1439  VALGRIND_CFI_EPILOGUE \
1440  : /*out*/ "=a" (_res) \
1441  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1442  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1443  ); \
1444  lval = (__typeof__(lval)) _res; \
1445  } while (0)
1446 
1447 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1448  arg7) \
1449  do { \
1450  volatile OrigFn _orig = (orig); \
1451  volatile unsigned long _argvec[8]; \
1452  volatile unsigned long _res; \
1453  _argvec[0] = (unsigned long)_orig.nraddr; \
1454  _argvec[1] = (unsigned long)(arg1); \
1455  _argvec[2] = (unsigned long)(arg2); \
1456  _argvec[3] = (unsigned long)(arg3); \
1457  _argvec[4] = (unsigned long)(arg4); \
1458  _argvec[5] = (unsigned long)(arg5); \
1459  _argvec[6] = (unsigned long)(arg6); \
1460  _argvec[7] = (unsigned long)(arg7); \
1461  __asm__ volatile( \
1462  VALGRIND_CFI_PROLOGUE \
1463  "subq $136,%%rsp\n\t" \
1464  "pushq 56(%%rax)\n\t" \
1465  "movq 48(%%rax), %%r9\n\t" \
1466  "movq 40(%%rax), %%r8\n\t" \
1467  "movq 32(%%rax), %%rcx\n\t" \
1468  "movq 24(%%rax), %%rdx\n\t" \
1469  "movq 16(%%rax), %%rsi\n\t" \
1470  "movq 8(%%rax), %%rdi\n\t" \
1471  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1472  VALGRIND_CALL_NOREDIR_RAX \
1473  "addq $8, %%rsp\n" \
1474  "addq $136,%%rsp\n\t" \
1475  VALGRIND_CFI_EPILOGUE \
1476  : /*out*/ "=a" (_res) \
1477  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1478  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1479  ); \
1480  lval = (__typeof__(lval)) _res; \
1481  } while (0)
1482 
1483 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1484  arg7,arg8) \
1485  do { \
1486  volatile OrigFn _orig = (orig); \
1487  volatile unsigned long _argvec[9]; \
1488  volatile unsigned long _res; \
1489  _argvec[0] = (unsigned long)_orig.nraddr; \
1490  _argvec[1] = (unsigned long)(arg1); \
1491  _argvec[2] = (unsigned long)(arg2); \
1492  _argvec[3] = (unsigned long)(arg3); \
1493  _argvec[4] = (unsigned long)(arg4); \
1494  _argvec[5] = (unsigned long)(arg5); \
1495  _argvec[6] = (unsigned long)(arg6); \
1496  _argvec[7] = (unsigned long)(arg7); \
1497  _argvec[8] = (unsigned long)(arg8); \
1498  __asm__ volatile( \
1499  VALGRIND_CFI_PROLOGUE \
1500  "subq $128,%%rsp\n\t" \
1501  "pushq 64(%%rax)\n\t" \
1502  "pushq 56(%%rax)\n\t" \
1503  "movq 48(%%rax), %%r9\n\t" \
1504  "movq 40(%%rax), %%r8\n\t" \
1505  "movq 32(%%rax), %%rcx\n\t" \
1506  "movq 24(%%rax), %%rdx\n\t" \
1507  "movq 16(%%rax), %%rsi\n\t" \
1508  "movq 8(%%rax), %%rdi\n\t" \
1509  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1510  VALGRIND_CALL_NOREDIR_RAX \
1511  "addq $16, %%rsp\n" \
1512  "addq $128,%%rsp\n\t" \
1513  VALGRIND_CFI_EPILOGUE \
1514  : /*out*/ "=a" (_res) \
1515  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1516  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1517  ); \
1518  lval = (__typeof__(lval)) _res; \
1519  } while (0)
1520 
1521 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1522  arg7,arg8,arg9) \
1523  do { \
1524  volatile OrigFn _orig = (orig); \
1525  volatile unsigned long _argvec[10]; \
1526  volatile unsigned long _res; \
1527  _argvec[0] = (unsigned long)_orig.nraddr; \
1528  _argvec[1] = (unsigned long)(arg1); \
1529  _argvec[2] = (unsigned long)(arg2); \
1530  _argvec[3] = (unsigned long)(arg3); \
1531  _argvec[4] = (unsigned long)(arg4); \
1532  _argvec[5] = (unsigned long)(arg5); \
1533  _argvec[6] = (unsigned long)(arg6); \
1534  _argvec[7] = (unsigned long)(arg7); \
1535  _argvec[8] = (unsigned long)(arg8); \
1536  _argvec[9] = (unsigned long)(arg9); \
1537  __asm__ volatile( \
1538  VALGRIND_CFI_PROLOGUE \
1539  "subq $136,%%rsp\n\t" \
1540  "pushq 72(%%rax)\n\t" \
1541  "pushq 64(%%rax)\n\t" \
1542  "pushq 56(%%rax)\n\t" \
1543  "movq 48(%%rax), %%r9\n\t" \
1544  "movq 40(%%rax), %%r8\n\t" \
1545  "movq 32(%%rax), %%rcx\n\t" \
1546  "movq 24(%%rax), %%rdx\n\t" \
1547  "movq 16(%%rax), %%rsi\n\t" \
1548  "movq 8(%%rax), %%rdi\n\t" \
1549  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1550  VALGRIND_CALL_NOREDIR_RAX \
1551  "addq $24, %%rsp\n" \
1552  "addq $136,%%rsp\n\t" \
1553  VALGRIND_CFI_EPILOGUE \
1554  : /*out*/ "=a" (_res) \
1555  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1556  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1557  ); \
1558  lval = (__typeof__(lval)) _res; \
1559  } while (0)
1560 
1561 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1562  arg7,arg8,arg9,arg10) \
1563  do { \
1564  volatile OrigFn _orig = (orig); \
1565  volatile unsigned long _argvec[11]; \
1566  volatile unsigned long _res; \
1567  _argvec[0] = (unsigned long)_orig.nraddr; \
1568  _argvec[1] = (unsigned long)(arg1); \
1569  _argvec[2] = (unsigned long)(arg2); \
1570  _argvec[3] = (unsigned long)(arg3); \
1571  _argvec[4] = (unsigned long)(arg4); \
1572  _argvec[5] = (unsigned long)(arg5); \
1573  _argvec[6] = (unsigned long)(arg6); \
1574  _argvec[7] = (unsigned long)(arg7); \
1575  _argvec[8] = (unsigned long)(arg8); \
1576  _argvec[9] = (unsigned long)(arg9); \
1577  _argvec[10] = (unsigned long)(arg10); \
1578  __asm__ volatile( \
1579  VALGRIND_CFI_PROLOGUE \
1580  "subq $128,%%rsp\n\t" \
1581  "pushq 80(%%rax)\n\t" \
1582  "pushq 72(%%rax)\n\t" \
1583  "pushq 64(%%rax)\n\t" \
1584  "pushq 56(%%rax)\n\t" \
1585  "movq 48(%%rax), %%r9\n\t" \
1586  "movq 40(%%rax), %%r8\n\t" \
1587  "movq 32(%%rax), %%rcx\n\t" \
1588  "movq 24(%%rax), %%rdx\n\t" \
1589  "movq 16(%%rax), %%rsi\n\t" \
1590  "movq 8(%%rax), %%rdi\n\t" \
1591  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1592  VALGRIND_CALL_NOREDIR_RAX \
1593  "addq $32, %%rsp\n" \
1594  "addq $128,%%rsp\n\t" \
1595  VALGRIND_CFI_EPILOGUE \
1596  : /*out*/ "=a" (_res) \
1597  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1598  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1599  ); \
1600  lval = (__typeof__(lval)) _res; \
1601  } while (0)
1602 
1603 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1604  arg7,arg8,arg9,arg10,arg11) \
1605  do { \
1606  volatile OrigFn _orig = (orig); \
1607  volatile unsigned long _argvec[12]; \
1608  volatile unsigned long _res; \
1609  _argvec[0] = (unsigned long)_orig.nraddr; \
1610  _argvec[1] = (unsigned long)(arg1); \
1611  _argvec[2] = (unsigned long)(arg2); \
1612  _argvec[3] = (unsigned long)(arg3); \
1613  _argvec[4] = (unsigned long)(arg4); \
1614  _argvec[5] = (unsigned long)(arg5); \
1615  _argvec[6] = (unsigned long)(arg6); \
1616  _argvec[7] = (unsigned long)(arg7); \
1617  _argvec[8] = (unsigned long)(arg8); \
1618  _argvec[9] = (unsigned long)(arg9); \
1619  _argvec[10] = (unsigned long)(arg10); \
1620  _argvec[11] = (unsigned long)(arg11); \
1621  __asm__ volatile( \
1622  VALGRIND_CFI_PROLOGUE \
1623  "subq $136,%%rsp\n\t" \
1624  "pushq 88(%%rax)\n\t" \
1625  "pushq 80(%%rax)\n\t" \
1626  "pushq 72(%%rax)\n\t" \
1627  "pushq 64(%%rax)\n\t" \
1628  "pushq 56(%%rax)\n\t" \
1629  "movq 48(%%rax), %%r9\n\t" \
1630  "movq 40(%%rax), %%r8\n\t" \
1631  "movq 32(%%rax), %%rcx\n\t" \
1632  "movq 24(%%rax), %%rdx\n\t" \
1633  "movq 16(%%rax), %%rsi\n\t" \
1634  "movq 8(%%rax), %%rdi\n\t" \
1635  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1636  VALGRIND_CALL_NOREDIR_RAX \
1637  "addq $40, %%rsp\n" \
1638  "addq $136,%%rsp\n\t" \
1639  VALGRIND_CFI_EPILOGUE \
1640  : /*out*/ "=a" (_res) \
1641  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1642  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1643  ); \
1644  lval = (__typeof__(lval)) _res; \
1645  } while (0)
1646 
1647 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1648  arg7,arg8,arg9,arg10,arg11,arg12) \
1649  do { \
1650  volatile OrigFn _orig = (orig); \
1651  volatile unsigned long _argvec[13]; \
1652  volatile unsigned long _res; \
1653  _argvec[0] = (unsigned long)_orig.nraddr; \
1654  _argvec[1] = (unsigned long)(arg1); \
1655  _argvec[2] = (unsigned long)(arg2); \
1656  _argvec[3] = (unsigned long)(arg3); \
1657  _argvec[4] = (unsigned long)(arg4); \
1658  _argvec[5] = (unsigned long)(arg5); \
1659  _argvec[6] = (unsigned long)(arg6); \
1660  _argvec[7] = (unsigned long)(arg7); \
1661  _argvec[8] = (unsigned long)(arg8); \
1662  _argvec[9] = (unsigned long)(arg9); \
1663  _argvec[10] = (unsigned long)(arg10); \
1664  _argvec[11] = (unsigned long)(arg11); \
1665  _argvec[12] = (unsigned long)(arg12); \
1666  __asm__ volatile( \
1667  VALGRIND_CFI_PROLOGUE \
1668  "subq $128,%%rsp\n\t" \
1669  "pushq 96(%%rax)\n\t" \
1670  "pushq 88(%%rax)\n\t" \
1671  "pushq 80(%%rax)\n\t" \
1672  "pushq 72(%%rax)\n\t" \
1673  "pushq 64(%%rax)\n\t" \
1674  "pushq 56(%%rax)\n\t" \
1675  "movq 48(%%rax), %%r9\n\t" \
1676  "movq 40(%%rax), %%r8\n\t" \
1677  "movq 32(%%rax), %%rcx\n\t" \
1678  "movq 24(%%rax), %%rdx\n\t" \
1679  "movq 16(%%rax), %%rsi\n\t" \
1680  "movq 8(%%rax), %%rdi\n\t" \
1681  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1682  VALGRIND_CALL_NOREDIR_RAX \
1683  "addq $48, %%rsp\n" \
1684  "addq $128,%%rsp\n\t" \
1685  VALGRIND_CFI_EPILOGUE \
1686  : /*out*/ "=a" (_res) \
1687  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1688  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1689  ); \
1690  lval = (__typeof__(lval)) _res; \
1691  } while (0)
1692 
1693 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
1694 
1695 /* ------------------------ ppc32-linux ------------------------ */
1696 
1697 #if defined(PLAT_ppc32_linux)
1698 
1699 /* This is useful for finding out about the on-stack stuff:
1700 
1701  extern int f9 ( int,int,int,int,int,int,int,int,int );
1702  extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1703  extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1704  extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1705 
1706  int g9 ( void ) {
1707  return f9(11,22,33,44,55,66,77,88,99);
1708  }
1709  int g10 ( void ) {
1710  return f10(11,22,33,44,55,66,77,88,99,110);
1711  }
1712  int g11 ( void ) {
1713  return f11(11,22,33,44,55,66,77,88,99,110,121);
1714  }
1715  int g12 ( void ) {
1716  return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1717  }
1718 */
1719 
1720 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1721 
1722 /* These regs are trashed by the hidden call. */
1723 #define __CALLER_SAVED_REGS \
1724  "lr", "ctr", "xer", \
1725  "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
1726  "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
1727  "r11", "r12", "r13"
1728 
1729 /* These CALL_FN_ macros assume that on ppc32-linux,
1730  sizeof(unsigned long) == 4. */
1731 
1732 #define CALL_FN_W_v(lval, orig) \
1733  do { \
1734  volatile OrigFn _orig = (orig); \
1735  volatile unsigned long _argvec[1]; \
1736  volatile unsigned long _res; \
1737  _argvec[0] = (unsigned long)_orig.nraddr; \
1738  __asm__ volatile( \
1739  "mr 11,%1\n\t" \
1740  "lwz 11,0(11)\n\t" /* target->r11 */ \
1741  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1742  "mr %0,3" \
1743  : /*out*/ "=r" (_res) \
1744  : /*in*/ "r" (&_argvec[0]) \
1745  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1746  ); \
1747  lval = (__typeof__(lval)) _res; \
1748  } while (0)
1749 
1750 #define CALL_FN_W_W(lval, orig, arg1) \
1751  do { \
1752  volatile OrigFn _orig = (orig); \
1753  volatile unsigned long _argvec[2]; \
1754  volatile unsigned long _res; \
1755  _argvec[0] = (unsigned long)_orig.nraddr; \
1756  _argvec[1] = (unsigned long)arg1; \
1757  __asm__ volatile( \
1758  "mr 11,%1\n\t" \
1759  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1760  "lwz 11,0(11)\n\t" /* target->r11 */ \
1761  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1762  "mr %0,3" \
1763  : /*out*/ "=r" (_res) \
1764  : /*in*/ "r" (&_argvec[0]) \
1765  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1766  ); \
1767  lval = (__typeof__(lval)) _res; \
1768  } while (0)
1769 
1770 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1771  do { \
1772  volatile OrigFn _orig = (orig); \
1773  volatile unsigned long _argvec[3]; \
1774  volatile unsigned long _res; \
1775  _argvec[0] = (unsigned long)_orig.nraddr; \
1776  _argvec[1] = (unsigned long)arg1; \
1777  _argvec[2] = (unsigned long)arg2; \
1778  __asm__ volatile( \
1779  "mr 11,%1\n\t" \
1780  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1781  "lwz 4,8(11)\n\t" \
1782  "lwz 11,0(11)\n\t" /* target->r11 */ \
1783  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1784  "mr %0,3" \
1785  : /*out*/ "=r" (_res) \
1786  : /*in*/ "r" (&_argvec[0]) \
1787  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1788  ); \
1789  lval = (__typeof__(lval)) _res; \
1790  } while (0)
1791 
1792 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1793  do { \
1794  volatile OrigFn _orig = (orig); \
1795  volatile unsigned long _argvec[4]; \
1796  volatile unsigned long _res; \
1797  _argvec[0] = (unsigned long)_orig.nraddr; \
1798  _argvec[1] = (unsigned long)arg1; \
1799  _argvec[2] = (unsigned long)arg2; \
1800  _argvec[3] = (unsigned long)arg3; \
1801  __asm__ volatile( \
1802  "mr 11,%1\n\t" \
1803  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1804  "lwz 4,8(11)\n\t" \
1805  "lwz 5,12(11)\n\t" \
1806  "lwz 11,0(11)\n\t" /* target->r11 */ \
1807  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1808  "mr %0,3" \
1809  : /*out*/ "=r" (_res) \
1810  : /*in*/ "r" (&_argvec[0]) \
1811  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1812  ); \
1813  lval = (__typeof__(lval)) _res; \
1814  } while (0)
1815 
1816 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1817  do { \
1818  volatile OrigFn _orig = (orig); \
1819  volatile unsigned long _argvec[5]; \
1820  volatile unsigned long _res; \
1821  _argvec[0] = (unsigned long)_orig.nraddr; \
1822  _argvec[1] = (unsigned long)arg1; \
1823  _argvec[2] = (unsigned long)arg2; \
1824  _argvec[3] = (unsigned long)arg3; \
1825  _argvec[4] = (unsigned long)arg4; \
1826  __asm__ volatile( \
1827  "mr 11,%1\n\t" \
1828  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1829  "lwz 4,8(11)\n\t" \
1830  "lwz 5,12(11)\n\t" \
1831  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1832  "lwz 11,0(11)\n\t" /* target->r11 */ \
1833  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1834  "mr %0,3" \
1835  : /*out*/ "=r" (_res) \
1836  : /*in*/ "r" (&_argvec[0]) \
1837  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1838  ); \
1839  lval = (__typeof__(lval)) _res; \
1840  } while (0)
1841 
1842 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1843  do { \
1844  volatile OrigFn _orig = (orig); \
1845  volatile unsigned long _argvec[6]; \
1846  volatile unsigned long _res; \
1847  _argvec[0] = (unsigned long)_orig.nraddr; \
1848  _argvec[1] = (unsigned long)arg1; \
1849  _argvec[2] = (unsigned long)arg2; \
1850  _argvec[3] = (unsigned long)arg3; \
1851  _argvec[4] = (unsigned long)arg4; \
1852  _argvec[5] = (unsigned long)arg5; \
1853  __asm__ volatile( \
1854  "mr 11,%1\n\t" \
1855  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1856  "lwz 4,8(11)\n\t" \
1857  "lwz 5,12(11)\n\t" \
1858  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1859  "lwz 7,20(11)\n\t" \
1860  "lwz 11,0(11)\n\t" /* target->r11 */ \
1861  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1862  "mr %0,3" \
1863  : /*out*/ "=r" (_res) \
1864  : /*in*/ "r" (&_argvec[0]) \
1865  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1866  ); \
1867  lval = (__typeof__(lval)) _res; \
1868  } while (0)
1869 
1870 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1871  do { \
1872  volatile OrigFn _orig = (orig); \
1873  volatile unsigned long _argvec[7]; \
1874  volatile unsigned long _res; \
1875  _argvec[0] = (unsigned long)_orig.nraddr; \
1876  _argvec[1] = (unsigned long)arg1; \
1877  _argvec[2] = (unsigned long)arg2; \
1878  _argvec[3] = (unsigned long)arg3; \
1879  _argvec[4] = (unsigned long)arg4; \
1880  _argvec[5] = (unsigned long)arg5; \
1881  _argvec[6] = (unsigned long)arg6; \
1882  __asm__ volatile( \
1883  "mr 11,%1\n\t" \
1884  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1885  "lwz 4,8(11)\n\t" \
1886  "lwz 5,12(11)\n\t" \
1887  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1888  "lwz 7,20(11)\n\t" \
1889  "lwz 8,24(11)\n\t" \
1890  "lwz 11,0(11)\n\t" /* target->r11 */ \
1891  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1892  "mr %0,3" \
1893  : /*out*/ "=r" (_res) \
1894  : /*in*/ "r" (&_argvec[0]) \
1895  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1896  ); \
1897  lval = (__typeof__(lval)) _res; \
1898  } while (0)
1899 
1900 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1901  arg7) \
1902  do { \
1903  volatile OrigFn _orig = (orig); \
1904  volatile unsigned long _argvec[8]; \
1905  volatile unsigned long _res; \
1906  _argvec[0] = (unsigned long)_orig.nraddr; \
1907  _argvec[1] = (unsigned long)arg1; \
1908  _argvec[2] = (unsigned long)arg2; \
1909  _argvec[3] = (unsigned long)arg3; \
1910  _argvec[4] = (unsigned long)arg4; \
1911  _argvec[5] = (unsigned long)arg5; \
1912  _argvec[6] = (unsigned long)arg6; \
1913  _argvec[7] = (unsigned long)arg7; \
1914  __asm__ volatile( \
1915  "mr 11,%1\n\t" \
1916  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1917  "lwz 4,8(11)\n\t" \
1918  "lwz 5,12(11)\n\t" \
1919  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1920  "lwz 7,20(11)\n\t" \
1921  "lwz 8,24(11)\n\t" \
1922  "lwz 9,28(11)\n\t" \
1923  "lwz 11,0(11)\n\t" /* target->r11 */ \
1924  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1925  "mr %0,3" \
1926  : /*out*/ "=r" (_res) \
1927  : /*in*/ "r" (&_argvec[0]) \
1928  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1929  ); \
1930  lval = (__typeof__(lval)) _res; \
1931  } while (0)
1932 
1933 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1934  arg7,arg8) \
1935  do { \
1936  volatile OrigFn _orig = (orig); \
1937  volatile unsigned long _argvec[9]; \
1938  volatile unsigned long _res; \
1939  _argvec[0] = (unsigned long)_orig.nraddr; \
1940  _argvec[1] = (unsigned long)arg1; \
1941  _argvec[2] = (unsigned long)arg2; \
1942  _argvec[3] = (unsigned long)arg3; \
1943  _argvec[4] = (unsigned long)arg4; \
1944  _argvec[5] = (unsigned long)arg5; \
1945  _argvec[6] = (unsigned long)arg6; \
1946  _argvec[7] = (unsigned long)arg7; \
1947  _argvec[8] = (unsigned long)arg8; \
1948  __asm__ volatile( \
1949  "mr 11,%1\n\t" \
1950  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1951  "lwz 4,8(11)\n\t" \
1952  "lwz 5,12(11)\n\t" \
1953  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1954  "lwz 7,20(11)\n\t" \
1955  "lwz 8,24(11)\n\t" \
1956  "lwz 9,28(11)\n\t" \
1957  "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1958  "lwz 11,0(11)\n\t" /* target->r11 */ \
1959  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1960  "mr %0,3" \
1961  : /*out*/ "=r" (_res) \
1962  : /*in*/ "r" (&_argvec[0]) \
1963  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1964  ); \
1965  lval = (__typeof__(lval)) _res; \
1966  } while (0)
1967 
1968 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1969  arg7,arg8,arg9) \
1970  do { \
1971  volatile OrigFn _orig = (orig); \
1972  volatile unsigned long _argvec[10]; \
1973  volatile unsigned long _res; \
1974  _argvec[0] = (unsigned long)_orig.nraddr; \
1975  _argvec[1] = (unsigned long)arg1; \
1976  _argvec[2] = (unsigned long)arg2; \
1977  _argvec[3] = (unsigned long)arg3; \
1978  _argvec[4] = (unsigned long)arg4; \
1979  _argvec[5] = (unsigned long)arg5; \
1980  _argvec[6] = (unsigned long)arg6; \
1981  _argvec[7] = (unsigned long)arg7; \
1982  _argvec[8] = (unsigned long)arg8; \
1983  _argvec[9] = (unsigned long)arg9; \
1984  __asm__ volatile( \
1985  "mr 11,%1\n\t" \
1986  "addi 1,1,-16\n\t" \
1987  /* arg9 */ \
1988  "lwz 3,36(11)\n\t" \
1989  "stw 3,8(1)\n\t" \
1990  /* args1-8 */ \
1991  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1992  "lwz 4,8(11)\n\t" \
1993  "lwz 5,12(11)\n\t" \
1994  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1995  "lwz 7,20(11)\n\t" \
1996  "lwz 8,24(11)\n\t" \
1997  "lwz 9,28(11)\n\t" \
1998  "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1999  "lwz 11,0(11)\n\t" /* target->r11 */ \
2000  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2001  "addi 1,1,16\n\t" \
2002  "mr %0,3" \
2003  : /*out*/ "=r" (_res) \
2004  : /*in*/ "r" (&_argvec[0]) \
2005  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2006  ); \
2007  lval = (__typeof__(lval)) _res; \
2008  } while (0)
2009 
2010 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2011  arg7,arg8,arg9,arg10) \
2012  do { \
2013  volatile OrigFn _orig = (orig); \
2014  volatile unsigned long _argvec[11]; \
2015  volatile unsigned long _res; \
2016  _argvec[0] = (unsigned long)_orig.nraddr; \
2017  _argvec[1] = (unsigned long)arg1; \
2018  _argvec[2] = (unsigned long)arg2; \
2019  _argvec[3] = (unsigned long)arg3; \
2020  _argvec[4] = (unsigned long)arg4; \
2021  _argvec[5] = (unsigned long)arg5; \
2022  _argvec[6] = (unsigned long)arg6; \
2023  _argvec[7] = (unsigned long)arg7; \
2024  _argvec[8] = (unsigned long)arg8; \
2025  _argvec[9] = (unsigned long)arg9; \
2026  _argvec[10] = (unsigned long)arg10; \
2027  __asm__ volatile( \
2028  "mr 11,%1\n\t" \
2029  "addi 1,1,-16\n\t" \
2030  /* arg10 */ \
2031  "lwz 3,40(11)\n\t" \
2032  "stw 3,12(1)\n\t" \
2033  /* arg9 */ \
2034  "lwz 3,36(11)\n\t" \
2035  "stw 3,8(1)\n\t" \
2036  /* args1-8 */ \
2037  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2038  "lwz 4,8(11)\n\t" \
2039  "lwz 5,12(11)\n\t" \
2040  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2041  "lwz 7,20(11)\n\t" \
2042  "lwz 8,24(11)\n\t" \
2043  "lwz 9,28(11)\n\t" \
2044  "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2045  "lwz 11,0(11)\n\t" /* target->r11 */ \
2046  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2047  "addi 1,1,16\n\t" \
2048  "mr %0,3" \
2049  : /*out*/ "=r" (_res) \
2050  : /*in*/ "r" (&_argvec[0]) \
2051  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2052  ); \
2053  lval = (__typeof__(lval)) _res; \
2054  } while (0)
2055 
2056 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2057  arg7,arg8,arg9,arg10,arg11) \
2058  do { \
2059  volatile OrigFn _orig = (orig); \
2060  volatile unsigned long _argvec[12]; \
2061  volatile unsigned long _res; \
2062  _argvec[0] = (unsigned long)_orig.nraddr; \
2063  _argvec[1] = (unsigned long)arg1; \
2064  _argvec[2] = (unsigned long)arg2; \
2065  _argvec[3] = (unsigned long)arg3; \
2066  _argvec[4] = (unsigned long)arg4; \
2067  _argvec[5] = (unsigned long)arg5; \
2068  _argvec[6] = (unsigned long)arg6; \
2069  _argvec[7] = (unsigned long)arg7; \
2070  _argvec[8] = (unsigned long)arg8; \
2071  _argvec[9] = (unsigned long)arg9; \
2072  _argvec[10] = (unsigned long)arg10; \
2073  _argvec[11] = (unsigned long)arg11; \
2074  __asm__ volatile( \
2075  "mr 11,%1\n\t" \
2076  "addi 1,1,-32\n\t" \
2077  /* arg11 */ \
2078  "lwz 3,44(11)\n\t" \
2079  "stw 3,16(1)\n\t" \
2080  /* arg10 */ \
2081  "lwz 3,40(11)\n\t" \
2082  "stw 3,12(1)\n\t" \
2083  /* arg9 */ \
2084  "lwz 3,36(11)\n\t" \
2085  "stw 3,8(1)\n\t" \
2086  /* args1-8 */ \
2087  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2088  "lwz 4,8(11)\n\t" \
2089  "lwz 5,12(11)\n\t" \
2090  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2091  "lwz 7,20(11)\n\t" \
2092  "lwz 8,24(11)\n\t" \
2093  "lwz 9,28(11)\n\t" \
2094  "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2095  "lwz 11,0(11)\n\t" /* target->r11 */ \
2096  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2097  "addi 1,1,32\n\t" \
2098  "mr %0,3" \
2099  : /*out*/ "=r" (_res) \
2100  : /*in*/ "r" (&_argvec[0]) \
2101  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2102  ); \
2103  lval = (__typeof__(lval)) _res; \
2104  } while (0)
2105 
2106 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2107  arg7,arg8,arg9,arg10,arg11,arg12) \
2108  do { \
2109  volatile OrigFn _orig = (orig); \
2110  volatile unsigned long _argvec[13]; \
2111  volatile unsigned long _res; \
2112  _argvec[0] = (unsigned long)_orig.nraddr; \
2113  _argvec[1] = (unsigned long)arg1; \
2114  _argvec[2] = (unsigned long)arg2; \
2115  _argvec[3] = (unsigned long)arg3; \
2116  _argvec[4] = (unsigned long)arg4; \
2117  _argvec[5] = (unsigned long)arg5; \
2118  _argvec[6] = (unsigned long)arg6; \
2119  _argvec[7] = (unsigned long)arg7; \
2120  _argvec[8] = (unsigned long)arg8; \
2121  _argvec[9] = (unsigned long)arg9; \
2122  _argvec[10] = (unsigned long)arg10; \
2123  _argvec[11] = (unsigned long)arg11; \
2124  _argvec[12] = (unsigned long)arg12; \
2125  __asm__ volatile( \
2126  "mr 11,%1\n\t" \
2127  "addi 1,1,-32\n\t" \
2128  /* arg12 */ \
2129  "lwz 3,48(11)\n\t" \
2130  "stw 3,20(1)\n\t" \
2131  /* arg11 */ \
2132  "lwz 3,44(11)\n\t" \
2133  "stw 3,16(1)\n\t" \
2134  /* arg10 */ \
2135  "lwz 3,40(11)\n\t" \
2136  "stw 3,12(1)\n\t" \
2137  /* arg9 */ \
2138  "lwz 3,36(11)\n\t" \
2139  "stw 3,8(1)\n\t" \
2140  /* args1-8 */ \
2141  "lwz 3,4(11)\n\t" /* arg1->r3 */ \
2142  "lwz 4,8(11)\n\t" \
2143  "lwz 5,12(11)\n\t" \
2144  "lwz 6,16(11)\n\t" /* arg4->r6 */ \
2145  "lwz 7,20(11)\n\t" \
2146  "lwz 8,24(11)\n\t" \
2147  "lwz 9,28(11)\n\t" \
2148  "lwz 10,32(11)\n\t" /* arg8->r10 */ \
2149  "lwz 11,0(11)\n\t" /* target->r11 */ \
2150  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2151  "addi 1,1,32\n\t" \
2152  "mr %0,3" \
2153  : /*out*/ "=r" (_res) \
2154  : /*in*/ "r" (&_argvec[0]) \
2155  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2156  ); \
2157  lval = (__typeof__(lval)) _res; \
2158  } while (0)
2159 
2160 #endif /* PLAT_ppc32_linux */
2161 
2162 /* ------------------------ ppc64-linux ------------------------ */
2163 
2164 #if defined(PLAT_ppc64_linux)
2165 
2166 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2167 
2168 /* These regs are trashed by the hidden call. */
2169 #define __CALLER_SAVED_REGS \
2170  "lr", "ctr", "xer", \
2171  "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
2172  "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
2173  "r11", "r12", "r13"
2174 
2175 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
2176  long) == 8. */
2177 
2178 #define CALL_FN_W_v(lval, orig) \
2179  do { \
2180  volatile OrigFn _orig = (orig); \
2181  volatile unsigned long _argvec[3+0]; \
2182  volatile unsigned long _res; \
2183  /* _argvec[0] holds current r2 across the call */ \
2184  _argvec[1] = (unsigned long)_orig.r2; \
2185  _argvec[2] = (unsigned long)_orig.nraddr; \
2186  __asm__ volatile( \
2187  "mr 11,%1\n\t" \
2188  "std 2,-16(11)\n\t" /* save tocptr */ \
2189  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2190  "ld 11, 0(11)\n\t" /* target->r11 */ \
2191  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2192  "mr 11,%1\n\t" \
2193  "mr %0,3\n\t" \
2194  "ld 2,-16(11)" /* restore tocptr */ \
2195  : /*out*/ "=r" (_res) \
2196  : /*in*/ "r" (&_argvec[2]) \
2197  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2198  ); \
2199  lval = (__typeof__(lval)) _res; \
2200  } while (0)
2201 
2202 #define CALL_FN_W_W(lval, orig, arg1) \
2203  do { \
2204  volatile OrigFn _orig = (orig); \
2205  volatile unsigned long _argvec[3+1]; \
2206  volatile unsigned long _res; \
2207  /* _argvec[0] holds current r2 across the call */ \
2208  _argvec[1] = (unsigned long)_orig.r2; \
2209  _argvec[2] = (unsigned long)_orig.nraddr; \
2210  _argvec[2+1] = (unsigned long)arg1; \
2211  __asm__ volatile( \
2212  "mr 11,%1\n\t" \
2213  "std 2,-16(11)\n\t" /* save tocptr */ \
2214  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2215  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2216  "ld 11, 0(11)\n\t" /* target->r11 */ \
2217  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2218  "mr 11,%1\n\t" \
2219  "mr %0,3\n\t" \
2220  "ld 2,-16(11)" /* restore tocptr */ \
2221  : /*out*/ "=r" (_res) \
2222  : /*in*/ "r" (&_argvec[2]) \
2223  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2224  ); \
2225  lval = (__typeof__(lval)) _res; \
2226  } while (0)
2227 
2228 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2229  do { \
2230  volatile OrigFn _orig = (orig); \
2231  volatile unsigned long _argvec[3+2]; \
2232  volatile unsigned long _res; \
2233  /* _argvec[0] holds current r2 across the call */ \
2234  _argvec[1] = (unsigned long)_orig.r2; \
2235  _argvec[2] = (unsigned long)_orig.nraddr; \
2236  _argvec[2+1] = (unsigned long)arg1; \
2237  _argvec[2+2] = (unsigned long)arg2; \
2238  __asm__ volatile( \
2239  "mr 11,%1\n\t" \
2240  "std 2,-16(11)\n\t" /* save tocptr */ \
2241  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2242  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2243  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2244  "ld 11, 0(11)\n\t" /* target->r11 */ \
2245  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2246  "mr 11,%1\n\t" \
2247  "mr %0,3\n\t" \
2248  "ld 2,-16(11)" /* restore tocptr */ \
2249  : /*out*/ "=r" (_res) \
2250  : /*in*/ "r" (&_argvec[2]) \
2251  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2252  ); \
2253  lval = (__typeof__(lval)) _res; \
2254  } while (0)
2255 
2256 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2257  do { \
2258  volatile OrigFn _orig = (orig); \
2259  volatile unsigned long _argvec[3+3]; \
2260  volatile unsigned long _res; \
2261  /* _argvec[0] holds current r2 across the call */ \
2262  _argvec[1] = (unsigned long)_orig.r2; \
2263  _argvec[2] = (unsigned long)_orig.nraddr; \
2264  _argvec[2+1] = (unsigned long)arg1; \
2265  _argvec[2+2] = (unsigned long)arg2; \
2266  _argvec[2+3] = (unsigned long)arg3; \
2267  __asm__ volatile( \
2268  "mr 11,%1\n\t" \
2269  "std 2,-16(11)\n\t" /* save tocptr */ \
2270  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2271  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2272  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2273  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2274  "ld 11, 0(11)\n\t" /* target->r11 */ \
2275  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2276  "mr 11,%1\n\t" \
2277  "mr %0,3\n\t" \
2278  "ld 2,-16(11)" /* restore tocptr */ \
2279  : /*out*/ "=r" (_res) \
2280  : /*in*/ "r" (&_argvec[2]) \
2281  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2282  ); \
2283  lval = (__typeof__(lval)) _res; \
2284  } while (0)
2285 
2286 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2287  do { \
2288  volatile OrigFn _orig = (orig); \
2289  volatile unsigned long _argvec[3+4]; \
2290  volatile unsigned long _res; \
2291  /* _argvec[0] holds current r2 across the call */ \
2292  _argvec[1] = (unsigned long)_orig.r2; \
2293  _argvec[2] = (unsigned long)_orig.nraddr; \
2294  _argvec[2+1] = (unsigned long)arg1; \
2295  _argvec[2+2] = (unsigned long)arg2; \
2296  _argvec[2+3] = (unsigned long)arg3; \
2297  _argvec[2+4] = (unsigned long)arg4; \
2298  __asm__ volatile( \
2299  "mr 11,%1\n\t" \
2300  "std 2,-16(11)\n\t" /* save tocptr */ \
2301  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2302  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2303  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2304  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2305  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2306  "ld 11, 0(11)\n\t" /* target->r11 */ \
2307  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2308  "mr 11,%1\n\t" \
2309  "mr %0,3\n\t" \
2310  "ld 2,-16(11)" /* restore tocptr */ \
2311  : /*out*/ "=r" (_res) \
2312  : /*in*/ "r" (&_argvec[2]) \
2313  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2314  ); \
2315  lval = (__typeof__(lval)) _res; \
2316  } while (0)
2317 
2318 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2319  do { \
2320  volatile OrigFn _orig = (orig); \
2321  volatile unsigned long _argvec[3+5]; \
2322  volatile unsigned long _res; \
2323  /* _argvec[0] holds current r2 across the call */ \
2324  _argvec[1] = (unsigned long)_orig.r2; \
2325  _argvec[2] = (unsigned long)_orig.nraddr; \
2326  _argvec[2+1] = (unsigned long)arg1; \
2327  _argvec[2+2] = (unsigned long)arg2; \
2328  _argvec[2+3] = (unsigned long)arg3; \
2329  _argvec[2+4] = (unsigned long)arg4; \
2330  _argvec[2+5] = (unsigned long)arg5; \
2331  __asm__ volatile( \
2332  "mr 11,%1\n\t" \
2333  "std 2,-16(11)\n\t" /* save tocptr */ \
2334  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2335  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2336  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2337  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2338  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2339  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2340  "ld 11, 0(11)\n\t" /* target->r11 */ \
2341  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2342  "mr 11,%1\n\t" \
2343  "mr %0,3\n\t" \
2344  "ld 2,-16(11)" /* restore tocptr */ \
2345  : /*out*/ "=r" (_res) \
2346  : /*in*/ "r" (&_argvec[2]) \
2347  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2348  ); \
2349  lval = (__typeof__(lval)) _res; \
2350  } while (0)
2351 
2352 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2353  do { \
2354  volatile OrigFn _orig = (orig); \
2355  volatile unsigned long _argvec[3+6]; \
2356  volatile unsigned long _res; \
2357  /* _argvec[0] holds current r2 across the call */ \
2358  _argvec[1] = (unsigned long)_orig.r2; \
2359  _argvec[2] = (unsigned long)_orig.nraddr; \
2360  _argvec[2+1] = (unsigned long)arg1; \
2361  _argvec[2+2] = (unsigned long)arg2; \
2362  _argvec[2+3] = (unsigned long)arg3; \
2363  _argvec[2+4] = (unsigned long)arg4; \
2364  _argvec[2+5] = (unsigned long)arg5; \
2365  _argvec[2+6] = (unsigned long)arg6; \
2366  __asm__ volatile( \
2367  "mr 11,%1\n\t" \
2368  "std 2,-16(11)\n\t" /* save tocptr */ \
2369  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2370  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2371  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2372  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2373  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2374  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2375  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2376  "ld 11, 0(11)\n\t" /* target->r11 */ \
2377  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2378  "mr 11,%1\n\t" \
2379  "mr %0,3\n\t" \
2380  "ld 2,-16(11)" /* restore tocptr */ \
2381  : /*out*/ "=r" (_res) \
2382  : /*in*/ "r" (&_argvec[2]) \
2383  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2384  ); \
2385  lval = (__typeof__(lval)) _res; \
2386  } while (0)
2387 
2388 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2389  arg7) \
2390  do { \
2391  volatile OrigFn _orig = (orig); \
2392  volatile unsigned long _argvec[3+7]; \
2393  volatile unsigned long _res; \
2394  /* _argvec[0] holds current r2 across the call */ \
2395  _argvec[1] = (unsigned long)_orig.r2; \
2396  _argvec[2] = (unsigned long)_orig.nraddr; \
2397  _argvec[2+1] = (unsigned long)arg1; \
2398  _argvec[2+2] = (unsigned long)arg2; \
2399  _argvec[2+3] = (unsigned long)arg3; \
2400  _argvec[2+4] = (unsigned long)arg4; \
2401  _argvec[2+5] = (unsigned long)arg5; \
2402  _argvec[2+6] = (unsigned long)arg6; \
2403  _argvec[2+7] = (unsigned long)arg7; \
2404  __asm__ volatile( \
2405  "mr 11,%1\n\t" \
2406  "std 2,-16(11)\n\t" /* save tocptr */ \
2407  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2408  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2409  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2410  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2411  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2412  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2413  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2414  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2415  "ld 11, 0(11)\n\t" /* target->r11 */ \
2416  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2417  "mr 11,%1\n\t" \
2418  "mr %0,3\n\t" \
2419  "ld 2,-16(11)" /* restore tocptr */ \
2420  : /*out*/ "=r" (_res) \
2421  : /*in*/ "r" (&_argvec[2]) \
2422  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2423  ); \
2424  lval = (__typeof__(lval)) _res; \
2425  } while (0)
2426 
2427 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2428  arg7,arg8) \
2429  do { \
2430  volatile OrigFn _orig = (orig); \
2431  volatile unsigned long _argvec[3+8]; \
2432  volatile unsigned long _res; \
2433  /* _argvec[0] holds current r2 across the call */ \
2434  _argvec[1] = (unsigned long)_orig.r2; \
2435  _argvec[2] = (unsigned long)_orig.nraddr; \
2436  _argvec[2+1] = (unsigned long)arg1; \
2437  _argvec[2+2] = (unsigned long)arg2; \
2438  _argvec[2+3] = (unsigned long)arg3; \
2439  _argvec[2+4] = (unsigned long)arg4; \
2440  _argvec[2+5] = (unsigned long)arg5; \
2441  _argvec[2+6] = (unsigned long)arg6; \
2442  _argvec[2+7] = (unsigned long)arg7; \
2443  _argvec[2+8] = (unsigned long)arg8; \
2444  __asm__ volatile( \
2445  "mr 11,%1\n\t" \
2446  "std 2,-16(11)\n\t" /* save tocptr */ \
2447  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2448  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2449  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2450  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2451  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2452  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2453  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2454  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2455  "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2456  "ld 11, 0(11)\n\t" /* target->r11 */ \
2457  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2458  "mr 11,%1\n\t" \
2459  "mr %0,3\n\t" \
2460  "ld 2,-16(11)" /* restore tocptr */ \
2461  : /*out*/ "=r" (_res) \
2462  : /*in*/ "r" (&_argvec[2]) \
2463  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2464  ); \
2465  lval = (__typeof__(lval)) _res; \
2466  } while (0)
2467 
2468 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2469  arg7,arg8,arg9) \
2470  do { \
2471  volatile OrigFn _orig = (orig); \
2472  volatile unsigned long _argvec[3+9]; \
2473  volatile unsigned long _res; \
2474  /* _argvec[0] holds current r2 across the call */ \
2475  _argvec[1] = (unsigned long)_orig.r2; \
2476  _argvec[2] = (unsigned long)_orig.nraddr; \
2477  _argvec[2+1] = (unsigned long)arg1; \
2478  _argvec[2+2] = (unsigned long)arg2; \
2479  _argvec[2+3] = (unsigned long)arg3; \
2480  _argvec[2+4] = (unsigned long)arg4; \
2481  _argvec[2+5] = (unsigned long)arg5; \
2482  _argvec[2+6] = (unsigned long)arg6; \
2483  _argvec[2+7] = (unsigned long)arg7; \
2484  _argvec[2+8] = (unsigned long)arg8; \
2485  _argvec[2+9] = (unsigned long)arg9; \
2486  __asm__ volatile( \
2487  "mr 11,%1\n\t" \
2488  "std 2,-16(11)\n\t" /* save tocptr */ \
2489  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2490  "addi 1,1,-128\n\t" /* expand stack frame */ \
2491  /* arg9 */ \
2492  "ld 3,72(11)\n\t" \
2493  "std 3,112(1)\n\t" \
2494  /* args1-8 */ \
2495  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2496  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2497  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2498  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2499  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2500  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2501  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2502  "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2503  "ld 11, 0(11)\n\t" /* target->r11 */ \
2504  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2505  "mr 11,%1\n\t" \
2506  "mr %0,3\n\t" \
2507  "ld 2,-16(11)\n\t" /* restore tocptr */ \
2508  "addi 1,1,128" /* restore frame */ \
2509  : /*out*/ "=r" (_res) \
2510  : /*in*/ "r" (&_argvec[2]) \
2511  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2512  ); \
2513  lval = (__typeof__(lval)) _res; \
2514  } while (0)
2515 
2516 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2517  arg7,arg8,arg9,arg10) \
2518  do { \
2519  volatile OrigFn _orig = (orig); \
2520  volatile unsigned long _argvec[3+10]; \
2521  volatile unsigned long _res; \
2522  /* _argvec[0] holds current r2 across the call */ \
2523  _argvec[1] = (unsigned long)_orig.r2; \
2524  _argvec[2] = (unsigned long)_orig.nraddr; \
2525  _argvec[2+1] = (unsigned long)arg1; \
2526  _argvec[2+2] = (unsigned long)arg2; \
2527  _argvec[2+3] = (unsigned long)arg3; \
2528  _argvec[2+4] = (unsigned long)arg4; \
2529  _argvec[2+5] = (unsigned long)arg5; \
2530  _argvec[2+6] = (unsigned long)arg6; \
2531  _argvec[2+7] = (unsigned long)arg7; \
2532  _argvec[2+8] = (unsigned long)arg8; \
2533  _argvec[2+9] = (unsigned long)arg9; \
2534  _argvec[2+10] = (unsigned long)arg10; \
2535  __asm__ volatile( \
2536  "mr 11,%1\n\t" \
2537  "std 2,-16(11)\n\t" /* save tocptr */ \
2538  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2539  "addi 1,1,-128\n\t" /* expand stack frame */ \
2540  /* arg10 */ \
2541  "ld 3,80(11)\n\t" \
2542  "std 3,120(1)\n\t" \
2543  /* arg9 */ \
2544  "ld 3,72(11)\n\t" \
2545  "std 3,112(1)\n\t" \
2546  /* args1-8 */ \
2547  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2548  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2549  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2550  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2551  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2552  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2553  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2554  "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2555  "ld 11, 0(11)\n\t" /* target->r11 */ \
2556  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2557  "mr 11,%1\n\t" \
2558  "mr %0,3\n\t" \
2559  "ld 2,-16(11)\n\t" /* restore tocptr */ \
2560  "addi 1,1,128" /* restore frame */ \
2561  : /*out*/ "=r" (_res) \
2562  : /*in*/ "r" (&_argvec[2]) \
2563  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2564  ); \
2565  lval = (__typeof__(lval)) _res; \
2566  } while (0)
2567 
2568 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2569  arg7,arg8,arg9,arg10,arg11) \
2570  do { \
2571  volatile OrigFn _orig = (orig); \
2572  volatile unsigned long _argvec[3+11]; \
2573  volatile unsigned long _res; \
2574  /* _argvec[0] holds current r2 across the call */ \
2575  _argvec[1] = (unsigned long)_orig.r2; \
2576  _argvec[2] = (unsigned long)_orig.nraddr; \
2577  _argvec[2+1] = (unsigned long)arg1; \
2578  _argvec[2+2] = (unsigned long)arg2; \
2579  _argvec[2+3] = (unsigned long)arg3; \
2580  _argvec[2+4] = (unsigned long)arg4; \
2581  _argvec[2+5] = (unsigned long)arg5; \
2582  _argvec[2+6] = (unsigned long)arg6; \
2583  _argvec[2+7] = (unsigned long)arg7; \
2584  _argvec[2+8] = (unsigned long)arg8; \
2585  _argvec[2+9] = (unsigned long)arg9; \
2586  _argvec[2+10] = (unsigned long)arg10; \
2587  _argvec[2+11] = (unsigned long)arg11; \
2588  __asm__ volatile( \
2589  "mr 11,%1\n\t" \
2590  "std 2,-16(11)\n\t" /* save tocptr */ \
2591  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2592  "addi 1,1,-144\n\t" /* expand stack frame */ \
2593  /* arg11 */ \
2594  "ld 3,88(11)\n\t" \
2595  "std 3,128(1)\n\t" \
2596  /* arg10 */ \
2597  "ld 3,80(11)\n\t" \
2598  "std 3,120(1)\n\t" \
2599  /* arg9 */ \
2600  "ld 3,72(11)\n\t" \
2601  "std 3,112(1)\n\t" \
2602  /* args1-8 */ \
2603  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2604  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2605  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2606  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2607  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2608  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2609  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2610  "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2611  "ld 11, 0(11)\n\t" /* target->r11 */ \
2612  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2613  "mr 11,%1\n\t" \
2614  "mr %0,3\n\t" \
2615  "ld 2,-16(11)\n\t" /* restore tocptr */ \
2616  "addi 1,1,144" /* restore frame */ \
2617  : /*out*/ "=r" (_res) \
2618  : /*in*/ "r" (&_argvec[2]) \
2619  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2620  ); \
2621  lval = (__typeof__(lval)) _res; \
2622  } while (0)
2623 
2624 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2625  arg7,arg8,arg9,arg10,arg11,arg12) \
2626  do { \
2627  volatile OrigFn _orig = (orig); \
2628  volatile unsigned long _argvec[3+12]; \
2629  volatile unsigned long _res; \
2630  /* _argvec[0] holds current r2 across the call */ \
2631  _argvec[1] = (unsigned long)_orig.r2; \
2632  _argvec[2] = (unsigned long)_orig.nraddr; \
2633  _argvec[2+1] = (unsigned long)arg1; \
2634  _argvec[2+2] = (unsigned long)arg2; \
2635  _argvec[2+3] = (unsigned long)arg3; \
2636  _argvec[2+4] = (unsigned long)arg4; \
2637  _argvec[2+5] = (unsigned long)arg5; \
2638  _argvec[2+6] = (unsigned long)arg6; \
2639  _argvec[2+7] = (unsigned long)arg7; \
2640  _argvec[2+8] = (unsigned long)arg8; \
2641  _argvec[2+9] = (unsigned long)arg9; \
2642  _argvec[2+10] = (unsigned long)arg10; \
2643  _argvec[2+11] = (unsigned long)arg11; \
2644  _argvec[2+12] = (unsigned long)arg12; \
2645  __asm__ volatile( \
2646  "mr 11,%1\n\t" \
2647  "std 2,-16(11)\n\t" /* save tocptr */ \
2648  "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2649  "addi 1,1,-144\n\t" /* expand stack frame */ \
2650  /* arg12 */ \
2651  "ld 3,96(11)\n\t" \
2652  "std 3,136(1)\n\t" \
2653  /* arg11 */ \
2654  "ld 3,88(11)\n\t" \
2655  "std 3,128(1)\n\t" \
2656  /* arg10 */ \
2657  "ld 3,80(11)\n\t" \
2658  "std 3,120(1)\n\t" \
2659  /* arg9 */ \
2660  "ld 3,72(11)\n\t" \
2661  "std 3,112(1)\n\t" \
2662  /* args1-8 */ \
2663  "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2664  "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2665  "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2666  "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2667  "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2668  "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2669  "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2670  "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2671  "ld 11, 0(11)\n\t" /* target->r11 */ \
2672  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2673  "mr 11,%1\n\t" \
2674  "mr %0,3\n\t" \
2675  "ld 2,-16(11)\n\t" /* restore tocptr */ \
2676  "addi 1,1,144" /* restore frame */ \
2677  : /*out*/ "=r" (_res) \
2678  : /*in*/ "r" (&_argvec[2]) \
2679  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2680  ); \
2681  lval = (__typeof__(lval)) _res; \
2682  } while (0)
2683 
2684 #endif /* PLAT_ppc64_linux */
2685 
2686 /* ------------------------- arm-linux ------------------------- */
2687 
2688 #if defined(PLAT_arm_linux)
2689 
2690 /* These regs are trashed by the hidden call. */
2691 #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
2692 
2693 /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
2694  long) == 4. */
2695 
2696 #define CALL_FN_W_v(lval, orig) \
2697  do { \
2698  volatile OrigFn _orig = (orig); \
2699  volatile unsigned long _argvec[1]; \
2700  volatile unsigned long _res; \
2701  _argvec[0] = (unsigned long)_orig.nraddr; \
2702  __asm__ volatile( \
2703  "ldr r4, [%1] \n\t" /* target->r4 */ \
2704  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2705  "mov %0, r0\n" \
2706  : /*out*/ "=r" (_res) \
2707  : /*in*/ "0" (&_argvec[0]) \
2708  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2709  ); \
2710  lval = (__typeof__(lval)) _res; \
2711  } while (0)
2712 
2713 #define CALL_FN_W_W(lval, orig, arg1) \
2714  do { \
2715  volatile OrigFn _orig = (orig); \
2716  volatile unsigned long _argvec[2]; \
2717  volatile unsigned long _res; \
2718  _argvec[0] = (unsigned long)_orig.nraddr; \
2719  _argvec[1] = (unsigned long)(arg1); \
2720  __asm__ volatile( \
2721  "ldr r0, [%1, #4] \n\t" \
2722  "ldr r4, [%1] \n\t" /* target->r4 */ \
2723  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2724  "mov %0, r0\n" \
2725  : /*out*/ "=r" (_res) \
2726  : /*in*/ "0" (&_argvec[0]) \
2727  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2728  ); \
2729  lval = (__typeof__(lval)) _res; \
2730  } while (0)
2731 
2732 #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2733  do { \
2734  volatile OrigFn _orig = (orig); \
2735  volatile unsigned long _argvec[3]; \
2736  volatile unsigned long _res; \
2737  _argvec[0] = (unsigned long)_orig.nraddr; \
2738  _argvec[1] = (unsigned long)(arg1); \
2739  _argvec[2] = (unsigned long)(arg2); \
2740  __asm__ volatile( \
2741  "ldr r0, [%1, #4] \n\t" \
2742  "ldr r1, [%1, #8] \n\t" \
2743  "ldr r4, [%1] \n\t" /* target->r4 */ \
2744  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2745  "mov %0, r0\n" \
2746  : /*out*/ "=r" (_res) \
2747  : /*in*/ "0" (&_argvec[0]) \
2748  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2749  ); \
2750  lval = (__typeof__(lval)) _res; \
2751  } while (0)
2752 
2753 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2754  do { \
2755  volatile OrigFn _orig = (orig); \
2756  volatile unsigned long _argvec[4]; \
2757  volatile unsigned long _res; \
2758  _argvec[0] = (unsigned long)_orig.nraddr; \
2759  _argvec[1] = (unsigned long)(arg1); \
2760  _argvec[2] = (unsigned long)(arg2); \
2761  _argvec[3] = (unsigned long)(arg3); \
2762  __asm__ volatile( \
2763  "ldr r0, [%1, #4] \n\t" \
2764  "ldr r1, [%1, #8] \n\t" \
2765  "ldr r2, [%1, #12] \n\t" \
2766  "ldr r4, [%1] \n\t" /* target->r4 */ \
2767  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2768  "mov %0, r0\n" \
2769  : /*out*/ "=r" (_res) \
2770  : /*in*/ "0" (&_argvec[0]) \
2771  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2772  ); \
2773  lval = (__typeof__(lval)) _res; \
2774  } while (0)
2775 
2776 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2777  do { \
2778  volatile OrigFn _orig = (orig); \
2779  volatile unsigned long _argvec[5]; \
2780  volatile unsigned long _res; \
2781  _argvec[0] = (unsigned long)_orig.nraddr; \
2782  _argvec[1] = (unsigned long)(arg1); \
2783  _argvec[2] = (unsigned long)(arg2); \
2784  _argvec[3] = (unsigned long)(arg3); \
2785  _argvec[4] = (unsigned long)(arg4); \
2786  __asm__ volatile( \
2787  "ldr r0, [%1, #4] \n\t" \
2788  "ldr r1, [%1, #8] \n\t" \
2789  "ldr r2, [%1, #12] \n\t" \
2790  "ldr r3, [%1, #16] \n\t" \
2791  "ldr r4, [%1] \n\t" /* target->r4 */ \
2792  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2793  "mov %0, r0" \
2794  : /*out*/ "=r" (_res) \
2795  : /*in*/ "0" (&_argvec[0]) \
2796  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2797  ); \
2798  lval = (__typeof__(lval)) _res; \
2799  } while (0)
2800 
2801 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2802  do { \
2803  volatile OrigFn _orig = (orig); \
2804  volatile unsigned long _argvec[6]; \
2805  volatile unsigned long _res; \
2806  _argvec[0] = (unsigned long)_orig.nraddr; \
2807  _argvec[1] = (unsigned long)(arg1); \
2808  _argvec[2] = (unsigned long)(arg2); \
2809  _argvec[3] = (unsigned long)(arg3); \
2810  _argvec[4] = (unsigned long)(arg4); \
2811  _argvec[5] = (unsigned long)(arg5); \
2812  __asm__ volatile( \
2813  "ldr r0, [%1, #20] \n\t" \
2814  "push {r0} \n\t" \
2815  "ldr r0, [%1, #4] \n\t" \
2816  "ldr r1, [%1, #8] \n\t" \
2817  "ldr r2, [%1, #12] \n\t" \
2818  "ldr r3, [%1, #16] \n\t" \
2819  "ldr r4, [%1] \n\t" /* target->r4 */ \
2820  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2821  "add sp, sp, #4 \n\t" \
2822  "mov %0, r0" \
2823  : /*out*/ "=r" (_res) \
2824  : /*in*/ "0" (&_argvec[0]) \
2825  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2826  ); \
2827  lval = (__typeof__(lval)) _res; \
2828  } while (0)
2829 
2830 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2831  do { \
2832  volatile OrigFn _orig = (orig); \
2833  volatile unsigned long _argvec[7]; \
2834  volatile unsigned long _res; \
2835  _argvec[0] = (unsigned long)_orig.nraddr; \
2836  _argvec[1] = (unsigned long)(arg1); \
2837  _argvec[2] = (unsigned long)(arg2); \
2838  _argvec[3] = (unsigned long)(arg3); \
2839  _argvec[4] = (unsigned long)(arg4); \
2840  _argvec[5] = (unsigned long)(arg5); \
2841  _argvec[6] = (unsigned long)(arg6); \
2842  __asm__ volatile( \
2843  "ldr r0, [%1, #20] \n\t" \
2844  "ldr r1, [%1, #24] \n\t" \
2845  "push {r0, r1} \n\t" \
2846  "ldr r0, [%1, #4] \n\t" \
2847  "ldr r1, [%1, #8] \n\t" \
2848  "ldr r2, [%1, #12] \n\t" \
2849  "ldr r3, [%1, #16] \n\t" \
2850  "ldr r4, [%1] \n\t" /* target->r4 */ \
2851  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2852  "add sp, sp, #8 \n\t" \
2853  "mov %0, r0" \
2854  : /*out*/ "=r" (_res) \
2855  : /*in*/ "0" (&_argvec[0]) \
2856  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2857  ); \
2858  lval = (__typeof__(lval)) _res; \
2859  } while (0)
2860 
2861 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2862  arg7) \
2863  do { \
2864  volatile OrigFn _orig = (orig); \
2865  volatile unsigned long _argvec[8]; \
2866  volatile unsigned long _res; \
2867  _argvec[0] = (unsigned long)_orig.nraddr; \
2868  _argvec[1] = (unsigned long)(arg1); \
2869  _argvec[2] = (unsigned long)(arg2); \
2870  _argvec[3] = (unsigned long)(arg3); \
2871  _argvec[4] = (unsigned long)(arg4); \
2872  _argvec[5] = (unsigned long)(arg5); \
2873  _argvec[6] = (unsigned long)(arg6); \
2874  _argvec[7] = (unsigned long)(arg7); \
2875  __asm__ volatile( \
2876  "ldr r0, [%1, #20] \n\t" \
2877  "ldr r1, [%1, #24] \n\t" \
2878  "ldr r2, [%1, #28] \n\t" \
2879  "push {r0, r1, r2} \n\t" \
2880  "ldr r0, [%1, #4] \n\t" \
2881  "ldr r1, [%1, #8] \n\t" \
2882  "ldr r2, [%1, #12] \n\t" \
2883  "ldr r3, [%1, #16] \n\t" \
2884  "ldr r4, [%1] \n\t" /* target->r4 */ \
2885  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2886  "add sp, sp, #12 \n\t" \
2887  "mov %0, r0" \
2888  : /*out*/ "=r" (_res) \
2889  : /*in*/ "0" (&_argvec[0]) \
2890  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2891  ); \
2892  lval = (__typeof__(lval)) _res; \
2893  } while (0)
2894 
2895 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2896  arg7,arg8) \
2897  do { \
2898  volatile OrigFn _orig = (orig); \
2899  volatile unsigned long _argvec[9]; \
2900  volatile unsigned long _res; \
2901  _argvec[0] = (unsigned long)_orig.nraddr; \
2902  _argvec[1] = (unsigned long)(arg1); \
2903  _argvec[2] = (unsigned long)(arg2); \
2904  _argvec[3] = (unsigned long)(arg3); \
2905  _argvec[4] = (unsigned long)(arg4); \
2906  _argvec[5] = (unsigned long)(arg5); \
2907  _argvec[6] = (unsigned long)(arg6); \
2908  _argvec[7] = (unsigned long)(arg7); \
2909  _argvec[8] = (unsigned long)(arg8); \
2910  __asm__ volatile( \
2911  "ldr r0, [%1, #20] \n\t" \
2912  "ldr r1, [%1, #24] \n\t" \
2913  "ldr r2, [%1, #28] \n\t" \
2914  "ldr r3, [%1, #32] \n\t" \
2915  "push {r0, r1, r2, r3} \n\t" \
2916  "ldr r0, [%1, #4] \n\t" \
2917  "ldr r1, [%1, #8] \n\t" \
2918  "ldr r2, [%1, #12] \n\t" \
2919  "ldr r3, [%1, #16] \n\t" \
2920  "ldr r4, [%1] \n\t" /* target->r4 */ \
2921  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2922  "add sp, sp, #16 \n\t" \
2923  "mov %0, r0" \
2924  : /*out*/ "=r" (_res) \
2925  : /*in*/ "0" (&_argvec[0]) \
2926  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2927  ); \
2928  lval = (__typeof__(lval)) _res; \
2929  } while (0)
2930 
2931 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2932  arg7,arg8,arg9) \
2933  do { \
2934  volatile OrigFn _orig = (orig); \
2935  volatile unsigned long _argvec[10]; \
2936  volatile unsigned long _res; \
2937  _argvec[0] = (unsigned long)_orig.nraddr; \
2938  _argvec[1] = (unsigned long)(arg1); \
2939  _argvec[2] = (unsigned long)(arg2); \
2940  _argvec[3] = (unsigned long)(arg3); \
2941  _argvec[4] = (unsigned long)(arg4); \
2942  _argvec[5] = (unsigned long)(arg5); \
2943  _argvec[6] = (unsigned long)(arg6); \
2944  _argvec[7] = (unsigned long)(arg7); \
2945  _argvec[8] = (unsigned long)(arg8); \
2946  _argvec[9] = (unsigned long)(arg9); \
2947  __asm__ volatile( \
2948  "ldr r0, [%1, #20] \n\t" \
2949  "ldr r1, [%1, #24] \n\t" \
2950  "ldr r2, [%1, #28] \n\t" \
2951  "ldr r3, [%1, #32] \n\t" \
2952  "ldr r4, [%1, #36] \n\t" \
2953  "push {r0, r1, r2, r3, r4} \n\t" \
2954  "ldr r0, [%1, #4] \n\t" \
2955  "ldr r1, [%1, #8] \n\t" \
2956  "ldr r2, [%1, #12] \n\t" \
2957  "ldr r3, [%1, #16] \n\t" \
2958  "ldr r4, [%1] \n\t" /* target->r4 */ \
2959  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2960  "add sp, sp, #20 \n\t" \
2961  "mov %0, r0" \
2962  : /*out*/ "=r" (_res) \
2963  : /*in*/ "0" (&_argvec[0]) \
2964  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2965  ); \
2966  lval = (__typeof__(lval)) _res; \
2967  } while (0)
2968 
2969 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2970  arg7,arg8,arg9,arg10) \
2971  do { \
2972  volatile OrigFn _orig = (orig); \
2973  volatile unsigned long _argvec[11]; \
2974  volatile unsigned long _res; \
2975  _argvec[0] = (unsigned long)_orig.nraddr; \
2976  _argvec[1] = (unsigned long)(arg1); \
2977  _argvec[2] = (unsigned long)(arg2); \
2978  _argvec[3] = (unsigned long)(arg3); \
2979  _argvec[4] = (unsigned long)(arg4); \
2980  _argvec[5] = (unsigned long)(arg5); \
2981  _argvec[6] = (unsigned long)(arg6); \
2982  _argvec[7] = (unsigned long)(arg7); \
2983  _argvec[8] = (unsigned long)(arg8); \
2984  _argvec[9] = (unsigned long)(arg9); \
2985  _argvec[10] = (unsigned long)(arg10); \
2986  __asm__ volatile( \
2987  "ldr r0, [%1, #40] \n\t" \
2988  "push {r0} \n\t" \
2989  "ldr r0, [%1, #20] \n\t" \
2990  "ldr r1, [%1, #24] \n\t" \
2991  "ldr r2, [%1, #28] \n\t" \
2992  "ldr r3, [%1, #32] \n\t" \
2993  "ldr r4, [%1, #36] \n\t" \
2994  "push {r0, r1, r2, r3, r4} \n\t" \
2995  "ldr r0, [%1, #4] \n\t" \
2996  "ldr r1, [%1, #8] \n\t" \
2997  "ldr r2, [%1, #12] \n\t" \
2998  "ldr r3, [%1, #16] \n\t" \
2999  "ldr r4, [%1] \n\t" /* target->r4 */ \
3000  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3001  "add sp, sp, #24 \n\t" \
3002  "mov %0, r0" \
3003  : /*out*/ "=r" (_res) \
3004  : /*in*/ "0" (&_argvec[0]) \
3005  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3006  ); \
3007  lval = (__typeof__(lval)) _res; \
3008  } while (0)
3009 
3010 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
3011  arg6,arg7,arg8,arg9,arg10, \
3012  arg11) \
3013  do { \
3014  volatile OrigFn _orig = (orig); \
3015  volatile unsigned long _argvec[12]; \
3016  volatile unsigned long _res; \
3017  _argvec[0] = (unsigned long)_orig.nraddr; \
3018  _argvec[1] = (unsigned long)(arg1); \
3019  _argvec[2] = (unsigned long)(arg2); \
3020  _argvec[3] = (unsigned long)(arg3); \
3021  _argvec[4] = (unsigned long)(arg4); \
3022  _argvec[5] = (unsigned long)(arg5); \
3023  _argvec[6] = (unsigned long)(arg6); \
3024  _argvec[7] = (unsigned long)(arg7); \
3025  _argvec[8] = (unsigned long)(arg8); \
3026  _argvec[9] = (unsigned long)(arg9); \
3027  _argvec[10] = (unsigned long)(arg10); \
3028  _argvec[11] = (unsigned long)(arg11); \
3029  __asm__ volatile( \
3030  "ldr r0, [%1, #40] \n\t" \
3031  "ldr r1, [%1, #44] \n\t" \
3032  "push {r0, r1} \n\t" \
3033  "ldr r0, [%1, #20] \n\t" \
3034  "ldr r1, [%1, #24] \n\t" \
3035  "ldr r2, [%1, #28] \n\t" \
3036  "ldr r3, [%1, #32] \n\t" \
3037  "ldr r4, [%1, #36] \n\t" \
3038  "push {r0, r1, r2, r3, r4} \n\t" \
3039  "ldr r0, [%1, #4] \n\t" \
3040  "ldr r1, [%1, #8] \n\t" \
3041  "ldr r2, [%1, #12] \n\t" \
3042  "ldr r3, [%1, #16] \n\t" \
3043  "ldr r4, [%1] \n\t" /* target->r4 */ \
3044  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3045  "add sp, sp, #28 \n\t" \
3046  "mov %0, r0" \
3047  : /*out*/ "=r" (_res) \
3048  : /*in*/ "0" (&_argvec[0]) \
3049  : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \
3050  ); \
3051  lval = (__typeof__(lval)) _res; \
3052  } while (0)
3053 
3054 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
3055  arg6,arg7,arg8,arg9,arg10, \
3056  arg11,arg12) \
3057  do { \
3058  volatile OrigFn _orig = (orig); \
3059  volatile unsigned long _argvec[13]; \
3060  volatile unsigned long _res; \
3061  _argvec[0] = (unsigned long)_orig.nraddr; \
3062  _argvec[1] = (unsigned long)(arg1); \
3063  _argvec[2] = (unsigned long)(arg2); \
3064  _argvec[3] = (unsigned long)(arg3); \
3065  _argvec[4] = (unsigned long)(arg4); \
3066  _argvec[5] = (unsigned long)(arg5); \
3067  _argvec[6] = (unsigned long)(arg6); \
3068  _argvec[7] = (unsigned long)(arg7); \
3069  _argvec[8] = (unsigned long)(arg8); \
3070  _argvec[9] = (unsigned long)(arg9); \
3071  _argvec[10] = (unsigned long)(arg10); \
3072  _argvec[11] = (unsigned long)(arg11); \
3073  _argvec[12] = (unsigned long)(arg12); \
3074  __asm__ volatile( \
3075  "ldr r0, [%1, #40] \n\t" \
3076  "ldr r1, [%1, #44] \n\t" \
3077  "ldr r2, [%1, #48] \n\t" \
3078  "push {r0, r1, r2} \n\t" \
3079  "ldr r0, [%1, #20] \n\t" \
3080  "ldr r1, [%1, #24] \n\t" \
3081  "ldr r2, [%1, #28] \n\t" \
3082  "ldr r3, [%1, #32] \n\t" \
3083  "ldr r4, [%1, #36] \n\t" \
3084  "push {r0, r1, r2, r3, r4} \n\t" \
3085  "ldr r0, [%1, #4] \n\t" \
3086  "ldr r1, [%1, #8] \n\t" \
3087  "ldr r2, [%1, #12] \n\t" \
3088  "ldr r3, [%1, #16] \n\t" \
3089  "ldr r4, [%1] \n\t" /* target->r4 */ \
3090  VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3091  "add sp, sp, #32 \n\t" \
3092  "mov %0, r0" \
3093  : /*out*/ "=r" (_res) \
3094  : /*in*/ "0" (&_argvec[0]) \
3095  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3096  ); \
3097  lval = (__typeof__(lval)) _res; \
3098  } while (0)
3099 
3100 #endif /* PLAT_arm_linux */
3101 
3102 /* ------------------------- s390x-linux ------------------------- */
3103 
3104 #if defined(PLAT_s390x_linux)
3105 
3106 /* Similar workaround as amd64 (see above), but we use r11 as frame
3107  pointer and save the old r11 in r7. r11 might be used for
3108  argvec, therefore we copy argvec in r1 since r1 is clobbered
3109  after the call anyway. */
3110 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3111 # define __FRAME_POINTER \
3112  ,"d"(__builtin_dwarf_cfa())
3113 # define VALGRIND_CFI_PROLOGUE \
3114  ".cfi_remember_state\n\t" \
3115  "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \
3116  "lgr 7,11\n\t" \
3117  "lgr 11,%2\n\t" \
3118  ".cfi_def_cfa r11, 0\n\t"
3119 # define VALGRIND_CFI_EPILOGUE \
3120  "lgr 11, 7\n\t" \
3121  ".cfi_restore_state\n\t"
3122 #else
3123 # define __FRAME_POINTER
3124 # define VALGRIND_CFI_PROLOGUE \
3125  "lgr 1,%1\n\t"
3126 # define VALGRIND_CFI_EPILOGUE
3127 #endif
3128 
3129 
3130 
3131 
3132 /* These regs are trashed by the hidden call. Note that we overwrite
3133  r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3134  function a proper return address. All others are ABI defined call
3135  clobbers. */
3136 #define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3137  "f0","f1","f2","f3","f4","f5","f6","f7"
3138 
3139 
3140 #define CALL_FN_W_v(lval, orig) \
3141  do { \
3142  volatile OrigFn _orig = (orig); \
3143  volatile unsigned long _argvec[1]; \
3144  volatile unsigned long _res; \
3145  _argvec[0] = (unsigned long)_orig.nraddr; \
3146  __asm__ volatile( \
3147  VALGRIND_CFI_PROLOGUE \
3148  "aghi 15,-160\n\t" \
3149  "lg 1, 0(1)\n\t" /* target->r1 */ \
3150  VALGRIND_CALL_NOREDIR_R1 \
3151  "lgr %0, 2\n\t" \
3152  "aghi 15,160\n\t" \
3153  VALGRIND_CFI_EPILOGUE \
3154  : /*out*/ "=d" (_res) \
3155  : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
3156  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3157  ); \
3158  lval = (__typeof__(lval)) _res; \
3159  } while (0)
3160 
3161 /* The call abi has the arguments in r2-r6 and stack */
3162 #define CALL_FN_W_W(lval, orig, arg1) \
3163  do { \
3164  volatile OrigFn _orig = (orig); \
3165  volatile unsigned long _argvec[2]; \
3166  volatile unsigned long _res; \
3167  _argvec[0] = (unsigned long)_orig.nraddr; \
3168  _argvec[1] = (unsigned long)arg1; \
3169  __asm__ volatile( \
3170  VALGRIND_CFI_PROLOGUE \
3171  "aghi 15,-160\n\t" \
3172  "lg 2, 8(1)\n\t" \
3173  "lg 1, 0(1)\n\t" \
3174  VALGRIND_CALL_NOREDIR_R1 \
3175  "lgr %0, 2\n\t" \
3176  "aghi 15,160\n\t" \
3177  VALGRIND_CFI_EPILOGUE \
3178  : /*out*/ "=d" (_res) \
3179  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3180  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3181  ); \
3182  lval = (__typeof__(lval)) _res; \
3183  } while (0)
3184 
3185 #define CALL_FN_W_WW(lval, orig, arg1, arg2) \
3186  do { \
3187  volatile OrigFn _orig = (orig); \
3188  volatile unsigned long _argvec[3]; \
3189  volatile unsigned long _res; \
3190  _argvec[0] = (unsigned long)_orig.nraddr; \
3191  _argvec[1] = (unsigned long)arg1; \
3192  _argvec[2] = (unsigned long)arg2; \
3193  __asm__ volatile( \
3194  VALGRIND_CFI_PROLOGUE \
3195  "aghi 15,-160\n\t" \
3196  "lg 2, 8(1)\n\t" \
3197  "lg 3,16(1)\n\t" \
3198  "lg 1, 0(1)\n\t" \
3199  VALGRIND_CALL_NOREDIR_R1 \
3200  "lgr %0, 2\n\t" \
3201  "aghi 15,160\n\t" \
3202  VALGRIND_CFI_EPILOGUE \
3203  : /*out*/ "=d" (_res) \
3204  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3205  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3206  ); \
3207  lval = (__typeof__(lval)) _res; \
3208  } while (0)
3209 
3210 #define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \
3211  do { \
3212  volatile OrigFn _orig = (orig); \
3213  volatile unsigned long _argvec[4]; \
3214  volatile unsigned long _res; \
3215  _argvec[0] = (unsigned long)_orig.nraddr; \
3216  _argvec[1] = (unsigned long)arg1; \
3217  _argvec[2] = (unsigned long)arg2; \
3218  _argvec[3] = (unsigned long)arg3; \
3219  __asm__ volatile( \
3220  VALGRIND_CFI_PROLOGUE \
3221  "aghi 15,-160\n\t" \
3222  "lg 2, 8(1)\n\t" \
3223  "lg 3,16(1)\n\t" \
3224  "lg 4,24(1)\n\t" \
3225  "lg 1, 0(1)\n\t" \
3226  VALGRIND_CALL_NOREDIR_R1 \
3227  "lgr %0, 2\n\t" \
3228  "aghi 15,160\n\t" \
3229  VALGRIND_CFI_EPILOGUE \
3230  : /*out*/ "=d" (_res) \
3231  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3232  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3233  ); \
3234  lval = (__typeof__(lval)) _res; \
3235  } while (0)
3236 
3237 #define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \
3238  do { \
3239  volatile OrigFn _orig = (orig); \
3240  volatile unsigned long _argvec[5]; \
3241  volatile unsigned long _res; \
3242  _argvec[0] = (unsigned long)_orig.nraddr; \
3243  _argvec[1] = (unsigned long)arg1; \
3244  _argvec[2] = (unsigned long)arg2; \
3245  _argvec[3] = (unsigned long)arg3; \
3246  _argvec[4] = (unsigned long)arg4; \
3247  __asm__ volatile( \
3248  VALGRIND_CFI_PROLOGUE \
3249  "aghi 15,-160\n\t" \
3250  "lg 2, 8(1)\n\t" \
3251  "lg 3,16(1)\n\t" \
3252  "lg 4,24(1)\n\t" \
3253  "lg 5,32(1)\n\t" \
3254  "lg 1, 0(1)\n\t" \
3255  VALGRIND_CALL_NOREDIR_R1 \
3256  "lgr %0, 2\n\t" \
3257  "aghi 15,160\n\t" \
3258  VALGRIND_CFI_EPILOGUE \
3259  : /*out*/ "=d" (_res) \
3260  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3261  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3262  ); \
3263  lval = (__typeof__(lval)) _res; \
3264  } while (0)
3265 
3266 #define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \
3267  do { \
3268  volatile OrigFn _orig = (orig); \
3269  volatile unsigned long _argvec[6]; \
3270  volatile unsigned long _res; \
3271  _argvec[0] = (unsigned long)_orig.nraddr; \
3272  _argvec[1] = (unsigned long)arg1; \
3273  _argvec[2] = (unsigned long)arg2; \
3274  _argvec[3] = (unsigned long)arg3; \
3275  _argvec[4] = (unsigned long)arg4; \
3276  _argvec[5] = (unsigned long)arg5; \
3277  __asm__ volatile( \
3278  VALGRIND_CFI_PROLOGUE \
3279  "aghi 15,-160\n\t" \
3280  "lg 2, 8(1)\n\t" \
3281  "lg 3,16(1)\n\t" \
3282  "lg 4,24(1)\n\t" \
3283  "lg 5,32(1)\n\t" \
3284  "lg 6,40(1)\n\t" \
3285  "lg 1, 0(1)\n\t" \
3286  VALGRIND_CALL_NOREDIR_R1 \
3287  "lgr %0, 2\n\t" \
3288  "aghi 15,160\n\t" \
3289  VALGRIND_CFI_EPILOGUE \
3290  : /*out*/ "=d" (_res) \
3291  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3292  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3293  ); \
3294  lval = (__typeof__(lval)) _res; \
3295  } while (0)
3296 
3297 #define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3298  arg6) \
3299  do { \
3300  volatile OrigFn _orig = (orig); \
3301  volatile unsigned long _argvec[7]; \
3302  volatile unsigned long _res; \
3303  _argvec[0] = (unsigned long)_orig.nraddr; \
3304  _argvec[1] = (unsigned long)arg1; \
3305  _argvec[2] = (unsigned long)arg2; \
3306  _argvec[3] = (unsigned long)arg3; \
3307  _argvec[4] = (unsigned long)arg4; \
3308  _argvec[5] = (unsigned long)arg5; \
3309  _argvec[6] = (unsigned long)arg6; \
3310  __asm__ volatile( \
3311  VALGRIND_CFI_PROLOGUE \
3312  "aghi 15,-168\n\t" \
3313  "lg 2, 8(1)\n\t" \
3314  "lg 3,16(1)\n\t" \
3315  "lg 4,24(1)\n\t" \
3316  "lg 5,32(1)\n\t" \
3317  "lg 6,40(1)\n\t" \
3318  "mvc 160(8,15), 48(1)\n\t" \
3319  "lg 1, 0(1)\n\t" \
3320  VALGRIND_CALL_NOREDIR_R1 \
3321  "lgr %0, 2\n\t" \
3322  "aghi 15,168\n\t" \
3323  VALGRIND_CFI_EPILOGUE \
3324  : /*out*/ "=d" (_res) \
3325  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3326  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3327  ); \
3328  lval = (__typeof__(lval)) _res; \
3329  } while (0)
3330 
3331 #define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3332  arg6, arg7) \
3333  do { \
3334  volatile OrigFn _orig = (orig); \
3335  volatile unsigned long _argvec[8]; \
3336  volatile unsigned long _res; \
3337  _argvec[0] = (unsigned long)_orig.nraddr; \
3338  _argvec[1] = (unsigned long)arg1; \
3339  _argvec[2] = (unsigned long)arg2; \
3340  _argvec[3] = (unsigned long)arg3; \
3341  _argvec[4] = (unsigned long)arg4; \
3342  _argvec[5] = (unsigned long)arg5; \
3343  _argvec[6] = (unsigned long)arg6; \
3344  _argvec[7] = (unsigned long)arg7; \
3345  __asm__ volatile( \
3346  VALGRIND_CFI_PROLOGUE \
3347  "aghi 15,-176\n\t" \
3348  "lg 2, 8(1)\n\t" \
3349  "lg 3,16(1)\n\t" \
3350  "lg 4,24(1)\n\t" \
3351  "lg 5,32(1)\n\t" \
3352  "lg 6,40(1)\n\t" \
3353  "mvc 160(8,15), 48(1)\n\t" \
3354  "mvc 168(8,15), 56(1)\n\t" \
3355  "lg 1, 0(1)\n\t" \
3356  VALGRIND_CALL_NOREDIR_R1 \
3357  "lgr %0, 2\n\t" \
3358  "aghi 15,176\n\t" \
3359  VALGRIND_CFI_EPILOGUE \
3360  : /*out*/ "=d" (_res) \
3361  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3362  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3363  ); \
3364  lval = (__typeof__(lval)) _res; \
3365  } while (0)
3366 
3367 #define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3368  arg6, arg7 ,arg8) \
3369  do { \
3370  volatile OrigFn _orig = (orig); \
3371  volatile unsigned long _argvec[9]; \
3372  volatile unsigned long _res; \
3373  _argvec[0] = (unsigned long)_orig.nraddr; \
3374  _argvec[1] = (unsigned long)arg1; \
3375  _argvec[2] = (unsigned long)arg2; \
3376  _argvec[3] = (unsigned long)arg3; \
3377  _argvec[4] = (unsigned long)arg4; \
3378  _argvec[5] = (unsigned long)arg5; \
3379  _argvec[6] = (unsigned long)arg6; \
3380  _argvec[7] = (unsigned long)arg7; \
3381  _argvec[8] = (unsigned long)arg8; \
3382  __asm__ volatile( \
3383  VALGRIND_CFI_PROLOGUE \
3384  "aghi 15,-184\n\t" \
3385  "lg 2, 8(1)\n\t" \
3386  "lg 3,16(1)\n\t" \
3387  "lg 4,24(1)\n\t" \
3388  "lg 5,32(1)\n\t" \
3389  "lg 6,40(1)\n\t" \
3390  "mvc 160(8,15), 48(1)\n\t" \
3391  "mvc 168(8,15), 56(1)\n\t" \
3392  "mvc 176(8,15), 64(1)\n\t" \
3393  "lg 1, 0(1)\n\t" \
3394  VALGRIND_CALL_NOREDIR_R1 \
3395  "lgr %0, 2\n\t" \
3396  "aghi 15,184\n\t" \
3397  VALGRIND_CFI_EPILOGUE \
3398  : /*out*/ "=d" (_res) \
3399  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3400  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3401  ); \
3402  lval = (__typeof__(lval)) _res; \
3403  } while (0)
3404 
3405 #define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3406  arg6, arg7 ,arg8, arg9) \
3407  do { \
3408  volatile OrigFn _orig = (orig); \
3409  volatile unsigned long _argvec[10]; \
3410  volatile unsigned long _res; \
3411  _argvec[0] = (unsigned long)_orig.nraddr; \
3412  _argvec[1] = (unsigned long)arg1; \
3413  _argvec[2] = (unsigned long)arg2; \
3414  _argvec[3] = (unsigned long)arg3; \
3415  _argvec[4] = (unsigned long)arg4; \
3416  _argvec[5] = (unsigned long)arg5; \
3417  _argvec[6] = (unsigned long)arg6; \
3418  _argvec[7] = (unsigned long)arg7; \
3419  _argvec[8] = (unsigned long)arg8; \
3420  _argvec[9] = (unsigned long)arg9; \
3421  __asm__ volatile( \
3422  VALGRIND_CFI_PROLOGUE \
3423  "aghi 15,-192\n\t" \
3424  "lg 2, 8(1)\n\t" \
3425  "lg 3,16(1)\n\t" \
3426  "lg 4,24(1)\n\t" \
3427  "lg 5,32(1)\n\t" \
3428  "lg 6,40(1)\n\t" \
3429  "mvc 160(8,15), 48(1)\n\t" \
3430  "mvc 168(8,15), 56(1)\n\t" \
3431  "mvc 176(8,15), 64(1)\n\t" \
3432  "mvc 184(8,15), 72(1)\n\t" \
3433  "lg 1, 0(1)\n\t" \
3434  VALGRIND_CALL_NOREDIR_R1 \
3435  "lgr %0, 2\n\t" \
3436  "aghi 15,192\n\t" \
3437  VALGRIND_CFI_EPILOGUE \
3438  : /*out*/ "=d" (_res) \
3439  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3440  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3441  ); \
3442  lval = (__typeof__(lval)) _res; \
3443  } while (0)
3444 
3445 #define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3446  arg6, arg7 ,arg8, arg9, arg10) \
3447  do { \
3448  volatile OrigFn _orig = (orig); \
3449  volatile unsigned long _argvec[11]; \
3450  volatile unsigned long _res; \
3451  _argvec[0] = (unsigned long)_orig.nraddr; \
3452  _argvec[1] = (unsigned long)arg1; \
3453  _argvec[2] = (unsigned long)arg2; \
3454  _argvec[3] = (unsigned long)arg3; \
3455  _argvec[4] = (unsigned long)arg4; \
3456  _argvec[5] = (unsigned long)arg5; \
3457  _argvec[6] = (unsigned long)arg6; \
3458  _argvec[7] = (unsigned long)arg7; \
3459  _argvec[8] = (unsigned long)arg8; \
3460  _argvec[9] = (unsigned long)arg9; \
3461  _argvec[10] = (unsigned long)arg10; \
3462  __asm__ volatile( \
3463  VALGRIND_CFI_PROLOGUE \
3464  "aghi 15,-200\n\t" \
3465  "lg 2, 8(1)\n\t" \
3466  "lg 3,16(1)\n\t" \
3467  "lg 4,24(1)\n\t" \
3468  "lg 5,32(1)\n\t" \
3469  "lg 6,40(1)\n\t" \
3470  "mvc 160(8,15), 48(1)\n\t" \
3471  "mvc 168(8,15), 56(1)\n\t" \
3472  "mvc 176(8,15), 64(1)\n\t" \
3473  "mvc 184(8,15), 72(1)\n\t" \
3474  "mvc 192(8,15), 80(1)\n\t" \
3475  "lg 1, 0(1)\n\t" \
3476  VALGRIND_CALL_NOREDIR_R1 \
3477  "lgr %0, 2\n\t" \
3478  "aghi 15,200\n\t" \
3479  VALGRIND_CFI_EPILOGUE \
3480  : /*out*/ "=d" (_res) \
3481  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3482  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3483  ); \
3484  lval = (__typeof__(lval)) _res; \
3485  } while (0)
3486 
3487 #define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3488  arg6, arg7 ,arg8, arg9, arg10, arg11) \
3489  do { \
3490  volatile OrigFn _orig = (orig); \
3491  volatile unsigned long _argvec[12]; \
3492  volatile unsigned long _res; \
3493  _argvec[0] = (unsigned long)_orig.nraddr; \
3494  _argvec[1] = (unsigned long)arg1; \
3495  _argvec[2] = (unsigned long)arg2; \
3496  _argvec[3] = (unsigned long)arg3; \
3497  _argvec[4] = (unsigned long)arg4; \
3498  _argvec[5] = (unsigned long)arg5; \
3499  _argvec[6] = (unsigned long)arg6; \
3500  _argvec[7] = (unsigned long)arg7; \
3501  _argvec[8] = (unsigned long)arg8; \
3502  _argvec[9] = (unsigned long)arg9; \
3503  _argvec[10] = (unsigned long)arg10; \
3504  _argvec[11] = (unsigned long)arg11; \
3505  __asm__ volatile( \
3506  VALGRIND_CFI_PROLOGUE \
3507  "aghi 15,-208\n\t" \
3508  "lg 2, 8(1)\n\t" \
3509  "lg 3,16(1)\n\t" \
3510  "lg 4,24(1)\n\t" \
3511  "lg 5,32(1)\n\t" \
3512  "lg 6,40(1)\n\t" \
3513  "mvc 160(8,15), 48(1)\n\t" \
3514  "mvc 168(8,15), 56(1)\n\t" \
3515  "mvc 176(8,15), 64(1)\n\t" \
3516  "mvc 184(8,15), 72(1)\n\t" \
3517  "mvc 192(8,15), 80(1)\n\t" \
3518  "mvc 200(8,15), 88(1)\n\t" \
3519  "lg 1, 0(1)\n\t" \
3520  VALGRIND_CALL_NOREDIR_R1 \
3521  "lgr %0, 2\n\t" \
3522  "aghi 15,208\n\t" \
3523  VALGRIND_CFI_EPILOGUE \
3524  : /*out*/ "=d" (_res) \
3525  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3526  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3527  ); \
3528  lval = (__typeof__(lval)) _res; \
3529  } while (0)
3530 
3531 #define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3532  arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3533  do { \
3534  volatile OrigFn _orig = (orig); \
3535  volatile unsigned long _argvec[13]; \
3536  volatile unsigned long _res; \
3537  _argvec[0] = (unsigned long)_orig.nraddr; \
3538  _argvec[1] = (unsigned long)arg1; \
3539  _argvec[2] = (unsigned long)arg2; \
3540  _argvec[3] = (unsigned long)arg3; \
3541  _argvec[4] = (unsigned long)arg4; \
3542  _argvec[5] = (unsigned long)arg5; \
3543  _argvec[6] = (unsigned long)arg6; \
3544  _argvec[7] = (unsigned long)arg7; \
3545  _argvec[8] = (unsigned long)arg8; \
3546  _argvec[9] = (unsigned long)arg9; \
3547  _argvec[10] = (unsigned long)arg10; \
3548  _argvec[11] = (unsigned long)arg11; \
3549  _argvec[12] = (unsigned long)arg12; \
3550  __asm__ volatile( \
3551  VALGRIND_CFI_PROLOGUE \
3552  "aghi 15,-216\n\t" \
3553  "lg 2, 8(1)\n\t" \
3554  "lg 3,16(1)\n\t" \
3555  "lg 4,24(1)\n\t" \
3556  "lg 5,32(1)\n\t" \
3557  "lg 6,40(1)\n\t" \
3558  "mvc 160(8,15), 48(1)\n\t" \
3559  "mvc 168(8,15), 56(1)\n\t" \
3560  "mvc 176(8,15), 64(1)\n\t" \
3561  "mvc 184(8,15), 72(1)\n\t" \
3562  "mvc 192(8,15), 80(1)\n\t" \
3563  "mvc 200(8,15), 88(1)\n\t" \
3564  "mvc 208(8,15), 96(1)\n\t" \
3565  "lg 1, 0(1)\n\t" \
3566  VALGRIND_CALL_NOREDIR_R1 \
3567  "lgr %0, 2\n\t" \
3568  "aghi 15,216\n\t" \
3569  VALGRIND_CFI_EPILOGUE \
3570  : /*out*/ "=d" (_res) \
3571  : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3572  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3573  ); \
3574  lval = (__typeof__(lval)) _res; \
3575  } while (0)
3576 
3577 
3578 #endif /* PLAT_s390x_linux */
3579 
3580 
3581 /* ------------------------------------------------------------------ */
3582 /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
3583 /* */
3584 /* ------------------------------------------------------------------ */
3585 
3586 /* Some request codes. There are many more of these, but most are not
3587  exposed to end-user view. These are the public ones, all of the
3588  form 0x1000 + small_number.
3589 
3590  Core ones are in the range 0x00000000--0x0000ffff. The non-public
3591  ones start at 0x2000.
3592 */
3593 
3594 /* These macros are used by tools -- they must be public, but don't
3595  embed them into other programs. */
3596 #define VG_USERREQ_TOOL_BASE(a,b) \
3597  ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
3598 #define VG_IS_TOOL_USERREQ(a, b, v) \
3599  (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
3600 
3601 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
3602  This enum comprises an ABI exported by Valgrind to programs
3603  which use client requests. DO NOT CHANGE THE ORDER OF THESE
3604  ENTRIES, NOR DELETE ANY -- add new ones at the end. */
3605 typedef
3608 
3609  /* These allow any function to be called from the simulated
3610  CPU but run on the real CPU. Nb: the first arg passed to
3611  the function is always the ThreadId of the running
3612  thread! So CLIENT_CALL0 actually requires a 1 arg
3613  function, etc. */
3618 
3619  /* Can be useful in regression testing suites -- eg. can
3620  send Valgrind's output to /dev/null and still count
3621  errors. */
3623 
3624  /* Allows a string (gdb monitor command) to be passed to the tool
3625  Used for interaction with vgdb/gdb */
3627 
3628  /* These are useful and can be interpreted by any tool that
3629  tracks malloc() et al, by using vg_replace_malloc.c. */
3633  /* Memory pool support. */
3642 
3643  /* Allow printfs to valgrind log. */
3644  /* The first two pass the va_list argument by value, which
3645  assumes it is the same size as or smaller than a UWord,
3646  which generally isn't the case. Hence are deprecated.
3647  The second two pass the vargs by reference and so are
3648  immune to this problem. */
3649  /* both :: char* fmt, va_list vargs (DEPRECATED) */
3652  /* both :: char* fmt, va_list* vargs */
3655 
3656  /* Stack support. */
3660 
3661  /* Wine support */
3663 
3664  /* Querying of debug info. */
3666 
3667  /* Disable/enable error reporting level. Takes a single
3668  Word arg which is the delta to this thread's error
3669  disablement indicator. Hence 1 disables or further
3670  disables errors, and -1 moves back towards enablement.
3671  Other values are not allowed. */
3674 
3675 #if !defined(__GNUC__)
3676 # define __extension__ /* */
3677 #endif
3678 
3679 
3680 /* Returns the number of Valgrinds this code is running under. That
3681  is, 0 if running natively, 1 if running under Valgrind, 2 if
3682  running under Valgrind which is running under another Valgrind,
3683  etc. */
3684 #define RUNNING_ON_VALGRIND \
3685  (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \
3686  VG_USERREQ__RUNNING_ON_VALGRIND, \
3687  0, 0, 0, 0, 0) \
3688 
3689 
3690 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
3691  _qzz_len - 1]. Useful if you are debugging a JITter or some such,
3692  since it provides a way to make sure valgrind will retranslate the
3693  invalidated area. Returns no value. */
3694 #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
3695  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \
3696  _qzz_addr, _qzz_len, 0, 0, 0)
3697 
3698 
3699 /* These requests are for getting Valgrind itself to print something.
3700  Possibly with a backtrace. This is a really ugly hack. The return value
3701  is the number of characters printed, excluding the "**<pid>** " part at the
3702  start and the backtrace (if present). */
3703 
3704 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
3705 /* Modern GCC will optimize the static routine out if unused,
3706  and unused attribute will shut down warnings about it. */
3707 static int VALGRIND_PRINTF(const char *format, ...)
3708  __attribute__((format(__printf__, 1, 2), __unused__));
3709 #endif
3710 static int
3711 #if defined(_MSC_VER)
3712 __inline
3713 #endif
3714 VALGRIND_PRINTF(const char *format, ...)
3715 {
3716 #if defined(NVALGRIND)
3717  return 0;
3718 #else /* NVALGRIND */
3719 #if defined(_MSC_VER)
3720  uintptr_t _qzz_res;
3721 #else
3722  unsigned long _qzz_res;
3723 #endif
3724  va_list vargs;
3725  va_start(vargs, format);
3726 #if defined(_MSC_VER)
3727  _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3729  (uintptr_t)format,
3730  (uintptr_t)&vargs,
3731  0, 0, 0);
3732 #else
3733  _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3735  (unsigned long)format,
3736  (unsigned long)&vargs,
3737  0, 0, 0);
3738 #endif
3739  va_end(vargs);
3740  return (int)_qzz_res;
3741 #endif /* NVALGRIND */
3742 }
3743 
3744 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
3745 static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3746  __attribute__((format(__printf__, 1, 2), __unused__));
3747 #endif
3748 static int
3749 #if defined(_MSC_VER)
3750 __inline
3751 #endif
3752 VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3753 {
3754 #if defined(NVALGRIND)
3755  return 0;
3756 #else /* NVALGRIND */
3757 #if defined(_MSC_VER)
3758  uintptr_t _qzz_res;
3759 #else
3760  unsigned long _qzz_res;
3761 #endif
3762  va_list vargs;
3763  va_start(vargs, format);
3764 #if defined(_MSC_VER)
3765  _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3767  (uintptr_t)format,
3768  (uintptr_t)&vargs,
3769  0, 0, 0);
3770 #else
3771  _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3773  (unsigned long)format,
3774  (unsigned long)&vargs,
3775  0, 0, 0);
3776 #endif
3777  va_end(vargs);
3778  return (int)_qzz_res;
3779 #endif /* NVALGRIND */
3780 }
3781 
3782 
3783 /* These requests allow control to move from the simulated CPU to the
3784  real CPU, calling an arbitary function.
3785 
3786  Note that the current ThreadId is inserted as the first argument.
3787  So this call:
3788 
3789  VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
3790 
3791  requires f to have this signature:
3792 
3793  Word f(Word tid, Word arg1, Word arg2)
3794 
3795  where "Word" is a word-sized type.
3796 
3797  Note that these client requests are not entirely reliable. For example,
3798  if you call a function with them that subsequently calls printf(),
3799  there's a high chance Valgrind will crash. Generally, your prospects of
3800  these working are made higher if the called function does not refer to
3801  any global variables, and does not refer to any libc or other functions
3802  (printf et al). Any kind of entanglement with libc or dynamic linking is
3803  likely to have a bad outcome, for tricky reasons which we've grappled
3804  with a lot in the past.
3805 */
3806 #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
3807  VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3808  VG_USERREQ__CLIENT_CALL0, \
3809  _qyy_fn, \
3810  0, 0, 0, 0)
3811 
3812 #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
3813  VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3814  VG_USERREQ__CLIENT_CALL1, \
3815  _qyy_fn, \
3816  _qyy_arg1, 0, 0, 0)
3817 
3818 #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
3819  VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3820  VG_USERREQ__CLIENT_CALL2, \
3821  _qyy_fn, \
3822  _qyy_arg1, _qyy_arg2, 0, 0)
3823 
3824 #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
3825  VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3826  VG_USERREQ__CLIENT_CALL3, \
3827  _qyy_fn, \
3828  _qyy_arg1, _qyy_arg2, \
3829  _qyy_arg3, 0)
3830 
3831 
3832 /* Counts the number of errors that have been recorded by a tool. Nb:
3833  the tool must record the errors with VG_(maybe_record_error)() or
3834  VG_(unique_error)() for them to be counted. */
3835 #define VALGRIND_COUNT_ERRORS \
3836  (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \
3837  0 /* default return */, \
3838  VG_USERREQ__COUNT_ERRORS, \
3839  0, 0, 0, 0, 0)
3840 
3841 /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
3842  when heap blocks are allocated in order to give accurate results. This
3843  happens automatically for the standard allocator functions such as
3844  malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
3845  delete[], etc.
3846 
3847  But if your program uses a custom allocator, this doesn't automatically
3848  happen, and Valgrind will not do as well. For example, if you allocate
3849  superblocks with mmap() and then allocates chunks of the superblocks, all
3850  Valgrind's observations will be at the mmap() level and it won't know that
3851  the chunks should be considered separate entities. In Memcheck's case,
3852  that means you probably won't get heap block overrun detection (because
3853  there won't be redzones marked as unaddressable) and you definitely won't
3854  get any leak detection.
3855 
3856  The following client requests allow a custom allocator to be annotated so
3857  that it can be handled accurately by Valgrind.
3858 
3859  VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
3860  by a malloc()-like function. For Memcheck (an illustrative case), this
3861  does two things:
3862 
3863  - It records that the block has been allocated. This means any addresses
3864  within the block mentioned in error messages will be
3865  identified as belonging to the block. It also means that if the block
3866  isn't freed it will be detected by the leak checker.
3867 
3868  - It marks the block as being addressable and undefined (if 'is_zeroed' is
3869  not set), or addressable and defined (if 'is_zeroed' is set). This
3870  controls how accesses to the block by the program are handled.
3871 
3872  'addr' is the start of the usable block (ie. after any
3873  redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator
3874  can apply redzones -- these are blocks of padding at the start and end of
3875  each block. Adding redzones is recommended as it makes it much more likely
3876  Valgrind will spot block overruns. `is_zeroed' indicates if the memory is
3877  zeroed (or filled with another predictable value), as is the case for
3878  calloc().
3879 
3880  VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
3881  heap block -- that will be used by the client program -- is allocated.
3882  It's best to put it at the outermost level of the allocator if possible;
3883  for example, if you have a function my_alloc() which calls
3884  internal_alloc(), and the client request is put inside internal_alloc(),
3885  stack traces relating to the heap block will contain entries for both
3886  my_alloc() and internal_alloc(), which is probably not what you want.
3887 
3888  For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
3889  custom blocks from within a heap block, B, that has been allocated with
3890  malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
3891  -- the custom blocks will take precedence.
3892 
3893  VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For
3894  Memcheck, it does two things:
3895 
3896  - It records that the block has been deallocated. This assumes that the
3897  block was annotated as having been allocated via
3898  VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
3899 
3900  - It marks the block as being unaddressable.
3901 
3902  VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
3903  heap block is deallocated.
3904 
3905  VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
3906  Memcheck, it does four things:
3907 
3908  - It records that the size of a block has been changed. This assumes that
3909  the block was annotated as having been allocated via
3910  VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
3911 
3912  - If the block shrunk, it marks the freed memory as being unaddressable.
3913 
3914  - If the block grew, it marks the new area as undefined and defines a red
3915  zone past the end of the new block.
3916 
3917  - The V-bits of the overlap between the old and the new block are preserved.
3918 
3919  VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
3920  and before deallocation of the old block.
3921 
3922  In many cases, these three client requests will not be enough to get your
3923  allocator working well with Memcheck. More specifically, if your allocator
3924  writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
3925  will be necessary to mark the memory as addressable just before the zeroing
3926  occurs, otherwise you'll get a lot of invalid write errors. For example,
3927  you'll need to do this if your allocator recycles freed blocks, but it
3928  zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
3929  Alternatively, if your allocator reuses freed blocks for allocator-internal
3930  data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
3931 
3932  Really, what's happening is a blurring of the lines between the client
3933  program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
3934  memory should be considered unaddressable to the client program, but the
3935  allocator knows more than the rest of the client program and so may be able
3936  to safely access it. Extra client requests are necessary for Valgrind to
3937  understand the distinction between the allocator and the rest of the
3938  program.
3939 
3940  Ignored if addr == 0.
3941 */
3942 #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
3943  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \
3944  addr, sizeB, rzB, is_zeroed, 0)
3945 
3946 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
3947  Ignored if addr == 0.
3948 */
3949 #define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \
3950  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \
3951  addr, oldSizeB, newSizeB, rzB, 0)
3952 
3953 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
3954  Ignored if addr == 0.
3955 */
3956 #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
3957  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \
3958  addr, rzB, 0, 0, 0)
3959 
3960 /* Create a memory pool. */
3961 #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
3962  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
3963  pool, rzB, is_zeroed, 0, 0)
3964 
3965 /* Destroy a memory pool. */
3966 #define VALGRIND_DESTROY_MEMPOOL(pool) \
3967  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \
3968  pool, 0, 0, 0, 0)
3969 
3970 /* Associate a piece of memory with a memory pool. */
3971 #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
3972  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \
3973  pool, addr, size, 0, 0)
3974 
3975 /* Disassociate a piece of memory from a memory pool. */
3976 #define VALGRIND_MEMPOOL_FREE(pool, addr) \
3977  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \
3978  pool, addr, 0, 0, 0)
3979 
3980 /* Disassociate any pieces outside a particular range. */
3981 #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
3982  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \
3983  pool, addr, size, 0, 0)
3984 
3985 /* Resize and/or move a piece associated with a memory pool. */
3986 #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
3987  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \
3988  poolA, poolB, 0, 0, 0)
3989 
3990 /* Resize and/or move a piece associated with a memory pool. */
3991 #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
3992  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \
3993  pool, addrA, addrB, size, 0)
3994 
3995 /* Return 1 if a mempool exists, else 0. */
3996 #define VALGRIND_MEMPOOL_EXISTS(pool) \
3997  (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3998  VG_USERREQ__MEMPOOL_EXISTS, \
3999  pool, 0, 0, 0, 0)
4000 
4001 /* Mark a piece of memory as being a stack. Returns a stack id. */
4002 #define VALGRIND_STACK_REGISTER(start, end) \
4003  (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
4004  VG_USERREQ__STACK_REGISTER, \
4005  start, end, 0, 0, 0)
4006 
4007 /* Unmark the piece of memory associated with a stack id as being a
4008  stack. */
4009 #define VALGRIND_STACK_DEREGISTER(id) \
4010  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
4011  id, 0, 0, 0, 0)
4012 
4013 /* Change the start and end address of the stack id. */
4014 #define VALGRIND_STACK_CHANGE(id, start, end) \
4015  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \
4016  id, start, end, 0, 0)
4017 
4018 /* Load PDB debug info for Wine PE image_map. */
4019 #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \
4020  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
4021  fd, ptr, total_size, delta, 0)
4022 
4023 /* Map a code address to a source file name and line number. buf64
4024  must point to a 64-byte buffer in the caller's address space. The
4025  result will be dumped in there and is guaranteed to be zero
4026  terminated. If no info is found, the first byte is set to zero. */
4027 #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \
4028  (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
4029  VG_USERREQ__MAP_IP_TO_SRCLOC, \
4030  addr, buf64, 0, 0, 0)
4031 
4032 /* Disable error reporting for this thread. Behaves in a stack like
4033  way, so you can safely call this multiple times provided that
4034  VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
4035  to re-enable reporting. The first call of this macro disables
4036  reporting. Subsequent calls have no effect except to increase the
4037  number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
4038  reporting. Child threads do not inherit this setting from their
4039  parents -- they are always created with reporting enabled. */
4040 #define VALGRIND_DISABLE_ERROR_REPORTING \
4041  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4042  1, 0, 0, 0, 0)
4043 
4044 /* Re-enable error reporting, as per comments on
4045  VALGRIND_DISABLE_ERROR_REPORTING. */
4046 #define VALGRIND_ENABLE_ERROR_REPORTING \
4047  VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4048  -1, 0, 0, 0, 0)
4049 
4050 #undef PLAT_x86_darwin
4051 #undef PLAT_amd64_darwin
4052 #undef PLAT_x86_win32
4053 #undef PLAT_x86_linux
4054 #undef PLAT_amd64_linux
4055 #undef PLAT_ppc32_linux
4056 #undef PLAT_ppc64_linux
4057 #undef PLAT_arm_linux
4058 #undef PLAT_s390x_linux
4059 
4060 #endif /* __VALGRIND_H */
4061 
_W64 unsigned int uintptr_t
Definition: stdint.h:165
static int VALGRIND_PRINTF_BACKTRACE(const char *format,...)
Definition: valgrind.h:3752
Vg_ClientRequest
Definition: valgrind.h:3606
@ VG_USERREQ__DESTROY_MEMPOOL
Definition: valgrind.h:3635
@ VG_USERREQ__MAP_IP_TO_SRCLOC
Definition: valgrind.h:3665
@ VG_USERREQ__LOAD_PDB_DEBUGINFO
Definition: valgrind.h:3662
@ VG_USERREQ__PRINTF_BACKTRACE
Definition: valgrind.h:3651
@ VG_USERREQ__GDB_MONITOR_COMMAND
Definition: valgrind.h:3626
@ VG_USERREQ__MEMPOOL_ALLOC
Definition: valgrind.h:3636
@ VG_USERREQ__RESIZEINPLACE_BLOCK
Definition: valgrind.h:3631
@ VG_USERREQ__MALLOCLIKE_BLOCK
Definition: valgrind.h:3630
@ VG_USERREQ__COUNT_ERRORS
Definition: valgrind.h:3622
@ VG_USERREQ__STACK_REGISTER
Definition: valgrind.h:3657
@ VG_USERREQ__MEMPOOL_CHANGE
Definition: valgrind.h:3640
@ VG_USERREQ__PRINTF_VALIST_BY_REF
Definition: valgrind.h:3653
@ VG_USERREQ__RUNNING_ON_VALGRIND
Definition: valgrind.h:3606
@ VG_USERREQ__CLIENT_CALL0
Definition: valgrind.h:3614
@ VG_USERREQ__DISCARD_TRANSLATIONS
Definition: valgrind.h:3607
@ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF
Definition: valgrind.h:3654
@ VG_USERREQ__FREELIKE_BLOCK
Definition: valgrind.h:3632
@ VG_USERREQ__CREATE_MEMPOOL
Definition: valgrind.h:3634
@ VG_USERREQ__MOVE_MEMPOOL
Definition: valgrind.h:3639
@ VG_USERREQ__CLIENT_CALL3
Definition: valgrind.h:3617
@ VG_USERREQ__MEMPOOL_TRIM
Definition: valgrind.h:3638
@ VG_USERREQ__CLIENT_CALL2
Definition: valgrind.h:3616
@ VG_USERREQ__PRINTF
Definition: valgrind.h:3650
@ VG_USERREQ__CHANGE_ERR_DISABLEMENT
Definition: valgrind.h:3672
@ VG_USERREQ__STACK_CHANGE
Definition: valgrind.h:3659
@ VG_USERREQ__STACK_DEREGISTER
Definition: valgrind.h:3658
@ VG_USERREQ__MEMPOOL_FREE
Definition: valgrind.h:3637
@ VG_USERREQ__MEMPOOL_EXISTS
Definition: valgrind.h:3641
@ VG_USERREQ__CLIENT_CALL1
Definition: valgrind.h:3615
static int VALGRIND_PRINTF(const char *format,...)
Definition: valgrind.h:3714
#define VALGRIND_DO_CLIENT_REQUEST_EXPR( _zzq_default, _zzq_request, _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)
Definition: valgrind.h:186