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