Home | History | Annotate | Download | only in valgrind
      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 arbitary 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 */
   4034