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