1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* -*- c -*- 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ---------------------------------------------------------------- 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Notice that the following BSD-style license applies to this one 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown file (valgrind.h) only. The rest of Valgrind is licensed under the 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown terms of the GNU General Public License, version 2, unless 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown otherwise indicated. See the COPYING file in the source 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown distribution for details. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ---------------------------------------------------------------- 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2000-2012 Julian Seward. All rights reserved. 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Redistribution and use in source and binary forms, with or without 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modification, are permitted provided that the following conditions 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are met: 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1. Redistributions of source code must retain the above copyright 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown notice, this list of conditions and the following disclaimer. 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2. The origin of this software must not be misrepresented; you must 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not claim that you wrote the original software. If you use this 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown software in a product, an acknowledgment in the product 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown documentation would be appreciated but is not required. 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3. Altered source versions must be plainly marked as such, and must 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not be misrepresented as being the original software. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4. The name of the author may not be used to endorse or promote 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown products derived from this software without specific prior written 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown permission. 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ---------------------------------------------------------------- 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Notice that the above BSD-style license applies to this one file 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (valgrind.h) only. The entire rest of Valgrind is licensed under 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the terms of the GNU General Public License, version 2. See the 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown COPYING file in the source distribution for details. 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ---------------------------------------------------------------- 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This file is for inclusion into client (your!) code. 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You can use these macros to manipulate and query Valgrind's 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown execution inside your own programs. 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The resulting executables will still run without Valgrind, just a 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown little bit more slowly than they otherwise would, but otherwise 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unchanged. When not running on valgrind, each client request 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown consumes very few (eg. 7) instructions, so the resulting performance 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loss is negligible unless you plan to execute client requests 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown millions of times per second. Nevertheless, if that is still a 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown problem, you can compile with the NVALGRIND symbol defined (gcc 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -DNVALGRIND) so that client requests are not even compiled in. */ 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __VALGRIND_H 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __VALGRIND_H 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* VERSION NUMBER OF VALGRIND */ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Specify Valgrind's version number, so that user code can 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown conditionally compile based on our version number. Note that these 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown were introduced at version 3.6 and so do not exist in version 3.5 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or earlier. The recommended way to use them to check for "version 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X.Y or later" is (eg) 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (__VALGRIND_MAJOR__ > 3 \ 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __VALGRIND_MAJOR__ 3 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __VALGRIND_MINOR__ 8 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdarg.h> 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Nb: this file might be included in a file compiled with -ansi. So 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we can't use C++ style "//" comments nor the "asm" keyword (instead 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use "__asm__"). */ 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Derive some tags indicating what the target platform is. Note 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that in this file we're using the compiler's CPP symbols for 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identifying architectures, which are different to the ones we use 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown within the rest of Valgrind. Note, __powerpc__ is active for both 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32 and 64-bit PPC, whereas __powerpc64__ is only active for the 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown latter (on Linux, that is). 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Misc note: how to find out what's predefined in gcc by default: 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gcc -Wp,-dM somefile.c 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_x86_darwin 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_amd64_darwin 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_x86_win32 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_x86_linux 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_amd64_linux 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc32_linux 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc64_linux 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_arm_linux 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_s390x_linux 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef PLAT_mips32_linux 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__APPLE__) && defined(__i386__) 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_x86_darwin 1 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__APPLE__) && defined(__x86_64__) 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_amd64_darwin 1 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(__MINGW32__) || defined(__CYGWIN32__) \ 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || (defined(_WIN32) && defined(_M_IX86)) 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_x86_win32 1 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__i386__) 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_x86_linux 1 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__x86_64__) 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_amd64_linux 1 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_ppc32_linux 1 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_ppc64_linux 1 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__arm__) 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PLAT_arm_linux 1 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define PLAT_s390x_linux 1 142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(__linux__) && defined(__mips__) 143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define PLAT_mips32_linux 1 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If we're not compiling for our target platform, don't generate 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any inline asms. */ 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if !defined(NVALGRIND) 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define NVALGRIND 1 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* in here of use to end-users -- skip to the next section. */ 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * request. Accepts both pointers and integers as arguments. 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * client request that does not return a value. 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * client request and whose value equals the client request result. Accepts 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * both pointers and integers as arguments. Note that such calls are not 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * necessarily pure functions -- they may have side effects. 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_request, _zzq_arg1, _zzq_arg2, \ 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(NVALGRIND) 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Define NVALGRIND to completely remove the Valgrind magic sequence 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from the compiled code (analogous to NDEBUG's effects on 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert()) */ 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (_zzq_default) 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else /* ! NVALGRIND */ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The following defines the magic code sequences which the JITter 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown spots and handles magically. Don't look too closely at them as 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown they will rot your brain. 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The assembly code sequences for all architectures is in this one 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown file. This is because this file must be stand-alone, and we don't 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown want to have multiple files. 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value gets put in the return slot, so that everything works when 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this is executed not under Valgrind. Args are passed in a memory 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block, and so there's no intrinsic limit to the number that could 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be passed, but it's currently five. 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The macro args are: 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_rlval result lvalue 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_default default value (result returned when running on real CPU) 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_request request code 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1..5 request params 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The other two macros are used to support function wrapping, and are 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest's NRADDR pseudo-register and whatever other information is 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown needed to safely run the call original from the wrapper: on 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppc64-linux, the R2 value at the divert point is also needed. This 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown information is abstracted into a user-visible type, OrigFn. 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_* behaves the same as the following on the 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest, but guarantees that the branch instruction will not be 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown complete inline asm, since it needs to be combined with more magic 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inline asm stuff to be useful. 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-{linux,darwin} ---------------- */ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || (defined(PLAT_x86_win32) && defined(__GNUC__)) 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int nraddr; /* where's the code? */ 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "roll $3, %%edi ; roll $13, %%edi\n\t" \ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "roll $29, %%edi ; roll $19, %%edi\n\t" 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({volatile unsigned int _zzq_args[6]; \ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned int _zzq_result; \ 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[0] = (unsigned int)(_zzq_request); \ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %EDX = client_request ( %EAX ) */ \ 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgl %%ebx,%%ebx" \ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=d" (_zzq_result) \ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory" \ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned int __addr; \ 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %EAX = guest_NRADDR */ \ 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgl %%ecx,%%ecx" \ 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (__addr) \ 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory" \ 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_EAX \ 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* call-noredir *%EAX */ \ 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgl %%edx,%%edx\n\t" 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-Win32 ------------------------- */ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_win32) && !defined(__GNUC__) 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int nraddr; /* where's the code? */ 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER) 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm rol edi, 3 __asm rol edi, 13 \ 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm rol edi, 29 __asm rol edi, 19 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic __inline uintptr_t 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvalgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uintptr_t _zzq_arg5) 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile uintptr_t _zzq_args[6]; 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned int _zzq_result; 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[0] = (uintptr_t)(_zzq_request); 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[1] = (uintptr_t)(_zzq_arg1); 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[2] = (uintptr_t)(_zzq_arg2); 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[3] = (uintptr_t)(_zzq_arg3); 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[4] = (uintptr_t)(_zzq_arg4); 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[5] = (uintptr_t)(_zzq_arg5); 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __SPECIAL_INSTRUCTION_PREAMBLE 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* %EDX = client_request ( %EAX ) */ 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm xchg ebx,ebx 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm mov _zzq_result, edx 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return _zzq_result; 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned int __addr; \ 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %EAX = guest_NRADDR */ \ 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm xchg ecx,ecx \ 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm mov __addr, eax \ 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_EAX ERROR 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error Unsupported compiler. 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_win32 */ 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ amd64-{linux,darwin} --------------- */ 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long long int nraddr; /* where's the code? */ 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({ volatile unsigned long long int _zzq_args[6]; \ 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long long int _zzq_result; \ 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[0] = (unsigned long long int)(_zzq_request); \ 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %RDX = client_request ( %RAX ) */ \ 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgq %%rbx,%%rbx" \ 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=d" (_zzq_result) \ 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory" \ 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long long int __addr; \ 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %RAX = guest_NRADDR */ \ 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgq %%rcx,%%rcx" \ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (__addr) \ 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory" \ 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_RAX \ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* call-noredir *%RAX */ \ 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "xchgq %%rdx,%%rdx\n\t" 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc32-linux ------------------------ */ 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc32_linux) 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int nraddr; /* where's the code? */ 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({ unsigned int _zzq_args[6]; \ 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int _zzq_result; \ 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int* _zzq_ptr; \ 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[0] = (unsigned int)(_zzq_request); \ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_ptr = _zzq_args; \ 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile("mr 3,%1\n\t" /*default*/ \ 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 4,%2\n\t" /*ptr*/ \ 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %R3 = client_request ( %R4 ) */ \ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "or 1,1,1\n\t" \ 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" /*result*/ \ 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=b" (_zzq_result) \ 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "b" (_zzq_default), "b" (_zzq_ptr) \ 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory", "r3", "r4"); \ 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int __addr; \ 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %R3 = guest_NRADDR */ \ 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "or 2,2,2\n\t" \ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=b" (__addr) \ 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory", "r3" \ 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* branch-and-link-to-noredir *%R11 */ \ 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "or 3,3,3\n\t" 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc32_linux */ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc64-linux ------------------------ */ 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc64_linux) 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long long int nraddr; /* where's the code? */ 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long long int r2; /* what tocptr do we need? */ 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rotldi 0,0,61 ; rotldi 0,0,51\n\t" 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({ unsigned long long int _zzq_args[6]; \ 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long long int _zzq_result; \ 491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long long int* _zzq_ptr; \ 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[0] = (unsigned long long int)(_zzq_request); \ 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_ptr = _zzq_args; \ 499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile("mr 3,%1\n\t" /*default*/ \ 500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mr 4,%2\n\t" /*ptr*/ \ 501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __SPECIAL_INSTRUCTION_PREAMBLE \ 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %R3 = client_request ( %R4 ) */ \ 503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "or 1,1,1\n\t" \ 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mr %0,3" /*result*/ \ 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=b" (_zzq_result) \ 506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "b" (_zzq_default), "b" (_zzq_ptr) \ 507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "memory", "r3", "r4"); \ 508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long long int __addr; \ 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %R3 = guest_NRADDR */ \ 516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "or 2,2,2\n\t" \ 517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mr %0,3" \ 518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=b" (__addr) \ 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "memory", "r3" \ 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* %R3 = guest_NRADDR_GPR2 */ \ 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "or 4,4,4\n\t" \ 526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mr %0,3" \ 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=b" (__addr) \ 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "memory", "r3" \ 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->r2 = __addr; \ 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* branch-and-link-to-noredir *%R11 */ \ 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "or 3,3,3\n\t" 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc64_linux */ 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- arm-linux ------------------------- */ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_arm_linux) 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int nraddr; /* where's the code? */ 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn; 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE \ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({volatile unsigned int _zzq_args[6]; \ 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned int _zzq_result; \ 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[0] = (unsigned int)(_zzq_request); \ 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile("mov r3, %1\n\t" /*default*/ \ 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov r4, %2\n\t" /*ptr*/ \ 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* R3 = client_request ( R4 ) */ \ 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "orr r10, r10, r10\n\t" \ 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r3" /*result*/ \ 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=r" (_zzq_result) \ 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (_zzq_default), "r" (&_zzq_args[0]) \ 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc","memory", "r3", "r4"); \ 577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int __addr; \ 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* R3 = guest_NRADDR */ \ 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "orr r11, r11, r11\n\t" \ 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r3" \ 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=r" (__addr) \ 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : \ 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory", "r3" \ 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _zzq_orig->nraddr = __addr; \ 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __SPECIAL_INSTRUCTION_PREAMBLE \ 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* branch-and-link-to-noredir *%R4 */ \ 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "orr r12, r12, r12\n\t" 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_arm_linux */ 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------ s390x-linux ------------------------ */ 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(PLAT_s390x_linux) 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long long int nraddr; /* where's the code? */ 6089bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root } 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov OrigFn; 6109bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * code. This detection is implemented in platform specific toIR.c 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * (e.g. VEX/priv/guest_s390_decoder.c). 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __SPECIAL_INSTRUCTION_PREAMBLE \ 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lr 15,15\n\t" \ 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lr 1,1\n\t" \ 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lr 2,2\n\t" \ 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lr 3,3\n\t" 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_default, _zzq_request, \ 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __extension__ \ 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({volatile unsigned long long int _zzq_args[6]; \ 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long long int _zzq_result; \ 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[0] = (unsigned long long int)(_zzq_request); \ 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile(/* r2 = args */ \ 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 2,%1\n\t" \ 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* r3 = default */ \ 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 3,%2\n\t" \ 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __SPECIAL_INSTRUCTION_PREAMBLE \ 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __CLIENT_REQUEST_CODE \ 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* results = r3 */ \ 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 3\n\t" \ 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=d" (_zzq_result) \ 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "2", "3", "memory" \ 648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_result; \ 650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }) 651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long long int __addr; \ 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __GET_NR_CONTEXT_CODE \ 657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 3\n\t" \ 658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (__addr) \ 659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : \ 660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "3", "memory" \ 661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _zzq_orig->nraddr = __addr; \ 663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_CALL_NOREDIR_R1 \ 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __SPECIAL_INSTRUCTION_PREAMBLE \ 667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __CALL_NO_REDIR_CODE 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* PLAT_s390x_linux */ 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------- mips32-linux ---------------- */ 672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_mips32_linux) 674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef 676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct { 677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned int nraddr; /* where's the code? */ 678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng OrigFn; 680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* .word 0x342 682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word 0x742 683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word 0xC2 684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word 0x4C2*/ 685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __SPECIAL_INSTRUCTION_PREAMBLE \ 686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl $0, $0, 13\n\t" \ 687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl $0, $0, 29\n\t" \ 688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl $0, $0, 3\n\t" \ 689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl $0, $0, 19\n\t" 690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_default, _zzq_request, \ 693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __extension__ \ 695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ({ volatile unsigned int _zzq_args[6]; \ 696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned int _zzq_result; \ 697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[0] = (unsigned int)(_zzq_request); \ 698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile("move $11, %1\n\t" /*default*/ \ 704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move $12, %2\n\t" /*ptr*/ \ 705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __SPECIAL_INSTRUCTION_PREAMBLE \ 706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* T3 = client_request ( T4 ) */ \ 707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "or $13, $13, $13\n\t" \ 708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $11\n\t" /*result*/ \ 709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "=r" (_zzq_result) \ 710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "r" (_zzq_default), "r" (&_zzq_args[0]) \ 711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "cc","memory", "t3", "t4"); \ 712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_result; \ 713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng }) 714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned int __addr; \ 718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* %t9 = guest_NRADDR */ \ 720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "or $14, $14, $14\n\t" \ 721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $11" /*result*/ \ 722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "=r" (__addr) \ 723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : \ 724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "cc", "memory" , "t3" \ 725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _zzq_orig->nraddr = __addr; \ 727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_CALL_NOREDIR_T9 \ 730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __SPECIAL_INSTRUCTION_PREAMBLE \ 731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* call-noredir *%t9 */ \ 732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "or $15, $15, $15\n\t" 733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_mips32_linux */ 734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Insert assembly code for other platforms here... */ 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* NVALGRIND */ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ugly. It's the least-worst tradeoff I can think of. */ 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */ 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This section defines magic (a.k.a appalling-hack) macros for doing 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guaranteed-no-redirection macros, so as to get from function 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrappers to the functions they are wrapping. The whole point is to 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown construct standard call sequences, but to do the call itself with a 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown special no-redirect call pseudo-instruction that the JIT 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown understands and handles specially. This section is long and 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown repetitious, and I can't see a way to make it shorter. 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The naming scheme is as follows: 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'W' stands for "word" and 'v' for "void". Hence there are 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown different macros for calling arity 0, 1, 2, 3, 4, etc, functions, 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and for each, the possibility of returning a word-typed result, or 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no result. 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use these to write the name of your wrapper. NOTE: duplicates 764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts 765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the default behaviour equivalance class tag "0000" into the name. 766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov See pub_tool_redir.h for details -- normally you don't need to 767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov think about this, though. */ 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use an extra level of macroisation so as to ensure the soname/fnname 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args are fully macro-expanded before pasting them together. */ 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ 774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ 777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use this macro from within a wrapper function to collect the 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown context (address and possibly other info) of the original function. 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Once you have that you can then use it in one of the CALL_FN_ 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown macros. The type of the argument _lval is OrigFn. */ 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Also provide end-user facilities for function replacement, rather 786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng than wrapping. A replacement function differs from a wrapper in 787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng that it has no way to get hold of the original function being 788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng called, and hence no way to call onwards to it. In a replacement 789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng function, VALGRIND_GET_ORIG_FN always returns zero. */ 790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ 792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) 793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ 795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) 796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Derivatives of the main macros below, for calling functions 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown returning void. */ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_v(fnptr) \ 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_v(_junk,fnptr); } while (0) 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_W(fnptr, arg1) \ 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_W(_junk,fnptr,arg1); } while (0) 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WW(fnptr, arg1,arg2) \ 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { volatile unsigned long _junk; \ 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-{linux,darwin} ---------------- */ 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. No need to mention eax 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as gcc can already see that, plus causes gcc to bomb. */ 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function 841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call and restore it afterwards as gcc may not keep the stack 842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pointer aligned if it doesn't realise calls are being made 843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to other functions. */ 844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK \ 846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movl %%esp,%%edi\n\t" \ 847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "andl $0xfffffff0,%%esp\n\t" 848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK \ 849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movl %%edi,%%esp\n\t" 850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown long) == 4. */ 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig) \ 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[1]; \ 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1) \ 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[2]; \ 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $12, %%esp\n\t" \ 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3]; \ 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $8, %%esp\n\t" \ 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[4]; \ 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $4, %%esp\n\t" \ 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[5]; \ 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[6]; \ 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $12, %%esp\n\t" \ 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[7]; \ 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $8, %%esp\n\t" \ 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7) \ 1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[8]; \ 1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $4, %%esp\n\t" \ 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8) \ 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[9]; \ 1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 32(%%eax)\n\t" \ 1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9) \ 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[10]; \ 1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $12, %%esp\n\t" \ 1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 36(%%eax)\n\t" \ 1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 32(%%eax)\n\t" \ 1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10) \ 1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[11]; \ 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $8, %%esp\n\t" \ 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 40(%%eax)\n\t" \ 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 36(%%eax)\n\t" \ 1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 32(%%eax)\n\t" \ 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg6,arg7,arg8,arg9,arg10, \ 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg11) \ 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[12]; \ 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)(arg11); \ 1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "subl $4, %%esp\n\t" \ 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 44(%%eax)\n\t" \ 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 40(%%eax)\n\t" \ 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 36(%%eax)\n\t" \ 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 32(%%eax)\n\t" \ 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg6,arg7,arg8,arg9,arg10, \ 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg11,arg12) \ 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[13]; \ 1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)(arg11); \ 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[12] = (unsigned long)(arg12); \ 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 48(%%eax)\n\t" \ 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 44(%%eax)\n\t" \ 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 40(%%eax)\n\t" \ 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 36(%%eax)\n\t" \ 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 32(%%eax)\n\t" \ 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 28(%%eax)\n\t" \ 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 24(%%eax)\n\t" \ 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 20(%%eax)\n\t" \ 1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 16(%%eax)\n\t" \ 1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 12(%%eax)\n\t" \ 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 8(%%eax)\n\t" \ 1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pushl 4(%%eax)\n\t" \ 1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CALL_NOREDIR_EAX \ 1253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=a" (_res) \ 1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "a" (&_argvec[0]) \ 1256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ 1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_linux || PLAT_x86_darwin */ 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ amd64-{linux,darwin} --------------- */ 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) 1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */ 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rdi", "r8", "r9", "r10", "r11" 1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is all pretty complex. It's so as to make stack unwinding 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown work reliably. See bug 243270. The basic problem is the sub and 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add of 128 of %rsp in all of the following macros. If gcc believes 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the CFA is in %rsp, then unwinding may fail, because what's at the 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CFA is not what gcc "expected" when it constructs the CFIs for the 1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown places where the macros are instantiated. 1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown But we can't just add a CFI annotation to increase the CFA offset 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by 128, to match the sub of 128 from %rsp, because we don't know 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whether gcc has chosen %rsp as the CFA at that point, or whether it 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has chosen some other register (eg, %rbp). In the latter case, 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown adding a CFI annotation to change the CFA offset is simply wrong. 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown So the solution is to get hold of the CFA using 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __builtin_dwarf_cfa(), put it in a known register, and add a 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CFI annotation to say what the register is. We choose %rbp for 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this (perhaps perversely), because: 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (1) %rbp is already subject to unwinding. If a new register was 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chosen then the unwinder would have to unwind it in all stack 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown traces, which is expensive, and 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (2) %rbp is already subject to precise exception updates in the 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown JIT. If a new register was chosen, we'd have to have precise 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exceptions for it too, which reduces performance of the 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown generated code. 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown However .. one extra complication. We can't just whack the result 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of __builtin_dwarf_cfa() into %rbp and then add %rbp to the 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown list of trashed registers at the end of the inline assembly 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fragments; gcc won't allow %rbp to appear in that list. Hence 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instead we need to stash %rbp in %r15 for the duration of the asm, 1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and say that %r15 is trashed instead. gcc seems happy to go with 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that. 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Oh .. and this all needs to be conditionalised so that it is 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unchanged from before this commit, when compiled with older gccs 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that don't support __builtin_dwarf_cfa. Furthermore, since 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this header file is freestanding, it has to be independent of 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown config.h, and so the following conditionalisation cannot depend on 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown configure time checks. 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Although it's not clear from 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', 1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this expression excludes Darwin. 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .cfi directives in Darwin assembly appear to be completely 1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown different and I haven't investigated how they work. 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For even more entertainment value, note we have to use the 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown completely undocumented __builtin_dwarf_cfa(), which appears to 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown really compute the CFA, whereas __builtin_frame_address(0) claims 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to but actually doesn't. See 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown https://bugs.kde.org/show_bug.cgi?id=243270#c47 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) 1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define __FRAME_POINTER \ 1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ,"r"(__builtin_dwarf_cfa()) 1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define VALGRIND_CFI_PROLOGUE \ 1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movq %%rbp, %%r15\n\t" \ 1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movq %2, %%rbp\n\t" \ 1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".cfi_remember_state\n\t" \ 1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".cfi_def_cfa rbp, 0\n\t" 1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define VALGRIND_CFI_EPILOGUE \ 1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movq %%r15, %%rbp\n\t" \ 1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".cfi_restore_state\n\t" 1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define __FRAME_POINTER 1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define VALGRIND_CFI_PROLOGUE 1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define VALGRIND_CFI_EPILOGUE 1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function 1345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call and restore it afterwards as gcc may not keep the stack 1346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pointer aligned if it doesn't realise calls are being made 1347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to other functions. */ 1348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK \ 1350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq %%rsp,%%r14\n\t" \ 1351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "andq $0xfffffffffffffff0,%%rsp\n\t" 1352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK \ 1353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq %%r14,%%rsp\n\t" 1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned 1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown long) == 8. */ 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown macros. In order not to trash the stack redzone, we need to drop 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %rsp by 128 before the hidden call, and restore afterwards. The 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nastyness is that it is only by luck that the stack still appears 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to be unwindable during the hidden call - since then the behaviour 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of any routine using this macro does not match what the CFI data 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown says. Sigh. 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Why is this important? Imagine that a wrapper has a stack 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allocated local, and passes to the hidden call, a pointer to it. 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Because gcc does not know about the hidden call, it may allocate 1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that local in the redzone. Unfortunately the hidden call may then 1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown trash it before it comes to use it. So we must step clear of the 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redzone, for the duration of the hidden call, to make it safe. 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Probably the same problem afflicts the other redzone-style ABIs too 1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ppc64-linux); but for those, the stack is 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown self describing (none of this CFI nonsense) so at least messing 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with the stack pointer doesn't give a danger of non-unwindable 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack. */ 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_v(lval, orig) \ 1380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[1]; \ 1383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_W(lval, orig, arg1) \ 1401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[2]; \ 1404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 1424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[3]; \ 1427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 1449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[4]; \ 1452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 1476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[5]; \ 1479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 1505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[6]; \ 1508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 1536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[7]; \ 1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7) \ 1570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[8]; \ 1573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $136,%%rsp\n\t" \ 1586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8) \ 1606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[9]; \ 1609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1614663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 1619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 64(%%rax)\n\t" \ 1624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9) \ 1644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[10]; \ 1647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 1657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 1658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $136,%%rsp\n\t" \ 1662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 72(%%rax)\n\t" \ 1663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 64(%%rax)\n\t" \ 1664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10) \ 1684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[11]; \ 1687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 1697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 1698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 1699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 80(%%rax)\n\t" \ 1704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 72(%%rax)\n\t" \ 1705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 64(%%rax)\n\t" \ 1706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10,arg11) \ 1726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[12]; \ 1729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1735663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 1739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 1740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 1741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[11] = (unsigned long)(arg11); \ 1742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $136,%%rsp\n\t" \ 1746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 88(%%rax)\n\t" \ 1747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 80(%%rax)\n\t" \ 1748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 72(%%rax)\n\t" \ 1749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 64(%%rax)\n\t" \ 1750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10,arg11,arg12) \ 1770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 1771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 1772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[13]; \ 1773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 1774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 1775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 1776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 1777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 1778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 1779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 1780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 1781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 1782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 1783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 1784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 1785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[11] = (unsigned long)(arg11); \ 1786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[12] = (unsigned long)(arg12); \ 1787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 1788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE \ 1789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subq $128,%%rsp\n\t" \ 1791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 96(%%rax)\n\t" \ 1792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 88(%%rax)\n\t" \ 1793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 80(%%rax)\n\t" \ 1794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 72(%%rax)\n\t" \ 1795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 64(%%rax)\n\t" \ 1796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "pushq 56(%%rax)\n\t" \ 1797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 48(%%rax), %%r9\n\t" \ 1798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 40(%%rax), %%r8\n\t" \ 1799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 32(%%rax), %%rcx\n\t" \ 1800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 24(%%rax), %%rdx\n\t" \ 1801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 16(%%rax), %%rsi\n\t" \ 1802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq 8(%%rax), %%rdi\n\t" \ 1803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_RAX \ 1805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_EPILOGUE \ 1807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=a" (_res) \ 1808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 1809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ 1810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 1811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 1812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 1813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ 1815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------ ppc32-linux ------------------------ */ 1817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_ppc32_linux) 1819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is useful for finding out about the on-stack stuff: 1821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng extern int f9 ( int,int,int,int,int,int,int,int,int ); 1823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng extern int f10 ( int,int,int,int,int,int,int,int,int,int ); 1824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); 1825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); 1826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int g9 ( void ) { 1828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return f9(11,22,33,44,55,66,77,88,99); 1829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int g10 ( void ) { 1831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return f10(11,22,33,44,55,66,77,88,99,110); 1832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int g11 ( void ) { 1834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return f11(11,22,33,44,55,66,77,88,99,110,121); 1835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int g12 ( void ) { 1837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return f12(11,22,33,44,55,66,77,88,99,110,121,132); 1838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 1840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ 1842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These regs are trashed by the hidden call. */ 1844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __CALLER_SAVED_REGS \ 1845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lr", "ctr", "xer", \ 1846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ 1847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ 1848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "r11", "r12", "r13" 1849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function 1851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call and restore it afterwards as gcc may not keep the stack 1852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pointer aligned if it doesn't realise calls are being made 1853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to other functions. */ 1854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK \ 1856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 28,1\n\t" \ 1857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "rlwinm 1,1,0,0,27\n\t" 1858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK \ 1859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 1,28\n\t" 1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These CALL_FN_ macros assume that on ppc32-linux, 1862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sizeof(unsigned long) == 4. */ 1863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig) \ 1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[1]; \ 1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 1874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 1877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 1878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 1879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1) \ 1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[2]; \ 1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 1896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 1899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 1900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 1901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3]; \ 1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 1913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 1919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 1920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 1923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 1924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 1925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[4]; \ 1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 1937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 1938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 1944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 1945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 1946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 1949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 1950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 1951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[5]; \ 1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 1963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 1964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 1965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 1974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[6]; \ 1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 1990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 1991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 1992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 1993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 1994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 1996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 1997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 1998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 2000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 2001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 2004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 2007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 2008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 2009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[7]; \ 2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 2021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 2022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 2023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 2024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 2025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)arg6; \ 2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 11,%1\n\t" \ 2029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 2031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 2032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 8,24(11)\n\t" \ 2035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 11,0(11)\n\t" /* target->r11 */ \ 2036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr %0,3" \ 2039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 2040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "r" (&_argvec[0]) \ 2041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7) \ 2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[8]; \ 2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)arg1; \ 2054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)arg2; \ 2055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 2056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 2057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 2058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)arg6; \ 2059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)arg7; \ 2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 4,8(11)\n\t" \ 2065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 2066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 8,24(11)\n\t" \ 2069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 9,28(11)\n\t" \ 2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8) \ 2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[9]; \ 2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)arg1; \ 2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)arg2; \ 2090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)arg3; \ 2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)arg6; \ 2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)arg7; \ 2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)arg8; \ 2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 4,8(11)\n\t" \ 2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 5,12(11)\n\t" \ 2102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 8,24(11)\n\t" \ 2105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 9,28(11)\n\t" \ 2106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9) \ 2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[10]; \ 2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)arg1; \ 2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)arg2; \ 2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)arg3; \ 2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)arg4; \ 2129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 2130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)arg6; \ 2131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)arg7; \ 2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)arg8; \ 2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)arg9; \ 2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addi 1,1,-16\n\t" \ 2138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* arg9 */ \ 2139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,36(11)\n\t" \ 2140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stw 3,8(1)\n\t" \ 2141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* args1-8 */ \ 2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 4,8(11)\n\t" \ 2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 5,12(11)\n\t" \ 2145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 8,24(11)\n\t" \ 2148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 9,28(11)\n\t" \ 2149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10) \ 2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[11]; \ 2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)arg1; \ 2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)arg2; \ 2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)arg3; \ 2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)arg4; \ 2172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)arg5; \ 2173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)arg6; \ 2174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)arg7; \ 2175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)arg8; \ 2176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)arg9; \ 2177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)arg10; \ 2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addi 1,1,-16\n\t" \ 2182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* arg10 */ \ 2183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,40(11)\n\t" \ 2184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stw 3,12(1)\n\t" \ 2185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* arg9 */ \ 2186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 3,36(11)\n\t" \ 2187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stw 3,8(1)\n\t" \ 2188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* args1-8 */ \ 2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 4,8(11)\n\t" \ 2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 5,12(11)\n\t" \ 2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 7,20(11)\n\t" \ 2194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 8,24(11)\n\t" \ 2195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 9,28(11)\n\t" \ 2196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10,arg11) \ 2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[12]; \ 2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)arg1; \ 2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)arg2; \ 2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)arg3; \ 2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)arg4; \ 2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)arg5; \ 2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)arg6; \ 2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)arg7; \ 2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)arg8; \ 2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)arg9; \ 2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)arg10; \ 2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)arg11; \ 2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-32\n\t" \ 2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg11 */ \ 2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,44(11)\n\t" \ 2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,16(1)\n\t" \ 2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg10 */ \ 2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,40(11)\n\t" \ 2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,12(1)\n\t" \ 2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,36(11)\n\t" \ 2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,8(1)\n\t" \ 2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 4,8(11)\n\t" \ 2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 5,12(11)\n\t" \ 2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 7,20(11)\n\t" \ 2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 8,24(11)\n\t" \ 2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 9,28(11)\n\t" \ 2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10,arg11,arg12) \ 2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[13]; \ 2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)arg1; \ 2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)arg2; \ 2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)arg3; \ 2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)arg4; \ 2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)arg5; \ 2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)arg6; \ 2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)arg7; \ 2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)arg8; \ 2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)arg9; \ 2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)arg10; \ 2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)arg11; \ 2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[12] = (unsigned long)arg12; \ 2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-32\n\t" \ 2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg12 */ \ 2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,48(11)\n\t" \ 2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,20(1)\n\t" \ 2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg11 */ \ 2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,44(11)\n\t" \ 2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,16(1)\n\t" \ 2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg10 */ \ 2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,40(11)\n\t" \ 2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,12(1)\n\t" \ 2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,36(11)\n\t" \ 2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stw 3,8(1)\n\t" \ 2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 4,8(11)\n\t" \ 2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 5,12(11)\n\t" \ 2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 7,20(11)\n\t" \ 2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 8,24(11)\n\t" \ 2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 9,28(11)\n\t" \ 2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lwz 11,0(11)\n\t" /* target->r11 */ \ 2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3" \ 2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[0]) \ 2309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc32_linux */ 2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc64-linux ------------------------ */ 2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc64_linux) 2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ 2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */ 2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS \ 2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lr", "ctr", "xer", \ 2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ 2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ 2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "r11", "r12", "r13" 2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function 2330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call and restore it afterwards as gcc may not keep the stack 2331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pointer aligned if it doesn't realise calls are being made 2332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to other functions. */ 2333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK \ 2335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 28,1\n\t" \ 2336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "rldicr 1,1,0,59\n\t" 2337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK \ 2338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mr 1,28\n\t" 2339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned 2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown long) == 8. */ 2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig) \ 2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+0]; \ 2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1) \ 2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+1]; \ 2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+2]; \ 2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+3]; \ 2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+4]; \ 2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+5]; \ 2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+6]; \ 2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7) \ 2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+7]; \ 2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8) \ 2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+8]; \ 2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+8] = (unsigned long)arg8; \ 2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9) \ 2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+9]; \ 2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+8] = (unsigned long)arg8; \ 2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+9] = (unsigned long)arg9; \ 2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-128\n\t" /* expand stack frame */ \ 2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,72(11)\n\t" \ 2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,112(1)\n\t" \ 2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10) \ 2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+10]; \ 2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+8] = (unsigned long)arg8; \ 2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+9] = (unsigned long)arg9; \ 2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+10] = (unsigned long)arg10; \ 2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-128\n\t" /* expand stack frame */ \ 2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg10 */ \ 2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,80(11)\n\t" \ 2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,120(1)\n\t" \ 2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,72(11)\n\t" \ 2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,112(1)\n\t" \ 2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10,arg11) \ 2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+11]; \ 2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+8] = (unsigned long)arg8; \ 2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+9] = (unsigned long)arg9; \ 2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+10] = (unsigned long)arg10; \ 2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+11] = (unsigned long)arg11; \ 2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-144\n\t" /* expand stack frame */ \ 2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg11 */ \ 2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,88(11)\n\t" \ 2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,128(1)\n\t" \ 2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg10 */ \ 2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,80(11)\n\t" \ 2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,120(1)\n\t" \ 2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,72(11)\n\t" \ 2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,112(1)\n\t" \ 2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10,arg11,arg12) \ 2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3+12]; \ 2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* _argvec[0] holds current r2 across the call */ \ 2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)_orig.r2; \ 2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)_orig.nraddr; \ 2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+1] = (unsigned long)arg1; \ 2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+2] = (unsigned long)arg2; \ 2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+3] = (unsigned long)arg3; \ 2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+4] = (unsigned long)arg4; \ 2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+5] = (unsigned long)arg5; \ 2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+6] = (unsigned long)arg6; \ 2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+7] = (unsigned long)arg7; \ 2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+8] = (unsigned long)arg8; \ 2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+9] = (unsigned long)arg9; \ 2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+10] = (unsigned long)arg10; \ 2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+11] = (unsigned long)arg11; \ 2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2+12] = (unsigned long)arg12; \ 2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 2,-16(11)\n\t" /* save tocptr */ \ 2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "addi 1,1,-144\n\t" /* expand stack frame */ \ 2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg12 */ \ 2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,96(11)\n\t" \ 2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,136(1)\n\t" \ 2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg11 */ \ 2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,88(11)\n\t" \ 2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,128(1)\n\t" \ 2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg10 */ \ 2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,80(11)\n\t" \ 2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,120(1)\n\t" \ 2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* arg9 */ \ 2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3,72(11)\n\t" \ 2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "std 3,112(1)\n\t" \ 2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* args1-8 */ \ 2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 11, 0(11)\n\t" /* target->r11 */ \ 2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr 11,%1\n\t" \ 2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mr %0,3\n\t" \ 2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r" (&_argvec[2]) \ 2866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc64_linux */ 2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- arm-linux ------------------------- */ 2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_arm_linux) 2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */ 2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" 2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function 2881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call and restore it afterwards as gcc may not keep the stack 2882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pointer aligned if it doesn't realise calls are being made 2883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to other functions. */ 2884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is a bit tricky. We store the original stack pointer in r10 2886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng as it is callee-saves. gcc doesn't allow the use of r11 for some 2887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng reason. Also, we can't directly "bic" the stack pointer in thumb 2888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mode since r13 isn't an allowed register number in that context. 2889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng So use r4 as a temporary, since that is about to get trashed 2890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng anyway, just after each use of this macro. Side effect is we need 2891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to be very careful about any future changes, since 2892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ 2893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK \ 2894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mov r10, sp\n\t" \ 2895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mov r4, sp\n\t" \ 2896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "bic r4, r4, #7\n\t" \ 2897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mov sp, r4\n\t" 2898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK \ 2899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "mov sp, r10\n\t" 2900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned 2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown long) == 4. */ 2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig) \ 2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[1]; \ 2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 2914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0\n" \ 2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 2918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1) \ 2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[2]; \ 2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 2935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0\n" \ 2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 2939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[3]; \ 2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 2958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0\n" \ 2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 2962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[4]; \ 2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 2977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 2983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0\n" \ 2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 2987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[5]; \ 2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[6]; \ 3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sub sp, sp, #4 \n\t" \ 3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0} \n\t" \ 3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[7]; \ 3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1} \n\t" \ 3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7) \ 3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[8]; \ 3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sub sp, sp, #4 \n\t" \ 3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2} \n\t" \ 3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8) \ 3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[9]; \ 3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #32] \n\t" \ 3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2, r3} \n\t" \ 3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9) \ 3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[10]; \ 3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sub sp, sp, #4 \n\t" \ 3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #32] \n\t" \ 3178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1, #36] \n\t" \ 3179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2, r3, r4} \n\t" \ 3180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg7,arg8,arg9,arg10) \ 3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[11]; \ 3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #40] \n\t" \ 3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0} \n\t" \ 3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #32] \n\t" \ 3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1, #36] \n\t" \ 3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2, r3, r4} \n\t" \ 3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg6,arg7,arg8,arg9,arg10, \ 3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg11) \ 3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[12]; \ 3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)(arg11); \ 3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sub sp, sp, #4 \n\t" \ 3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #40] \n\t" \ 3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #44] \n\t" \ 3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1} \n\t" \ 3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #32] \n\t" \ 3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1, #36] \n\t" \ 3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2, r3, r4} \n\t" \ 3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg6,arg7,arg8,arg9,arg10, \ 3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg11,arg12) \ 3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile OrigFn _orig = (orig); \ 3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _argvec[13]; \ 3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile unsigned long _res; \ 3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[0] = (unsigned long)_orig.nraddr; \ 3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[1] = (unsigned long)(arg1); \ 3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[2] = (unsigned long)(arg2); \ 3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[3] = (unsigned long)(arg3); \ 3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[4] = (unsigned long)(arg4); \ 3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[5] = (unsigned long)(arg5); \ 3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[6] = (unsigned long)(arg6); \ 3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[7] = (unsigned long)(arg7); \ 3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[8] = (unsigned long)(arg8); \ 3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[9] = (unsigned long)(arg9); \ 3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[10] = (unsigned long)(arg10); \ 3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[11] = (unsigned long)(arg11); \ 3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _argvec[12] = (unsigned long)(arg12); \ 3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ volatile( \ 3304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_ALIGN_STACK \ 3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #40] \n\t" \ 3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #44] \n\t" \ 3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #48] \n\t" \ 3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2} \n\t" \ 3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #20] \n\t" \ 3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #24] \n\t" \ 3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #28] \n\t" \ 3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #32] \n\t" \ 3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1, #36] \n\t" \ 3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "push {r0, r1, r2, r3, r4} \n\t" \ 3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r0, [%1, #4] \n\t" \ 3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r1, [%1, #8] \n\t" \ 3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r2, [%1, #12] \n\t" \ 3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r3, [%1, #16] \n\t" \ 3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "ldr r4, [%1] \n\t" /* target->r4 */ \ 3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 3321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK \ 3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "mov %0, r0" \ 3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ "=r" (_res) \ 3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "0" (&_argvec[0]) \ 3325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ 3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lval = (__typeof__(lval)) _res; \ 3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_arm_linux */ 3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------- s390x-linux ------------------------- */ 3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(PLAT_s390x_linux) 3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Similar workaround as amd64 (see above), but we use r11 as frame 3337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pointer and save the old r11 in r7. r11 might be used for 3338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argvec, therefore we copy argvec in r1 since r1 is clobbered 3339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov after the call anyway. */ 3340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) 3341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define __FRAME_POINTER \ 3342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ,"d"(__builtin_dwarf_cfa()) 3343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VALGRIND_CFI_PROLOGUE \ 3344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ".cfi_remember_state\n\t" \ 3345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ 3346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 7,11\n\t" \ 3347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 11,%2\n\t" \ 3348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ".cfi_def_cfa r11, 0\n\t" 3349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VALGRIND_CFI_EPILOGUE \ 3350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 11, 7\n\t" \ 3351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ".cfi_restore_state\n\t" 3352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 3353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define __FRAME_POINTER 3354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VALGRIND_CFI_PROLOGUE \ 3355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr 1,%1\n\t" 3356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VALGRIND_CFI_EPILOGUE 3357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Nb: On s390 the stack pointer is properly aligned *at all times* 3360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng according to the s390 GCC maintainer. (The ABI specification is not 3361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and 3362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_RESTORE_STACK are not defined here. */ 3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* These regs are trashed by the hidden call. Note that we overwrite 3365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the 3366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov function a proper return address. All others are ABI defined call 3367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov clobbers. */ 3368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ 3369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "f0","f1","f2","f3","f4","f5","f6","f7" 3370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Nb: Although r11 is modified in the asm snippets below (inside 3372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for 3373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng two reasons: 3374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not 3375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng modified 3376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (2) GCC will complain that r11 cannot appear inside a clobber section, 3377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng when compiled with -O -fno-omit-frame-pointer 3378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 3379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_v(lval, orig) \ 3381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[1]; \ 3384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" /* target->r1 */ \ 3390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ 3396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 3397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* The call abi has the arguments in r2-r6 and stack */ 3402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_W(lval, orig, arg1) \ 3403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[2]; \ 3406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 3421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ 3426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[3]; \ 3429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 3446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ 3451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[4]; \ 3454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 3473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ 3478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[5]; \ 3481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 3502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ 3507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[6]; \ 3510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-160\n\t" \ 3520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,160\n\t" \ 3529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6) \ 3539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[7]; \ 3542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-168\n\t" \ 3553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,168\n\t" \ 3563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7) \ 3573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[8]; \ 3576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-176\n\t" \ 3588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,176\n\t" \ 3599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7 ,arg8) \ 3609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[9]; \ 3612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[8] = (unsigned long)arg8; \ 3622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-184\n\t" \ 3625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 176(8,15), 64(1)\n\t" \ 3633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,184\n\t" \ 3637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7 ,arg8, arg9) \ 3647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[10]; \ 3650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[8] = (unsigned long)arg8; \ 3660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[9] = (unsigned long)arg9; \ 3661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-192\n\t" \ 3664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 176(8,15), 64(1)\n\t" \ 3672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 184(8,15), 72(1)\n\t" \ 3673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,192\n\t" \ 3677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7 ,arg8, arg9, arg10) \ 3687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[11]; \ 3690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[8] = (unsigned long)arg8; \ 3700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[9] = (unsigned long)arg9; \ 3701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[10] = (unsigned long)arg10; \ 3702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-200\n\t" \ 3705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 176(8,15), 64(1)\n\t" \ 3713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 184(8,15), 72(1)\n\t" \ 3714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 192(8,15), 80(1)\n\t" \ 3715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,200\n\t" \ 3719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7 ,arg8, arg9, arg10, arg11) \ 3729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[12]; \ 3732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[8] = (unsigned long)arg8; \ 3742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[9] = (unsigned long)arg9; \ 3743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[10] = (unsigned long)arg10; \ 3744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[11] = (unsigned long)arg11; \ 3745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-208\n\t" \ 3748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 176(8,15), 64(1)\n\t" \ 3756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 184(8,15), 72(1)\n\t" \ 3757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 192(8,15), 80(1)\n\t" \ 3758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 200(8,15), 88(1)\n\t" \ 3759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,208\n\t" \ 3763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 3772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ 3773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do { \ 3774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile OrigFn _orig = (orig); \ 3775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _argvec[13]; \ 3776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile unsigned long _res; \ 3777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[0] = (unsigned long)_orig.nraddr; \ 3778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[1] = (unsigned long)arg1; \ 3779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[2] = (unsigned long)arg2; \ 3780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[3] = (unsigned long)arg3; \ 3781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[4] = (unsigned long)arg4; \ 3782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[5] = (unsigned long)arg5; \ 3783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[6] = (unsigned long)arg6; \ 3784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[7] = (unsigned long)arg7; \ 3785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[8] = (unsigned long)arg8; \ 3786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[9] = (unsigned long)arg9; \ 3787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[10] = (unsigned long)arg10; \ 3788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[11] = (unsigned long)arg11; \ 3789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _argvec[12] = (unsigned long)arg12; \ 3790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ volatile( \ 3791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_PROLOGUE \ 3792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,-216\n\t" \ 3793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 2, 8(1)\n\t" \ 3794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 3,16(1)\n\t" \ 3795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 4,24(1)\n\t" \ 3796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 5,32(1)\n\t" \ 3797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 6,40(1)\n\t" \ 3798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 160(8,15), 48(1)\n\t" \ 3799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 168(8,15), 56(1)\n\t" \ 3800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 176(8,15), 64(1)\n\t" \ 3801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 184(8,15), 72(1)\n\t" \ 3802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 192(8,15), 80(1)\n\t" \ 3803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 200(8,15), 88(1)\n\t" \ 3804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mvc 208(8,15), 96(1)\n\t" \ 3805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lg 1, 0(1)\n\t" \ 3806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CALL_NOREDIR_R1 \ 3807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %0, 2\n\t" \ 3808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "aghi 15,216\n\t" \ 3809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_CFI_EPILOGUE \ 3810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*out*/ "=d" (_res) \ 3811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 3812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 3813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); \ 3814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov lval = (__typeof__(lval)) _res; \ 3815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } while (0) 3816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* PLAT_s390x_linux */ 3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------- mips-linux ------------------------- */ 3821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_mips32_linux) 3823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These regs are trashed by the hidden call. */ 3825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ 3826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 3827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"$25", "$31" 3828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned 3830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng long) == 4. */ 3831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_v(lval, orig) \ 3833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[1]; \ 3836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 16 \n\t" \ 3843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 3844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 3845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 16\n\t" \ 3846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 3847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 3848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 8 \n\t" \ 3849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 3850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 3851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 3852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 3854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 3855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_W(lval, orig, arg1) \ 3858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[2]; \ 3861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 3864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 16 \n\t" \ 3869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" /* arg1*/ \ 3870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 3871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 3872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 16 \n\t" \ 3873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 3874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 3875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 8 \n\t" \ 3876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 3877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 3878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 3879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 3881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 3882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 3885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[3]; \ 3888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 3891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 3892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 16 \n\t" \ 3897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 3898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 3899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 3900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 3901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 16 \n\t" \ 3902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 3903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 3904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 8 \n\t" \ 3905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 3906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 3907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 3908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 3910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 3911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 3914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[4]; \ 3917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 3920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 3921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 3922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 16 \n\t" \ 3927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 3928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 3929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 3930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 3931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 3932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 16 \n\t" \ 3933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 3934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 3935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 8 \n\t" \ 3936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 3937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 3938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 3939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 3941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 3942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 3945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[5]; \ 3948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 3951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 3952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 3953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 3954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 16 \n\t" \ 3959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 3960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 3962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 3963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 3964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 3965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 16 \n\t" \ 3966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 3967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 3968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 8 \n\t" \ 3969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 3970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 3971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 3972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 3974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 3975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 3978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 3979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 3980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[6]; \ 3981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 3982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 3983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 3984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 3985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 3986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 3987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 3988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 3989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 3990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 3991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 3992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 3993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 24\n\t" \ 3994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 3995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 3996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 3997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 3998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 3999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $29, $29, 24 \n\t" \ 4002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 4013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[7]; \ 4016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 32\n\t" \ 4030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "nop\n\t" \ 4033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 32 \n\t" \ 4041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 4053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7) \ 4054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[8]; \ 4057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 32\n\t" \ 4072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 32 \n\t" \ 4084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 4096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8) \ 4097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[9]; \ 4100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 4110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 40\n\t" \ 4116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 32(%1) \n\t" \ 4122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 28($sp) \n\t" \ 4123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 40 \n\t" \ 4130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 4142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9) \ 4143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[10]; \ 4146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 4156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 4157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 40\n\t" \ 4163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 32(%1) \n\t" \ 4169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 28($sp) \n\t" \ 4170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 36(%1) \n\t" \ 4171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 32($sp) \n\t" \ 4172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 40 \n\t" \ 4179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 4191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg7,arg8,arg9,arg10) \ 4192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[11]; \ 4195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 4205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 4206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 4207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 48\n\t" \ 4213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 32(%1) \n\t" \ 4219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 28($sp) \n\t" \ 4220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 36(%1) \n\t" \ 4221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 32($sp) \n\t" \ 4222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 40(%1) \n\t" \ 4223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 36($sp) \n\t" \ 4224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 48 \n\t" \ 4231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 4243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg6,arg7,arg8,arg9,arg10, \ 4244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg11) \ 4245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[12]; \ 4248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 4258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 4259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 4260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[11] = (unsigned long)(arg11); \ 4261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 48\n\t" \ 4267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 32(%1) \n\t" \ 4273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 28($sp) \n\t" \ 4274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 36(%1) \n\t" \ 4275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 32($sp) \n\t" \ 4276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 40(%1) \n\t" \ 4277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 36($sp) \n\t" \ 4278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 44(%1) \n\t" \ 4279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 40($sp) \n\t" \ 4280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 48 \n\t" \ 4287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 4299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg6,arg7,arg8,arg9,arg10, \ 4300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arg11,arg12) \ 4301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { \ 4302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile OrigFn _orig = (orig); \ 4303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _argvec[13]; \ 4304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng volatile unsigned long _res; \ 4305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[0] = (unsigned long)_orig.nraddr; \ 4306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[1] = (unsigned long)(arg1); \ 4307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[2] = (unsigned long)(arg2); \ 4308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[3] = (unsigned long)(arg3); \ 4309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[4] = (unsigned long)(arg4); \ 4310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[5] = (unsigned long)(arg5); \ 4311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[6] = (unsigned long)(arg6); \ 4312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[7] = (unsigned long)(arg7); \ 4313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[8] = (unsigned long)(arg8); \ 4314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[9] = (unsigned long)(arg9); \ 4315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[10] = (unsigned long)(arg10); \ 4316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[11] = (unsigned long)(arg11); \ 4317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _argvec[12] = (unsigned long)(arg12); \ 4318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile( \ 4319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $29, $29, 8 \n\t" \ 4320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $gp, 0($sp) \n\t" \ 4321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $ra, 4($sp) \n\t" \ 4322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 20(%1) \n\t" \ 4323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "subu $sp, $sp, 56\n\t" \ 4324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 16($sp) \n\t" \ 4325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 24(%1) \n\t" \ 4326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 20($sp) \n\t" \ 4327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 28(%1) \n\t" \ 4328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 24($sp) \n\t" \ 4329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 32(%1) \n\t" \ 4330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 28($sp) \n\t" \ 4331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 36(%1) \n\t" \ 4332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 32($sp) \n\t" \ 4333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 40(%1) \n\t" \ 4334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 36($sp) \n\t" \ 4335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 44(%1) \n\t" \ 4336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 40($sp) \n\t" \ 4337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 48(%1) \n\t" \ 4338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "sw $a0, 44($sp) \n\t" \ 4339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a0, 4(%1) \n\t" \ 4340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a1, 8(%1) \n\t" \ 4341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a2, 12(%1) \n\t" \ 4342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $a3, 16(%1) \n\t" \ 4343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $t9, 0(%1) \n\t" /* target->t9 */ \ 4344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALGRIND_CALL_NOREDIR_T9 \ 4345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 56 \n\t" \ 4346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $gp, 0($sp) \n\t" \ 4347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lw $ra, 4($sp) \n\t" \ 4348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "addu $sp, $sp, 8 \n\t" \ 4349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "move %0, $v0\n" \ 4350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*out*/ "=r" (_res) \ 4351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*in*/ "0" (&_argvec[0]) \ 4352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 4353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); \ 4354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lval = (__typeof__(lval)) _res; \ 4355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 4356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_mips32_linux */ 4358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------------------------ */ 4361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ 4362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* */ 4363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------------------------ */ 4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Some request codes. There are many more of these, but most are not 4366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exposed to end-user view. These are the public ones, all of the 4367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov form 0x1000 + small_number. 4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Core ones are in the range 0x00000000--0x0000ffff. The non-public 4370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ones start at 0x2000. 4371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 4372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* These macros are used by tools -- they must be public, but don't 4374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov embed them into other programs. */ 4375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_USERREQ_TOOL_BASE(a,b) \ 4376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) 4377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_IS_TOOL_USERREQ(a, b, v) \ 4378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) 4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This enum comprises an ABI exported by Valgrind to programs 4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which use client requests. DO NOT CHANGE THE ORDER OF THESE 4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ENTRIES, NOR DELETE ANY -- add new ones at the end. */ 4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, 4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, 4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* These allow any function to be called from the simulated 4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CPU but run on the real CPU. Nb: the first arg passed to 4390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the function is always the ThreadId of the running 4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread! So CLIENT_CALL0 actually requires a 1 arg 4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function, etc. */ 4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__CLIENT_CALL0 = 0x1101, 4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__CLIENT_CALL1 = 0x1102, 4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__CLIENT_CALL2 = 0x1103, 4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__CLIENT_CALL3 = 0x1104, 4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Can be useful in regression testing suites -- eg. can 4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown send Valgrind's output to /dev/null and still count 4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown errors. */ 4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__COUNT_ERRORS = 0x1201, 4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Allows a string (gdb monitor command) to be passed to the tool 4404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Used for interaction with vgdb/gdb */ 4405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, 4406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* These are useful and can be interpreted by any tool that 4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tracks malloc() et al, by using vg_replace_malloc.c. */ 4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, 4410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, 4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__FREELIKE_BLOCK = 0x1302, 4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Memory pool support. */ 4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__CREATE_MEMPOOL = 0x1303, 4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__DESTROY_MEMPOOL = 0x1304, 4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_ALLOC = 0x1305, 4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_FREE = 0x1306, 4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_TRIM = 0x1307, 4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MOVE_MEMPOOL = 0x1308, 4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_CHANGE = 0x1309, 4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_EXISTS = 0x130a, 4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Allow printfs to valgrind log. */ 4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The first two pass the va_list argument by value, which 4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumes it is the same size as or smaller than a UWord, 4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which generally isn't the case. Hence are deprecated. 4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The second two pass the vargs by reference and so are 4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown immune to this problem. */ 4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* both :: char* fmt, va_list vargs (DEPRECATED) */ 4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF = 0x1401, 4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_BACKTRACE = 0x1402, 4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* both :: char* fmt, va_list* vargs */ 4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, 4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, 4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Stack support. */ 4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__STACK_REGISTER = 0x1501, 4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__STACK_DEREGISTER = 0x1502, 4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__STACK_CHANGE = 0x1503, 4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Wine support */ 4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, 4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Querying of debug info. */ 4444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, 4445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Disable/enable error reporting level. Takes a single 4447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Word arg which is the delta to this thread's error 4448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov disablement indicator. Hence 1 disables or further 4449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov disables errors, and -1 moves back towards enablement. 4450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Other values are not allowed. */ 4451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801 4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Vg_ClientRequest; 4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if !defined(__GNUC__) 4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define __extension__ /* */ 4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the number of Valgrinds this code is running under. That 4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is, 0 if running natively, 1 if running under Valgrind, 2 if 4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown running under Valgrind which is running under another Valgrind, 4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown etc. */ 4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RUNNING_ON_VALGRIND \ 4464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ 4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__RUNNING_ON_VALGRIND, \ 4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, 0, 0, 0, 0) \ 4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + 4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _qzz_len - 1]. Useful if you are debugging a JITter or some such, 4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since it provides a way to make sure valgrind will retranslate the 4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidated area. Returns no value. */ 4473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ 4474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ 4475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qzz_addr, _qzz_len, 0, 0, 0) 4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These requests are for getting Valgrind itself to print something. 4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Possibly with a backtrace. This is a really ugly hack. The return value 4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is the number of characters printed, excluding the "**<pid>** " part at the 4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start and the backtrace (if present). */ 4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) 4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Modern GCC will optimize the static routine out if unused, 4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and unused attribute will shut down warnings about it. */ 4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int VALGRIND_PRINTF(const char *format, ...) 4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __attribute__((format(__printf__, 1, 2), __unused__)); 4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int 4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER) 4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__inline 4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVALGRIND_PRINTF(const char *format, ...) 4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(NVALGRIND) 4496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 4497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else /* NVALGRIND */ 4498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(_MSC_VER) 4499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uintptr_t _qzz_res; 4500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long _qzz_res; 4502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER) 4506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_VALIST_BY_REF, 4508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (uintptr_t)format, 4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (uintptr_t)&vargs, 4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, 0, 0); 4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 4512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_VALIST_BY_REF, 4514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (unsigned long)format, 4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (unsigned long)&vargs, 4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, 0, 0); 4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (int)_qzz_res; 4520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* NVALGRIND */ 4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) 4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) 4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __attribute__((format(__printf__, 1, 2), __unused__)); 4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int 4528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER) 4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__inline 4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVALGRIND_PRINTF_BACKTRACE(const char *format, ...) 4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(NVALGRIND) 4534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 4535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else /* NVALGRIND */ 4536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(_MSC_VER) 4537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uintptr_t _qzz_res; 4538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 4539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long _qzz_res; 4540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 4541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 4542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 4543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER) 4544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, 4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (uintptr_t)format, 4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (uintptr_t)&vargs, 4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, 0, 0); 4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 4550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, 4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (unsigned long)format, 4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (unsigned long)&vargs, 4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, 0, 0); 4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (int)_qzz_res; 45589bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root#endif /* NVALGRIND */ 4559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 45609bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root 4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These requests allow control to move from the simulated CPU to the 4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown real CPU, calling an arbitary function. 4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that the current ThreadId is inserted as the first argument. 4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown So this call: 4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) 4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown requires f to have this signature: 4571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word f(Word tid, Word arg1, Word arg2) 4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown where "Word" is a word-sized type. 4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that these client requests are not entirely reliable. For example, 4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if you call a function with them that subsequently calls printf(), 4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there's a high chance Valgrind will crash. Generally, your prospects of 4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown these working are made higher if the called function does not refer to 4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any global variables, and does not refer to any libc or other functions 4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (printf et al). Any kind of entanglement with libc or dynamic linking is 4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown likely to have a bad outcome, for tricky reasons which we've grappled 4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with a lot in the past. 4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ 4586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 4587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__CLIENT_CALL0, \ 4588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_fn, \ 4589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0, 0, 0, 0) 4590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ 4592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 4593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__CLIENT_CALL1, \ 4594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_fn, \ 4595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_arg1, 0, 0, 0) 4596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ 4598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 4599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__CLIENT_CALL2, \ 4600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_fn, \ 4601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_arg1, _qyy_arg2, 0, 0) 4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ 4604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 4605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_USERREQ__CLIENT_CALL3, \ 4606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_fn, \ 4607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_arg1, _qyy_arg2, \ 4608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _qyy_arg3, 0) 4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Counts the number of errors that have been recorded by a tool. Nb: 4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the tool must record the errors with VG_(maybe_record_error)() or 4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(unique_error)() for them to be counted. */ 4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_COUNT_ERRORS \ 4615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 4616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0 /* default return */, \ 4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__COUNT_ERRORS, \ 4618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0, 0, 0, 0, 0) 4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing 4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when heap blocks are allocated in order to give accurate results. This 4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown happens automatically for the standard allocator functions such as 4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, 4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete[], etc. 4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown But if your program uses a custom allocator, this doesn't automatically 4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown happen, and Valgrind will not do as well. For example, if you allocate 4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown superblocks with mmap() and then allocates chunks of the superblocks, all 4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Valgrind's observations will be at the mmap() level and it won't know that 4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the chunks should be considered separate entities. In Memcheck's case, 4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that means you probably won't get heap block overrun detection (because 4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there won't be redzones marked as unaddressable) and you definitely won't 4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get any leak detection. 4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The following client requests allow a custom allocator to be annotated so 4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that it can be handled accurately by Valgrind. 4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated 4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by a malloc()-like function. For Memcheck (an illustrative case), this 4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does two things: 4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - It records that the block has been allocated. This means any addresses 4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown within the block mentioned in error messages will be 4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identified as belonging to the block. It also means that if the block 4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isn't freed it will be detected by the leak checker. 4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - It marks the block as being addressable and undefined (if 'is_zeroed' is 4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not set), or addressable and defined (if 'is_zeroed' is set). This 4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown controls how accesses to the block by the program are handled. 4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'addr' is the start of the usable block (ie. after any 4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator 4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown can apply redzones -- these are blocks of padding at the start and end of 4654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each block. Adding redzones is recommended as it makes it much more likely 4655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Valgrind will spot block overruns. `is_zeroed' indicates if the memory is 4656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zeroed (or filled with another predictable value), as is the case for 4657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown calloc(). 4658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a 4660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown heap block -- that will be used by the client program -- is allocated. 4661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It's best to put it at the outermost level of the allocator if possible; 4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for example, if you have a function my_alloc() which calls 4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown internal_alloc(), and the client request is put inside internal_alloc(), 4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack traces relating to the heap block will contain entries for both 4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my_alloc() and internal_alloc(), which is probably not what you want. 4666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out 4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown custom blocks from within a heap block, B, that has been allocated with 4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malloc/calloc/new/etc, then block B will be *ignored* during leak-checking 4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -- the custom blocks will take precedence. 4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For 4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memcheck, it does two things: 4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - It records that the block has been deallocated. This assumes that the 4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block was annotated as having been allocated via 4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. 4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - It marks the block as being unaddressable. 4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a 4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown heap block is deallocated. 4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For 4685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Memcheck, it does four things: 4686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov - It records that the size of a block has been changed. This assumes that 4688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the block was annotated as having been allocated via 4689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. 4690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov - If the block shrunk, it marks the freed memory as being unaddressable. 4692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov - If the block grew, it marks the new area as undefined and defines a red 4694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov zone past the end of the new block. 4695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov - The V-bits of the overlap between the old and the new block are preserved. 4697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block 4699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and before deallocation of the old block. 4700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov In many cases, these three client requests will not be enough to get your 4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allocator working well with Memcheck. More specifically, if your allocator 4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call 4704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown will be necessary to mark the memory as addressable just before the zeroing 4705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown occurs, otherwise you'll get a lot of invalid write errors. For example, 4706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown you'll need to do this if your allocator recycles freed blocks, but it 4707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). 4708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Alternatively, if your allocator reuses freed blocks for allocator-internal 4709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. 4710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Really, what's happening is a blurring of the lines between the client 4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the 4713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memory should be considered unaddressable to the client program, but the 4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allocator knows more than the rest of the client program and so may be able 4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to safely access it. Extra client requests are necessary for Valgrind to 4716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown understand the distinction between the allocator and the rest of the 4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown program. 4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ignored if addr == 0. 4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ 4722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ 4723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr, sizeB, rzB, is_zeroed, 0) 47248f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov 47258f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. 47268f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov Ignored if addr == 0. 47278f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov*/ 4728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ 4729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ 4730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr, oldSizeB, newSizeB, rzB, 0) 4731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. 4733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Ignored if addr == 0. 4734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 4735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ 4736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ 4737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr, rzB, 0, 0, 0) 4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create a memory pool. */ 4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ 4741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ 4742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, rzB, is_zeroed, 0, 0) 4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Destroy a memory pool. */ 4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_DESTROY_MEMPOOL(pool) \ 4746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ 4747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, 0, 0, 0, 0) 4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Associate a piece of memory with a memory pool. */ 4750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ 4751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ 4752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, addr, size, 0, 0) 4753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Disassociate a piece of memory from a memory pool. */ 4755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_FREE(pool, addr) \ 4756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ 4757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, addr, 0, 0, 0) 4758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Disassociate any pieces outside a particular range. */ 4760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ 4761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ 4762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, addr, size, 0, 0) 4763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Resize and/or move a piece associated with a memory pool. */ 4765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ 4766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ 4767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov poolA, poolB, 0, 0, 0) 4768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Resize and/or move a piece associated with a memory pool. */ 4770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ 4771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ 4772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, addrA, addrB, size, 0) 4773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return 1 if a mempool exists, else 0. */ 4775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_EXISTS(pool) \ 4776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MEMPOOL_EXISTS, \ 4778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pool, 0, 0, 0, 0) 4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Mark a piece of memory as being a stack. Returns a stack id. */ 4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_REGISTER(start, end) \ 4782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__STACK_REGISTER, \ 4784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov start, end, 0, 0, 0) 4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Unmark the piece of memory associated with a stack id as being a 4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack. */ 4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_DEREGISTER(id) \ 4789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ 4790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov id, 0, 0, 0, 0) 4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Change the start and end address of the stack id. */ 4793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_CHANGE(id, start, end) \ 4794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ 4795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov id, start, end, 0, 0) 4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Load PDB debug info for Wine PE image_map. */ 4798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ 4799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ 4800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fd, ptr, total_size, delta, 0) 4801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Map a code address to a source file name and line number. buf64 4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown must point to a 64-byte buffer in the caller's address space. The 4804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result will be dumped in there and is guaranteed to be zero 4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown terminated. If no info is found, the first byte is set to zero. */ 4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ 4807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 4808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_USERREQ__MAP_IP_TO_SRCLOC, \ 4809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr, buf64, 0, 0, 0) 4810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Disable error reporting for this thread. Behaves in a stack like 4812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov way, so you can safely call this multiple times provided that 4813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times 4814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to re-enable reporting. The first call of this macro disables 4815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov reporting. Subsequent calls have no effect except to increase the 4816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable 4817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov reporting. Child threads do not inherit this setting from their 4818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov parents -- they are always created with reporting enabled. */ 4819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DISABLE_ERROR_REPORTING \ 4820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ 4821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1, 0, 0, 0, 0) 4822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Re-enable error reporting, as per comments on 4824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DISABLE_ERROR_REPORTING. */ 4825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_ENABLE_ERROR_REPORTING \ 4826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ 4827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov -1, 0, 0, 0, 0) 4828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_x86_darwin 4830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_amd64_darwin 4831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_x86_win32 4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_x86_linux 4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_amd64_linux 4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc32_linux 4835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc64_linux 4836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_arm_linux 4837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_s390x_linux 4838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef PLAT_mips32_linux 4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* __VALGRIND_H */ 4841