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