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