1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* -*- c -*- 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ---------------------------------------------------------------- 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Notice that the following BSD-style license applies to this one 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block file (valgrind.h) only. The rest of Valgrind is licensed under the 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block terms of the GNU General Public License, version 2, unless 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block otherwise indicated. See the COPYING file in the source 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block distribution for details. 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ---------------------------------------------------------------- 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block This file is part of Valgrind, a dynamic binary instrumentation 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block framework. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Copyright (C) 2000-2010 Julian Seward. All rights reserved. 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Redistribution and use in source and binary forms, with or without 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block modification, are permitted provided that the following conditions 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block are met: 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1. Redistributions of source code must retain the above copyright 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notice, this list of conditions and the following disclaimer. 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2. The origin of this software must not be misrepresented; you must 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not claim that you wrote the original software. If you use this 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block software in a product, an acknowledgment in the product 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block documentation would be appreciated but is not required. 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3. Altered source versions must be plainly marked as such, and must 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not be misrepresented as being the original software. 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4. The name of the author may not be used to endorse or promote 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block products derived from this software without specific prior written 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block permission. 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ---------------------------------------------------------------- 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Notice that the above BSD-style license applies to this one file 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (valgrind.h) only. The entire rest of Valgrind is licensed under 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block the terms of the GNU General Public License, version 2. See the 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block COPYING file in the source distribution for details. 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ---------------------------------------------------------------- 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* This file is for inclusion into client (your!) code. 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block You can use these macros to manipulate and query Valgrind's 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block execution inside your own programs. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block The resulting executables will still run without Valgrind, just a 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block little bit more slowly than they otherwise would, but otherwise 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unchanged. When not running on valgrind, each client request 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block consumes very few (eg. 7) instructions, so the resulting performance 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block loss is negligible unless you plan to execute client requests 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block millions of times per second. Nevertheless, if that is still a 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block problem, you can compile with the NVALGRIND symbol defined (gcc 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block -DNVALGRIND) so that client requests are not even compiled in. */ 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef __VALGRIND_H 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __VALGRIND_H 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------------------------------------------------ */ 783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* VERSION NUMBER OF VALGRIND */ 793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------------------------------------------------ */ 803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Specify Valgrind's version number, so that user code can 823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch conditionally compile based on our version number. Note that these 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch were introduced at version 3.6 and so do not exist in version 3.5 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch or earlier. The recommended way to use them to check for "version 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch X.Y or later" is (eg) 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ 883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch && (__VALGRIND_MAJOR__ > 3 \ 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __VALGRIND_MAJOR__ 3 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __VALGRIND_MINOR__ 6 933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdarg.h> 96d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include <stdint.h> 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Nb: this file might be included in a file compiled with -ansi. So 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block we can't use C++ style "//" comments nor the "asm" keyword (instead 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block use "__asm__"). */ 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Derive some tags indicating what the target platform is. Note 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block that in this file we're using the compiler's CPP symbols for 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block identifying architectures, which are different to the ones we use 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block within the rest of Valgrind. Note, __powerpc__ is active for both 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32 and 64-bit PPC, whereas __powerpc64__ is only active for the 1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch latter (on Linux, that is). 1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Misc note: how to find out what's predefined in gcc by default: 1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch gcc -Wp,-dM somefile.c 1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_x86_darwin 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_amd64_darwin 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_x86_win32 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_x86_linux 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_amd64_linux 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_ppc32_linux 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_ppc64_linux 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_arm_linux 1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_s390x_linux 1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__APPLE__) && defined(__i386__) 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define PLAT_x86_darwin 1 1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__APPLE__) && defined(__x86_64__) 1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define PLAT_amd64_darwin 1 1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__MINGW32__) || defined(__CYGWIN32__) \ 1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch || (defined(_WIN32) && defined(_M_IX86)) 1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define PLAT_x86_win32 1 1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__i386__) 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define PLAT_x86_linux 1 1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__x86_64__) 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define PLAT_amd64_linux 1 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define PLAT_ppc32_linux 1 1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define PLAT_ppc64_linux 1 1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__arm__) 1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define PLAT_arm_linux 1 1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define PLAT_s390x_linux 1 1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* If we're not compiling for our target platform, don't generate 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block any inline asms. */ 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# if !defined(NVALGRIND) 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define NVALGRIND 1 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# endif 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* in here of use to end-users -- skip to the next section. */ 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* 1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client 1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * request. Accepts both pointers and integers as arguments. 1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * 1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind 1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * client request and whose value equals the client request result. Accepts 1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * both pointers and integers as arguments. 1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch */ 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_request, _zzq_arg1, _zzq_arg2, \ 1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 1683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ 1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ 1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } 1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if defined(NVALGRIND) 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Define NVALGRIND to completely remove the Valgrind magic sequence 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block from the compiled code (analogous to NDEBUG's effects on 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assert()) */ 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (_zzq_default) 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else /* ! NVALGRIND */ 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* The following defines the magic code sequences which the JITter 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spots and handles magically. Don't look too closely at them as 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block they will rot your brain. 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block The assembly code sequences for all architectures is in this one 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block file. This is because this file must be stand-alone, and we don't 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block want to have multiple files. 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value gets put in the return slot, so that everything works when 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this is executed not under Valgrind. Args are passed in a memory 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block block, and so there's no intrinsic limit to the number that could 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block be passed, but it's currently five. 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block The macro args are: 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_rlval result lvalue 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_default default value (result returned when running on real CPU) 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_request request code 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1..5 request params 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block The other two macros are used to support function wrapping, and are 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block guest's NRADDR pseudo-register and whatever other information is 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block needed to safely run the call original from the wrapper: on 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ppc64-linux, the R2 value at the divert point is also needed. This 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block information is abstracted into a user-visible type, OrigFn. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_* behaves the same as the following on the 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block guest, but guarantees that the branch instruction will not be 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block complete inline asm, since it needs to be combined with more magic 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline asm stuff to be useful. 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- x86-{linux,darwin} ---------------- */ 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ 2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch || (defined(PLAT_x86_win32) && defined(__GNUC__)) 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct { 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int nraddr; /* where's the code? */ 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OrigFn; 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __SPECIAL_INSTRUCTION_PREAMBLE \ 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "roll $3, %%edi ; roll $13, %%edi\n\t" \ 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "roll $29, %%edi ; roll $19, %%edi\n\t" 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({volatile unsigned int _zzq_args[6]; \ 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned int _zzq_result; \ 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[0] = (unsigned int)(_zzq_request); \ 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %EDX = client_request ( %EAX ) */ \ 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgl %%ebx,%%ebx" \ 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=d" (_zzq_result) \ 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned int __addr; \ 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %EAX = guest_NRADDR */ \ 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgl %%ecx,%%ecx" \ 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=a" (__addr) \ 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->nraddr = __addr; \ 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_CALL_NOREDIR_EAX \ 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* call-noredir *%EAX */ \ 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgl %%edx,%%edx\n\t" 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- x86-Win32 ------------------------- */ 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_x86_win32) && !defined(__GNUC__) 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtypedef 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch struct { 2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned int nraddr; /* where's the code? */ 2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OrigFn; 2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __SPECIAL_INSTRUCTION_PREAMBLE \ 2883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm rol edi, 3 __asm rol edi, 13 \ 2893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm rol edi, 29 __asm rol edi, 19 2903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 2923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 2933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ 2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ 2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ 2973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) 2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstatic __inline uintptr_t 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvalgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, 3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, 3033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t _zzq_arg5) 3043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch{ 3053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile uintptr_t _zzq_args[6]; 3063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned int _zzq_result; 3073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[0] = (uintptr_t)(_zzq_request); 3083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[1] = (uintptr_t)(_zzq_arg1); 3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[2] = (uintptr_t)(_zzq_arg2); 3103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[3] = (uintptr_t)(_zzq_arg3); 3113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[4] = (uintptr_t)(_zzq_arg4); 3123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[5] = (uintptr_t)(_zzq_arg5); 3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default 3143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __SPECIAL_INSTRUCTION_PREAMBLE 3153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* %EDX = client_request ( %EAX ) */ 3163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm xchg ebx,ebx 3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm mov _zzq_result, edx 3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return _zzq_result; 3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned int __addr; \ 3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ 3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* %EAX = guest_NRADDR */ \ 3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm xchg ecx,ecx \ 3283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm mov __addr, eax \ 3293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } \ 3303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_orig->nraddr = __addr; \ 3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_CALL_NOREDIR_EAX ERROR 3343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 3363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#error Unsupported compiler. 3373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_x86_win32 */ 3403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------ amd64-{linux,darwin} --------------- */ 3423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct { 347d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t nraddr; /* where's the code? */ 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OrigFn; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __SPECIAL_INSTRUCTION_PREAMBLE \ 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 3583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({ volatile uint64_t _zzq_args[6]; \ 360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block volatile uint64_t _zzq_result; \ 361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[0] = (uint64_t)(_zzq_request); \ 362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[1] = (uint64_t)(_zzq_arg1); \ 363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[2] = (uint64_t)(_zzq_arg2); \ 364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[3] = (uint64_t)(_zzq_arg3); \ 365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[4] = (uint64_t)(_zzq_arg4); \ 366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[5] = (uint64_t)(_zzq_arg5); \ 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %RDX = client_request ( %RAX ) */ \ 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgq %%rbx,%%rbx" \ 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=d" (_zzq_result) \ 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 3743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block volatile uint64_t __addr; \ 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %RAX = guest_NRADDR */ \ 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgq %%rcx,%%rcx" \ 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=a" (__addr) \ 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->nraddr = __addr; \ 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_CALL_NOREDIR_RAX \ 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* call-noredir *%RAX */ \ 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "xchgq %%rdx,%%rdx\n\t" 3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------ ppc32-linux ------------------------ */ 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if defined(PLAT_ppc32_linux) 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct { 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int nraddr; /* where's the code? */ 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OrigFn; 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __SPECIAL_INSTRUCTION_PREAMBLE \ 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block \ 4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({ unsigned int _zzq_args[6]; \ 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int _zzq_result; \ 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int* _zzq_ptr; \ 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[0] = (unsigned int)(_zzq_request); \ 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_ptr = _zzq_args; \ 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile("mr 3,%1\n\t" /*default*/ \ 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 4,%2\n\t" /*ptr*/ \ 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %R3 = client_request ( %R4 ) */ \ 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 1,1,1\n\t" \ 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" /*result*/ \ 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=b" (_zzq_result) \ 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "b" (_zzq_default), "b" (_zzq_ptr) \ 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory", "r3", "r4"); \ 4343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 4353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int __addr; \ 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %R3 = guest_NRADDR */ \ 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 2,2,2\n\t" \ 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=b" (__addr) \ 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory", "r3" \ 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->nraddr = __addr; \ 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* branch-and-link-to-noredir *%R11 */ \ 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 3,3,3\n\t" 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* PLAT_ppc32_linux */ 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------ ppc64-linux ------------------------ */ 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if defined(PLAT_ppc64_linux) 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct { 463d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t nraddr; /* where's the code? */ 464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t r2; /* what tocptr do we need? */ 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OrigFn; 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __SPECIAL_INSTRUCTION_PREAMBLE \ 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rotldi 0,0,61 ; rotldi 0,0,51\n\t" 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block \ 4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({ uint64_t _zzq_args[6]; \ 478d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block register uint64_t _zzq_result __asm__("r3"); \ 479d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block register uint64_t* _zzq_ptr __asm__("r4"); \ 480d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[0] = (uint64_t)(_zzq_request); \ 481d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[1] = (uint64_t)(_zzq_arg1); \ 482d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[2] = (uint64_t)(_zzq_arg2); \ 483d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[3] = (uint64_t)(_zzq_arg3); \ 484d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[4] = (uint64_t)(_zzq_arg4); \ 485d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block _zzq_args[5] = (uint64_t)(_zzq_arg5); \ 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_ptr = _zzq_args; \ 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %R3 = client_request ( %R4 ) */ \ 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 1,1,1" \ 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=r" (_zzq_result) \ 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "0" (_zzq_default), "r" (_zzq_ptr) \ 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory"); \ 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 498d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block register uint64_t __addr __asm__("r3"); \ 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %R3 = guest_NRADDR */ \ 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 2,2,2" \ 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=r" (__addr) \ 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->nraddr = __addr; \ 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* %R3 = guest_NRADDR_GPR2 */ \ 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 4,4,4" \ 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "=r" (__addr) \ 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : "cc", "memory" \ 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->r2 = __addr; \ 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* branch-and-link-to-noredir *%R11 */ \ 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "or 3,3,3\n\t" 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* PLAT_ppc64_linux */ 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- arm-linux ------------------------- */ 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_arm_linux) 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct { 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int nraddr; /* where's the code? */ 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OrigFn; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __SPECIAL_INSTRUCTION_PREAMBLE \ 5353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ 5363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 5393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block \ 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({volatile unsigned int _zzq_args[6]; \ 5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned int _zzq_result; \ 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[0] = (unsigned int)(_zzq_request); \ 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[1] = (unsigned int)(_zzq_arg1); \ 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[2] = (unsigned int)(_zzq_arg2); \ 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[3] = (unsigned int)(_zzq_arg3); \ 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[4] = (unsigned int)(_zzq_arg4); \ 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_args[5] = (unsigned int)(_zzq_arg5); \ 5513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile("mov r3, %1\n\t" /*default*/ \ 5523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov r4, %2\n\t" /*ptr*/ \ 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 5543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* R3 = client_request ( R4 ) */ \ 5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "orr r10, r10, r10\n\t" \ 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r3" /*result*/ \ 5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "=r" (_zzq_result) \ 5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "r" (_zzq_default), "r" (&_zzq_args[0]) \ 5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "cc","memory", "r3", "r4"); \ 5603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned int __addr; \ 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* R3 = guest_NRADDR */ \ 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "orr r11, r11, r11\n\t" \ 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r3" \ 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "=r" (__addr) \ 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : \ 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "cc", "memory", "r3" \ 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _zzq_orig->nraddr = __addr; \ 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __SPECIAL_INSTRUCTION_PREAMBLE \ 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* branch-and-link-to-noredir *%R4 */ \ 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "orr r12, r12, r12\n\t" 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_arm_linux */ 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------ s390x-linux ------------------------ */ 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_s390x_linux) 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch struct { 5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t nraddr; /* where's the code? */ 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OrigFn; 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific 5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * code. This detection is implemented in platform specific toIR.c 5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch * (e.g. VEX/priv/guest_s390_decoder.c). 5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch */ 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __SPECIAL_INSTRUCTION_PREAMBLE \ 5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lr 15,15\n\t" \ 6003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lr 1,1\n\t" \ 6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lr 2,2\n\t" \ 6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lr 3,3\n\t" 6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" 6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" 6073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_default, _zzq_request, \ 6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __extension__ \ 6123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ({volatile uint64_t _zzq_args[6]; \ 6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile uint64_t _zzq_result; \ 6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[0] = (uint64_t)(_zzq_request); \ 6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[1] = (uint64_t)(_zzq_arg1); \ 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[2] = (uint64_t)(_zzq_arg2); \ 6173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[3] = (uint64_t)(_zzq_arg3); \ 6183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[4] = (uint64_t)(_zzq_arg4); \ 6193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_args[5] = (uint64_t)(_zzq_arg5); \ 6203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile(/* r2 = args */ \ 6213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 2,%1\n\t" \ 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* r3 = default */ \ 6233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 3,%2\n\t" \ 6243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __SPECIAL_INSTRUCTION_PREAMBLE \ 6253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __CLIENT_REQUEST_CODE \ 6263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* results = r3 */ \ 6273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 3\n\t" \ 6283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "=d" (_zzq_result) \ 6293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "a" (&_zzq_args[0]), "0" (_zzq_default) \ 6303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "cc", "2", "3", "memory" \ 6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 6323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_result; \ 6333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }) 6343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ 6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ 6373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile uint64_t __addr; \ 6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ 6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __GET_NR_CONTEXT_CODE \ 6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 3\n\t" \ 6413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "=a" (__addr) \ 6423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : \ 6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : "cc", "3", "memory" \ 6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _zzq_orig->nraddr = __addr; \ 6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_CALL_NOREDIR_R1 \ 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __SPECIAL_INSTRUCTION_PREAMBLE \ 6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __CALL_NO_REDIR_CODE 6513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_s390x_linux */ 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Insert assembly code for other platforms here... */ 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* NVALGRIND */ 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ugly. It's the least-worst tradeoff I can think of. */ 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* This section defines magic (a.k.a appalling-hack) macros for doing 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block guaranteed-no-redirection macros, so as to get from function 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block wrappers to the functions they are wrapping. The whole point is to 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block construct standard call sequences, but to do the call itself with a 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block special no-redirect call pseudo-instruction that the JIT 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block understands and handles specially. This section is long and 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block repetitious, and I can't see a way to make it shorter. 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block The naming scheme is as follows: 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'W' stands for "word" and 'v' for "void". Hence there are 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block different macros for calling arity 0, 1, 2, 3, 4, etc, functions, 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block and for each, the possibility of returning a word-typed result, or 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no result. 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Use these to write the name of your wrapper. NOTE: duplicates 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Use an extra level of macroisation so as to ensure the soname/fnname 6863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch args are fully macro-expanded before pasting them together. */ 6873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd 6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ 6903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_CONCAT4(_vgwZU_,soname,_,fnname) 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ 6933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_CONCAT4(_vgwZZ_,soname,_,fnname) 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Use this macro from within a wrapper function to collect the 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context (address and possibly other info) of the original function. 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Once you have that you can then use it in one of the CALL_FN_ 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block macros. The type of the argument _lval is OrigFn. */ 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Derivatives of the main macros below, for calling functions 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block returning void. */ 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_v_v(fnptr) \ 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { volatile unsigned long _junk; \ 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_FN_W_v(_junk,fnptr); } while (0) 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_v_W(fnptr, arg1) \ 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { volatile unsigned long _junk; \ 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_FN_W_W(_junk,fnptr,arg1); } while (0) 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_v_WW(fnptr, arg1,arg2) \ 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { volatile unsigned long _junk; \ 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { volatile unsigned long _junk; \ 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { volatile unsigned long _junk; \ 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) 7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ 7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { volatile unsigned long _junk; \ 7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { volatile unsigned long _junk; \ 7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) 7313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ 7333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { volatile unsigned long _junk; \ 7343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) 7353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- x86-{linux,darwin} ---------------- */ 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These regs are trashed by the hidden call. No need to mention eax 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block as gcc can already see that, plus causes gcc to bomb. */ 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long) == 4. */ 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_v(lval, orig) \ 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[1]; \ 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_W(lval, orig, arg1) \ 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[2]; \ 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 7713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $12, %%esp\n\t" \ 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 7753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $16, %%esp\n" \ 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3]; \ 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 7923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $8, %%esp\n\t" \ 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 7973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $16, %%esp\n" \ 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[4]; \ 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 8153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $4, %%esp\n\t" \ 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 8213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $16, %%esp\n" \ 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[5]; \ 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addl $16, %%esp\n" \ 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[6]; \ 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $12, %%esp\n\t" \ 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 8743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $32, %%esp\n" \ 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[7]; \ 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 8953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $8, %%esp\n\t" \ 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 9043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $32, %%esp\n" \ 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7) \ 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[8]; \ 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 9273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $4, %%esp\n\t" \ 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 9373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $32, %%esp\n" \ 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8) \ 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[9]; \ 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 32(%%eax)\n\t" \ 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addl $32, %%esp\n" \ 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9) \ 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[10]; \ 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 9963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $12, %%esp\n\t" \ 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 36(%%eax)\n\t" \ 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 32(%%eax)\n\t" \ 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 10083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $48, %%esp\n" \ 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10) \ 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[11]; \ 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 10343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $8, %%esp\n\t" \ 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 40(%%eax)\n\t" \ 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 36(%%eax)\n\t" \ 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 32(%%eax)\n\t" \ 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 10473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $48, %%esp\n" \ 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg6,arg7,arg8,arg9,arg10, \ 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg11) \ 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[12]; \ 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)(arg11); \ 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subl $4, %%esp\n\t" \ 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 44(%%eax)\n\t" \ 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 40(%%eax)\n\t" \ 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 36(%%eax)\n\t" \ 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 32(%%eax)\n\t" \ 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 10893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addl $48, %%esp\n" \ 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg6,arg7,arg8,arg9,arg10, \ 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg11,arg12) \ 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[13]; \ 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)(arg11); \ 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[12] = (unsigned long)(arg12); \ 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 48(%%eax)\n\t" \ 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 44(%%eax)\n\t" \ 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 40(%%eax)\n\t" \ 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 36(%%eax)\n\t" \ 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 32(%%eax)\n\t" \ 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 28(%%eax)\n\t" \ 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 24(%%eax)\n\t" \ 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 20(%%eax)\n\t" \ 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 16(%%eax)\n\t" \ 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 12(%%eax)\n\t" \ 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 8(%%eax)\n\t" \ 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushl 4(%%eax)\n\t" \ 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movl (%%eax), %%eax\n\t" /* target->%eax */ \ 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_EAX \ 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addl $48, %%esp\n" \ 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "a" (&_argvec[0]) \ 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_x86_linux || PLAT_x86_darwin */ 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------ amd64-{linux,darwin} --------------- */ 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These regs are trashed by the hidden call. */ 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "rdi", "r8", "r9", "r10", "r11" 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* This is all pretty complex. It's so as to make stack unwinding 11533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch work reliably. See bug 243270. The basic problem is the sub and 11543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch add of 128 of %rsp in all of the following macros. If gcc believes 11553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch the CFA is in %rsp, then unwinding may fail, because what's at the 11563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CFA is not what gcc "expected" when it constructs the CFIs for the 11573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch places where the macros are instantiated. 11583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch But we can't just add a CFI annotation to increase the CFA offset 11603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch by 128, to match the sub of 128 from %rsp, because we don't know 11613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch whether gcc has chosen %rsp as the CFA at that point, or whether it 11623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch has chosen some other register (eg, %rbp). In the latter case, 11633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch adding a CFI annotation to change the CFA offset is simply wrong. 11643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch So the solution is to get hold of the CFA using 11663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __builtin_dwarf_cfa(), put it in a known register, and add a 11673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CFI annotation to say what the register is. We choose %rbp for 11683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch this (perhaps perversely), because: 11693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (1) %rbp is already subject to unwinding. If a new register was 11713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch chosen then the unwinder would have to unwind it in all stack 11723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch traces, which is expensive, and 11733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (2) %rbp is already subject to precise exception updates in the 11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JIT. If a new register was chosen, we'd have to have precise 11763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exceptions for it too, which reduces performance of the 11773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch generated code. 11783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch However .. one extra complication. We can't just whack the result 11803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch of __builtin_dwarf_cfa() into %rbp and then add %rbp to the 11813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch list of trashed registers at the end of the inline assembly 11823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fragments; gcc won't allow %rbp to appear in that list. Hence 11833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch instead we need to stash %rbp in %r15 for the duration of the asm, 11843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch and say that %r15 is trashed instead. gcc seems happy to go with 11853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch that. 11863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Oh .. and this all needs to be conditionalised so that it is 11883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unchanged from before this commit, when compiled with older gccs 11893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch that don't support __builtin_dwarf_cfa. Furthermore, since 11903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch this header file is freestanding, it has to be independent of 11913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch config.h, and so the following conditionalisation cannot depend on 11923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch configure time checks. 11933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Although it's not clear from 11953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', 11963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch this expression excludes Darwin. 11973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch .cfi directives in Darwin assembly appear to be completely 11983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch different and I haven't investigated how they work. 11993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch For even more entertainment value, note we have to use the 12013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch completely undocumented __builtin_dwarf_cfa(), which appears to 12023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch really compute the CFA, whereas __builtin_frame_address(0) claims 12033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch to but actually doesn't. See 12043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch https://bugs.kde.org/show_bug.cgi?id=243270#c47 12053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 12063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) 12073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define __FRAME_POINTER \ 12083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ,"r"(__builtin_dwarf_cfa()) 12093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_PROLOGUE \ 12103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "movq %%rbp, %%r15\n\t" \ 12113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "movq %2, %%rbp\n\t" \ 12123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_remember_state\n\t" \ 12133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_def_cfa rbp, 0\n\t" 12143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_EPILOGUE \ 12153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "movq %%r15, %%rbp\n\t" \ 12163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_restore_state\n\t" 12173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 12183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define __FRAME_POINTER 12193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_PROLOGUE 12203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_EPILOGUE 12213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 12223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long) == 8. */ 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block macros. In order not to trash the stack redzone, we need to drop 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %rsp by 128 before the hidden call, and restore afterwards. The 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nastyness is that it is only by luck that the stack still appears 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block to be unwindable during the hidden call - since then the behaviour 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block of any routine using this macro does not match what the CFI data 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block says. Sigh. 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Why is this important? Imagine that a wrapper has a stack 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block allocated local, and passes to the hidden call, a pointer to it. 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Because gcc does not know about the hidden call, it may allocate 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block that local in the redzone. Unfortunately the hidden call may then 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block trash it before it comes to use it. So we must step clear of the 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block redzone, for the duration of the hidden call, to make it safe. 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Probably the same problem afflicts the other redzone-style ABIs too 12433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (ppc64-linux); but for those, the stack is 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self describing (none of this CFI nonsense) so at least messing 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block with the stack pointer doesn't give a danger of non-unwindable 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack. */ 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_v(lval, orig) \ 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[1]; \ 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 12603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 12623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 12633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_W(lval, orig, arg1) \ 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[2]; \ 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 12763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 12823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 12843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 12853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3]; \ 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 12993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 13063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 13083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 13093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[4]; \ 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 13243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 13323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 13343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 13353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[5]; \ 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 13513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 13603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 13623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 13633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[6]; \ 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 13803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 13903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 13923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 13933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[7]; \ 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 14113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 14213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addq $128,%%rsp\n\t" \ 14223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 14243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 14253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7) \ 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[8]; \ 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 14453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 14463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subq $136,%%rsp\n\t" \ 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $8, %%rsp\n" \ 14573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addq $136,%%rsp\n\t" \ 14583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 14603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 14613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8) \ 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[9]; \ 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 14823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 64(%%rax)\n\t" \ 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $16, %%rsp\n" \ 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 14963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 14983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 14993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9) \ 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[10]; \ 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 15213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 15223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subq $136,%%rsp\n\t" \ 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 72(%%rax)\n\t" \ 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 64(%%rax)\n\t" \ 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $24, %%rsp\n" \ 15353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addq $136,%%rsp\n\t" \ 15363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 15383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 15393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10) \ 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[11]; \ 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 15623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 80(%%rax)\n\t" \ 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 72(%%rax)\n\t" \ 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 64(%%rax)\n\t" \ 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $32, %%rsp\n" \ 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 15783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 15803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 15813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11) \ 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[12]; \ 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)(arg11); \ 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 16053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 16063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "subq $136,%%rsp\n\t" \ 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 88(%%rax)\n\t" \ 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 80(%%rax)\n\t" \ 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 72(%%rax)\n\t" \ 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 64(%%rax)\n\t" \ 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $40, %%rsp\n" \ 16213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "addq $136,%%rsp\n\t" \ 16223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 16243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 16253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11,arg12) \ 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[13]; \ 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)(arg1); \ 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)(arg2); \ 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)(arg3); \ 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)(arg4); \ 1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)(arg5); \ 1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)(arg6); \ 1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)(arg7); \ 1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)(arg8); \ 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)(arg9); \ 1646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)(arg10); \ 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)(arg11); \ 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[12] = (unsigned long)(arg12); \ 1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 16503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "subq $128,%%rsp\n\t" \ 1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 96(%%rax)\n\t" \ 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 88(%%rax)\n\t" \ 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 80(%%rax)\n\t" \ 1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 72(%%rax)\n\t" \ 1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 64(%%rax)\n\t" \ 1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "pushq 56(%%rax)\n\t" \ 1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 48(%%rax), %%r9\n\t" \ 1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 40(%%rax), %%r8\n\t" \ 1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 32(%%rax), %%rcx\n\t" \ 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 24(%%rax), %%rdx\n\t" \ 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 16(%%rax), %%rsi\n\t" \ 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq 8(%%rax), %%rdi\n\t" \ 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "movq (%%rax), %%rax\n\t" /* target->%rax */ \ 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_CALL_NOREDIR_RAX \ 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $48, %%rsp\n" \ 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addq $128,%%rsp\n\t" \ 16683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=a" (_res) \ 16703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 16713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------ ppc32-linux ------------------------ */ 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if defined(PLAT_ppc32_linux) 1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* This is useful for finding out about the on-stack stuff: 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extern int f9 ( int,int,int,int,int,int,int,int,int ); 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extern int f10 ( int,int,int,int,int,int,int,int,int,int ); 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int g9 ( void ) { 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return f9(11,22,33,44,55,66,77,88,99); 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int g10 ( void ) { 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return f10(11,22,33,44,55,66,77,88,99,110); 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int g11 ( void ) { 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return f11(11,22,33,44,55,66,77,88,99,110,121); 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int g12 ( void ) { 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return f12(11,22,33,44,55,66,77,88,99,110,121,132); 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These regs are trashed by the hidden call. */ 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __CALLER_SAVED_REGS \ 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lr", "ctr", "xer", \ 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "r11", "r12", "r13" 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These CALL_FN_ macros assume that on ppc32-linux, 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sizeof(unsigned long) == 4. */ 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_v(lval, orig) \ 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[1]; \ 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_W(lval, orig, arg1) \ 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[2]; \ 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3]; \ 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[4]; \ 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[5]; \ 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[6]; \ 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[7]; \ 1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7) \ 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[8]; \ 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8) \ 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[9]; \ 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)arg8; \ 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9) \ 1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[10]; \ 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)arg8; \ 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)arg9; \ 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-16\n\t" \ 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,36(11)\n\t" \ 1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,8(1)\n\t" \ 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,16\n\t" \ 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10) \ 1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[11]; \ 1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 2001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 2002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)arg8; \ 2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)arg9; \ 2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)arg10; \ 2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-16\n\t" \ 2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,40(11)\n\t" \ 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,12(1)\n\t" \ 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,36(11)\n\t" \ 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,8(1)\n\t" \ 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,16\n\t" \ 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11) \ 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[12]; \ 2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)arg8; \ 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)arg9; \ 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)arg10; \ 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)arg11; \ 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-32\n\t" \ 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg11 */ \ 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,44(11)\n\t" \ 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,16(1)\n\t" \ 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,40(11)\n\t" \ 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,12(1)\n\t" \ 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,36(11)\n\t" \ 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,8(1)\n\t" \ 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,32\n\t" \ 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11,arg12) \ 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[13]; \ 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[0] = (unsigned long)_orig.nraddr; \ 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)arg1; \ 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)arg2; \ 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[3] = (unsigned long)arg3; \ 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[4] = (unsigned long)arg4; \ 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[5] = (unsigned long)arg5; \ 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[6] = (unsigned long)arg6; \ 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[7] = (unsigned long)arg7; \ 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[8] = (unsigned long)arg8; \ 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[9] = (unsigned long)arg9; \ 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[10] = (unsigned long)arg10; \ 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[11] = (unsigned long)arg11; \ 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[12] = (unsigned long)arg12; \ 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-32\n\t" \ 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg12 */ \ 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,48(11)\n\t" \ 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,20(1)\n\t" \ 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg11 */ \ 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,44(11)\n\t" \ 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,16(1)\n\t" \ 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,40(11)\n\t" \ 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,12(1)\n\t" \ 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,36(11)\n\t" \ 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "stw 3,8(1)\n\t" \ 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 3,4(11)\n\t" /* arg1->r3 */ \ 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 4,8(11)\n\t" \ 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 5,12(11)\n\t" \ 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 6,16(11)\n\t" /* arg4->r6 */ \ 2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 7,20(11)\n\t" \ 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 8,24(11)\n\t" \ 2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 9,28(11)\n\t" \ 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 10,32(11)\n\t" /* arg8->r10 */ \ 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lwz 11,0(11)\n\t" /* target->r11 */ \ 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,32\n\t" \ 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3" \ 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[0]) \ 2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* PLAT_ppc32_linux */ 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------ ppc64-linux ------------------------ */ 2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if defined(PLAT_ppc64_linux) 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These regs are trashed by the hidden call. */ 2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __CALLER_SAVED_REGS \ 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lr", "ctr", "xer", \ 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "r11", "r12", "r13" 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long) == 8. */ 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_v(lval, orig) \ 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+0]; \ 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_W(lval, orig, arg1) \ 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+1]; \ 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+2]; \ 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+3]; \ 2243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 2270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+4]; \ 2273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+5]; \ 2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+6]; \ 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7) \ 2373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+7]; \ 2376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8) \ 2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+8]; \ 2415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+8] = (unsigned long)arg8; \ 2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)" /* restore tocptr */ \ 2444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9) \ 2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+9]; \ 2456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+8] = (unsigned long)arg8; \ 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+9] = (unsigned long)arg9; \ 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-128\n\t" /* expand stack frame */ \ 2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,72(11)\n\t" \ 2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,112(1)\n\t" \ 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,128" /* restore frame */ \ 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10) \ 2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+10]; \ 2504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+8] = (unsigned long)arg8; \ 2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+9] = (unsigned long)arg9; \ 2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+10] = (unsigned long)arg10; \ 2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-128\n\t" /* expand stack frame */ \ 2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,80(11)\n\t" \ 2525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,120(1)\n\t" \ 2526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,72(11)\n\t" \ 2528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,112(1)\n\t" \ 2529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,128" /* restore frame */ \ 2544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11) \ 2553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+11]; \ 2556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+8] = (unsigned long)arg8; \ 2568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+9] = (unsigned long)arg9; \ 2569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+10] = (unsigned long)arg10; \ 2570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+11] = (unsigned long)arg11; \ 2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-144\n\t" /* expand stack frame */ \ 2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg11 */ \ 2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,88(11)\n\t" \ 2578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,128(1)\n\t" \ 2579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,80(11)\n\t" \ 2581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,120(1)\n\t" \ 2582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,72(11)\n\t" \ 2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,112(1)\n\t" \ 2585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,144" /* restore frame */ \ 2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10,arg11,arg12) \ 2609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 2611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _argvec[3+12]; \ 2612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 2613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* _argvec[0] holds current r2 across the call */ \ 2614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[1] = (unsigned long)_orig.r2; \ 2615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2] = (unsigned long)_orig.nraddr; \ 2616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+1] = (unsigned long)arg1; \ 2617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+2] = (unsigned long)arg2; \ 2618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+3] = (unsigned long)arg3; \ 2619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+4] = (unsigned long)arg4; \ 2620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+5] = (unsigned long)arg5; \ 2621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+6] = (unsigned long)arg6; \ 2622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+7] = (unsigned long)arg7; \ 2623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+8] = (unsigned long)arg8; \ 2624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+9] = (unsigned long)arg9; \ 2625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+10] = (unsigned long)arg10; \ 2626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+11] = (unsigned long)arg11; \ 2627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _argvec[2+12] = (unsigned long)arg12; \ 2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 2,-16(11)\n\t" /* save tocptr */ \ 2631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ 2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,-144\n\t" /* expand stack frame */ \ 2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg12 */ \ 2634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,96(11)\n\t" \ 2635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,136(1)\n\t" \ 2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg11 */ \ 2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,88(11)\n\t" \ 2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,128(1)\n\t" \ 2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg10 */ \ 2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,80(11)\n\t" \ 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,120(1)\n\t" \ 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* arg9 */ \ 2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3,72(11)\n\t" \ 2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "std 3,112(1)\n\t" \ 2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* args1-8 */ \ 2646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 3, 8(11)\n\t" /* arg1->r3 */ \ 2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 4, 16(11)\n\t" /* arg2->r4 */ \ 2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 5, 24(11)\n\t" /* arg3->r5 */ \ 2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 6, 32(11)\n\t" /* arg4->r6 */ \ 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 7, 40(11)\n\t" /* arg5->r7 */ \ 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 8, 48(11)\n\t" /* arg6->r8 */ \ 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 9, 56(11)\n\t" /* arg7->r9 */ \ 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 10, 64(11)\n\t" /* arg8->r10 */ \ 2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 11, 0(11)\n\t" /* target->r11 */ \ 2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ 2656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr 11,%1\n\t" \ 2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "mr %0,3\n\t" \ 2658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "ld 2,-16(11)\n\t" /* restore tocptr */ \ 2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "addi 1,1,144" /* restore frame */ \ 2660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 2661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*in*/ "r" (&_argvec[2]) \ 2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* PLAT_ppc64_linux */ 2668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- arm-linux ------------------------- */ 2670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_arm_linux) 2672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These regs are trashed by the hidden call. */ 26743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" 2675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned 2677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long) == 4. */ 2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_v(lval, orig) \ 2680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 26823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[1]; \ 2683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 26843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 2685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 26863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 26873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 26883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0\n" \ 2689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 26903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_W(lval, orig, arg1) \ 2697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 26993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[2]; \ 2700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 27013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 27023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 2703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 27043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 27053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 27063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 27073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0\n" \ 2708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 27093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 27103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ 2716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 27183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[3]; \ 2719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 27203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 27213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 27223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 2723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 27243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 27253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 27263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 27273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 27283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0\n" \ 2729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 27303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ 2737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 27393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[4]; \ 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 27413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 27423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 27433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 27443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 2745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 27463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 27473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 27483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 27493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 27503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 27513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0\n" \ 2752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 27533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ 2760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 27623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[5]; \ 2763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 27643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 27653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 27663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 27673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 27683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 2769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 27703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 27713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 27723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 27733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 27743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 27753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 27763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 27783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ 2785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 27873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[6]; \ 2788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 27893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 27903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 27913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 27923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 27933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 27943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 2795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 27963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 27973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0} \n\t" \ 27983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 27993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 28003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 28013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 28023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 28033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 28043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #4 \n\t" \ 28053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 28073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ 2814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 28163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[7]; \ 2817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 28183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 28193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 28203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 28213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 28223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 28233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 28243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 2825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 28263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 28273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 28283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1} \n\t" \ 28293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 28303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 28313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 28323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 28333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 28343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 28353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #8 \n\t" \ 28363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 28383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7) \ 2846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 28483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[8]; \ 2849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 28503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 28513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 28523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 28533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 28543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 28553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 28563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 28573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 2858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 28593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 28603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 28613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 28623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2} \n\t" \ 28633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 28643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 28653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 28663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 28673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 28683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 28693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #12 \n\t" \ 28703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 28723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8) \ 2880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 28823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[9]; \ 2883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 28843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 28853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 28863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 28873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 28883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 28893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 28903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 28913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 28923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)(arg8); \ 2893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 28943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 28953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 28963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 28973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #32] \n\t" \ 28983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2, r3} \n\t" \ 28993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 29003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 29013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 29023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 29033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 29043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 29053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #16 \n\t" \ 29063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 29083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9) \ 2916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 29173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 29183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[10]; \ 29193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 29203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 29213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 29223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 29233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 29243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 29253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 29263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 29273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 29283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)(arg8); \ 29293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)(arg9); \ 2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 29313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 29323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 29333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 29343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #32] \n\t" \ 29353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1, #36] \n\t" \ 29363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2, r3, r4} \n\t" \ 29373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 29383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 29393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 29403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 29413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 29423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 29433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #20 \n\t" \ 29443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 29463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ 2953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arg7,arg8,arg9,arg10) \ 2954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 29563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[11]; \ 2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 29583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 29593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 29603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 29613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 29623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 29633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 29643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 29653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 29663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)(arg8); \ 29673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)(arg9); \ 29683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)(arg10); \ 2969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 29703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #40] \n\t" \ 29713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0} \n\t" \ 29723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 29733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 29743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 29753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #32] \n\t" \ 29763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1, #36] \n\t" \ 29773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2, r3, r4} \n\t" \ 29783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 29793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 29803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 29813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 29823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 29833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 29843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #24 \n\t" \ 29853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 2986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 29873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 2988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 2989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 2990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 2991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 2992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 29943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6,arg7,arg8,arg9,arg10, \ 29953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg11) \ 2996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 2997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 29983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[12]; \ 2999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 30003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 30013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 30023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 30033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 30043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 30053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 30063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 30073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 30083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)(arg8); \ 30093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)(arg9); \ 30103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)(arg10); \ 30113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[11] = (unsigned long)(arg11); \ 3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 30133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #40] \n\t" \ 30143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #44] \n\t" \ 30153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1} \n\t" \ 30163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 30173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 30183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 30193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #32] \n\t" \ 30203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1, #36] \n\t" \ 30213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2, r3, r4} \n\t" \ 30223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 30233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 30243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 30253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 30263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 30273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 30283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #28 \n\t" \ 30293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 3030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 30313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 30323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \ 3033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 3034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ 30383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6,arg7,arg8,arg9,arg10, \ 30393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg11,arg12) \ 3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 3041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile OrigFn _orig = (orig); \ 30423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[13]; \ 3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block volatile unsigned long _res; \ 30443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 30453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)(arg1); \ 30463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)(arg2); \ 30473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)(arg3); \ 30483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)(arg4); \ 30493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)(arg5); \ 30503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)(arg6); \ 30513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)(arg7); \ 30523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)(arg8); \ 30533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)(arg9); \ 30543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)(arg10); \ 30553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[11] = (unsigned long)(arg11); \ 30563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[12] = (unsigned long)(arg12); \ 3057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __asm__ volatile( \ 30583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #40] \n\t" \ 30593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #44] \n\t" \ 30603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #48] \n\t" \ 30613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2} \n\t" \ 30623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #20] \n\t" \ 30633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #24] \n\t" \ 30643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #28] \n\t" \ 30653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #32] \n\t" \ 30663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1, #36] \n\t" \ 30673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "push {r0, r1, r2, r3, r4} \n\t" \ 30683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r0, [%1, #4] \n\t" \ 30693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r1, [%1, #8] \n\t" \ 30703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r2, [%1, #12] \n\t" \ 30713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r3, [%1, #16] \n\t" \ 30723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "ldr r4, [%1] \n\t" /* target->r4 */ \ 30733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ 30743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "add sp, sp, #32 \n\t" \ 30753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mov %0, r0" \ 3076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*out*/ "=r" (_res) \ 30773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "0" (&_argvec[0]) \ 3078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ 3079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ); \ 3080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lval = (__typeof__(lval)) _res; \ 3081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (0) 3082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_arm_linux */ 30843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* ------------------------- s390x-linux ------------------------- */ 30863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(PLAT_s390x_linux) 30883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Similar workaround as amd64 (see above), but we use r11 as frame 30903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pointer and save the old r11 in r7. r11 might be used for 30913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch argvec, therefore we copy argvec in r1 since r1 is clobbered 30923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch after the call anyway. */ 30933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) 30943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define __FRAME_POINTER \ 30953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ,"d"(__builtin_dwarf_cfa()) 30963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_PROLOGUE \ 30973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_remember_state\n\t" \ 30983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ 30993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 7,11\n\t" \ 31003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 11,%2\n\t" \ 31013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_def_cfa r11, 0\n\t" 31023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_EPILOGUE \ 31033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 11, 7\n\t" \ 31043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ".cfi_restore_state\n\t" 31053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 31063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define __FRAME_POINTER 31073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_PROLOGUE \ 31083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr 1,%1\n\t" 31093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# define VALGRIND_CFI_EPILOGUE 31103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 31113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* These regs are trashed by the hidden call. Note that we overwrite 31163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the 31173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function a proper return address. All others are ABI defined call 31183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch clobbers. */ 31193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ 31203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "f0","f1","f2","f3","f4","f5","f6","f7" 31213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_v(lval, orig) \ 31243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 31253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 31263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[1]; \ 31273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 31283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 31293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 31303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 31313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 31323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" /* target->r1 */ \ 31333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 31343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 31353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 31363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 31373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 31383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ 31393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 31403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 31413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 31423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 31433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* The call abi has the arguments in r2-r6 and stack */ 31453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_W(lval, orig, arg1) \ 31463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 31473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 31483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[2]; \ 31493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 31503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 31513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 31523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 31533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 31543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 31553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 31563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 31573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 31583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 31593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 31603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 31613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 31623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 31633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 31643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 31653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 31663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 31673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ 31693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 31703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 31713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[3]; \ 31723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 31733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 31743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 31753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 31763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 31773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 31783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 31793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 31803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 31813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 31823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 31833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 31843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 31853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 31863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 31873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 31883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 31893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 31903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 31913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 31923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ 31943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 31953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 31963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[4]; \ 31973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 31983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 31993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 32003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 32013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 32023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 32033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 32043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 32053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 32063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 32073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 32083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 32093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 32103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 32113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 32123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 32133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 32143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 32153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 32163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 32173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 32183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 32193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 32203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ 32213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 32223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 32233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[5]; \ 32243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 32253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 32263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 32273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 32283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 32293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 32303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 32313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 32323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 32333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 32343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 32353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 32363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 32373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 32383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 32393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 32403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 32413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 32423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 32433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 32443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ 32453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 32463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 32473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 32483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 32493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ 32503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 32513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 32523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[6]; \ 32533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 32543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 32553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 32563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 32573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 32583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 32593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 32603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 32613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 32623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-160\n\t" \ 32633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 32643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 32653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 32663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 32673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 32683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 32693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 32703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 32713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,160\n\t" \ 32723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 32733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 32743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 32753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 32763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 32773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 32783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 32793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 32803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 32813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6) \ 32823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 32833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 32843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[7]; \ 32853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 32863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 32873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 32883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 32893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 32903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 32913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 32923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 32933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 32943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 32953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-168\n\t" \ 32963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 32973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 32983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 32993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 33003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 33013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 33023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 33033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 33043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 33053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,168\n\t" \ 33063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 33073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 33083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 33093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 33103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 33113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 33123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 33133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 33143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 33153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7) \ 33163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 33173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 33183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[8]; \ 33193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 33203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 33213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 33223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 33233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 33243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 33253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 33263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 33273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 33283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 33293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 33303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-176\n\t" \ 33313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 33323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 33333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 33343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 33353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 33363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 33373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 33383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 33393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 33403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 33413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,176\n\t" \ 33423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 33433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 33443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 33453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 33463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 33473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 33483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 33493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 33503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 33513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7 ,arg8) \ 33523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 33533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 33543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[9]; \ 33553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 33563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 33573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 33583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 33593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 33603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 33613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 33623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 33633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 33643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)arg8; \ 33653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 33663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 33673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-184\n\t" \ 33683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 33693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 33703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 33713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 33723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 33733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 33743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 33753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 176(8,15), 64(1)\n\t" \ 33763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 33773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 33783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 33793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,184\n\t" \ 33803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 33813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 33823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 33833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 33843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 33853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 33863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 33873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 33883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 33893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7 ,arg8, arg9) \ 33903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 33913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 33923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[10]; \ 33933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 33943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 33953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 33963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 33973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 33983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 33993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 34003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 34013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 34023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)arg8; \ 34033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)arg9; \ 34043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 34053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 34063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-192\n\t" \ 34073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 34083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 34093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 34103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 34113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 34123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 34133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 34143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 176(8,15), 64(1)\n\t" \ 34153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 184(8,15), 72(1)\n\t" \ 34163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 34173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 34183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 34193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,192\n\t" \ 34203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 34213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 34223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 34233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 34243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 34253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 34263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 34273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 34283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 34293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7 ,arg8, arg9, arg10) \ 34303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 34313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 34323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[11]; \ 34333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 34343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 34353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 34363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 34373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 34383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 34393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 34403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 34413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 34423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)arg8; \ 34433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)arg9; \ 34443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)arg10; \ 34453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 34463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 34473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-200\n\t" \ 34483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 34493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 34503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 34513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 34523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 34533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 34543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 34553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 176(8,15), 64(1)\n\t" \ 34563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 184(8,15), 72(1)\n\t" \ 34573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 192(8,15), 80(1)\n\t" \ 34583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 34593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 34603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 34613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,200\n\t" \ 34623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 34633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 34643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 34653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 34663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 34673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 34683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 34693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 34703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 34713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7 ,arg8, arg9, arg10, arg11) \ 34723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 34733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 34743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[12]; \ 34753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 34763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 34773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 34783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 34793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 34803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 34813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 34823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 34833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 34843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)arg8; \ 34853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)arg9; \ 34863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)arg10; \ 34873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[11] = (unsigned long)arg11; \ 34883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 34893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 34903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-208\n\t" \ 34913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 34923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 34933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 34943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 34953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 34963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 34973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 34983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 176(8,15), 64(1)\n\t" \ 34993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 184(8,15), 72(1)\n\t" \ 35003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 192(8,15), 80(1)\n\t" \ 35013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 200(8,15), 88(1)\n\t" \ 35023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 35033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 35043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 35053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,208\n\t" \ 35063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 35073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 35083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 35093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 35103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 35113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 35123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 35133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 35143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ 35153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ 35163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { \ 35173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile OrigFn _orig = (orig); \ 35183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _argvec[13]; \ 35193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch volatile unsigned long _res; \ 35203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[0] = (unsigned long)_orig.nraddr; \ 35213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[1] = (unsigned long)arg1; \ 35223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[2] = (unsigned long)arg2; \ 35233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[3] = (unsigned long)arg3; \ 35243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[4] = (unsigned long)arg4; \ 35253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[5] = (unsigned long)arg5; \ 35263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[6] = (unsigned long)arg6; \ 35273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[7] = (unsigned long)arg7; \ 35283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[8] = (unsigned long)arg8; \ 35293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[9] = (unsigned long)arg9; \ 35303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[10] = (unsigned long)arg10; \ 35313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[11] = (unsigned long)arg11; \ 35323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _argvec[12] = (unsigned long)arg12; \ 35333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __asm__ volatile( \ 35343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_PROLOGUE \ 35353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,-216\n\t" \ 35363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 2, 8(1)\n\t" \ 35373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 3,16(1)\n\t" \ 35383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 4,24(1)\n\t" \ 35393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 5,32(1)\n\t" \ 35403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 6,40(1)\n\t" \ 35413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 160(8,15), 48(1)\n\t" \ 35423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 168(8,15), 56(1)\n\t" \ 35433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 176(8,15), 64(1)\n\t" \ 35443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 184(8,15), 72(1)\n\t" \ 35453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 192(8,15), 80(1)\n\t" \ 35463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 200(8,15), 88(1)\n\t" \ 35473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "mvc 208(8,15), 96(1)\n\t" \ 35483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lg 1, 0(1)\n\t" \ 35493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CALL_NOREDIR_R1 \ 35503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "lgr %0, 2\n\t" \ 35513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "aghi 15,216\n\t" \ 35523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_CFI_EPILOGUE \ 35533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*out*/ "=d" (_res) \ 35543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ 35553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ 35563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ); \ 35573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch lval = (__typeof__(lval)) _res; \ 35583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (0) 35593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 35603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 35613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* PLAT_s390x_linux */ 3562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 3565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ 3566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* */ 3567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------------------------------ */ 3568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Some request codes. There are many more of these, but most are not 3570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exposed to end-user view. These are the public ones, all of the 3571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block form 0x1000 + small_number. 3572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Core ones are in the range 0x00000000--0x0000ffff. The non-public 3574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ones start at 0x2000. 3575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 3576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These macros are used by tools -- they must be public, but don't 3578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block embed them into other programs. */ 3579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VG_USERREQ_TOOL_BASE(a,b) \ 3580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) 3581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VG_IS_TOOL_USERREQ(a, b, v) \ 3582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) 3583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 3585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block This enum comprises an ABI exported by Valgrind to programs 3586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block which use client requests. DO NOT CHANGE THE ORDER OF THESE 3587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ENTRIES, NOR DELETE ANY -- add new ones at the end. */ 3588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef 3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, 3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, 3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* These allow any function to be called from the simulated 3593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CPU but run on the real CPU. Nb: the first arg passed to 3594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block the function is always the ThreadId of the running 3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread! So CLIENT_CALL0 actually requires a 1 arg 3596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function, etc. */ 3597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CLIENT_CALL0 = 0x1101, 3598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CLIENT_CALL1 = 0x1102, 3599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CLIENT_CALL2 = 0x1103, 3600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CLIENT_CALL3 = 0x1104, 3601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Can be useful in regression testing suites -- eg. can 3603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block send Valgrind's output to /dev/null and still count 3604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block errors. */ 3605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__COUNT_ERRORS = 0x1201, 3606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* Allows a string (gdb monitor command) to be passed to the tool 36083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Used for interaction with vgdb/gdb */ 36093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, 36103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* These are useful and can be interpreted by any tool that 3612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tracks malloc() et al, by using vg_replace_malloc.c. */ 3613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, 36143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, 3615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__FREELIKE_BLOCK = 0x1302, 3616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Memory pool support. */ 3617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CREATE_MEMPOOL = 0x1303, 3618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__DESTROY_MEMPOOL = 0x1304, 3619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_ALLOC = 0x1305, 3620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_FREE = 0x1306, 3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_TRIM = 0x1307, 3622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MOVE_MEMPOOL = 0x1308, 3623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_CHANGE = 0x1309, 3624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_EXISTS = 0x130a, 3625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Allow printfs to valgrind log. */ 36273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* The first two pass the va_list argument by value, which 36283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch assumes it is the same size as or smaller than a UWord, 36293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch which generally isn't the case. Hence are deprecated. 36303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch The second two pass the vargs by reference and so are 36313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch immune to this problem. */ 36323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* both :: char* fmt, va_list vargs (DEPRECATED) */ 3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__PRINTF = 0x1401, 3634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__PRINTF_BACKTRACE = 0x1402, 36353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* both :: char* fmt, va_list* vargs */ 36363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, 36373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, 3638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Stack support. */ 3640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__STACK_REGISTER = 0x1501, 3641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__STACK_DEREGISTER = 0x1502, 36423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__STACK_CHANGE = 0x1503, 36433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 36443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* Wine support */ 36453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, 36463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 36473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch /* Querying of debug info. */ 36483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701 3649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } Vg_ClientRequest; 3650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if !defined(__GNUC__) 3652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# define __extension__ /* */ 3653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 3654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Returns the number of Valgrinds this code is running under. That 3657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is, 0 if running natively, 1 if running under Valgrind, 2 if 3658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running under Valgrind which is running under another Valgrind, 3659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block etc. */ 36603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define RUNNING_ON_VALGRIND \ 36613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ 36623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__RUNNING_ON_VALGRIND, \ 36633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 0, 0, 0, 0) \ 3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block _qzz_len - 1]. Useful if you are debugging a JITter or some such, 3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block since it provides a way to make sure valgrind will retranslate the 3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block invalidated area. Returns no value. */ 3670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ 36713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__DISCARD_TRANSLATIONS, \ 36733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qzz_addr, _qzz_len, 0, 0, 0) 3674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These requests are for getting Valgrind itself to print something. 36773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Possibly with a backtrace. This is a really ugly hack. The return value 36783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch is the number of characters printed, excluding the "**<pid>** " part at the 36793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch start and the backtrace (if present). */ 3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__GNUC__) || defined(__INTEL_COMPILER) 3682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Modern GCC will optimize the static routine out if unused, 3683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block and unused attribute will shut down warnings about it. */ 3684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int VALGRIND_PRINTF(const char *format, ...) 3685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __attribute__((format(__printf__, 1, 2), __unused__)); 36863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int 36883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 36893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch__inline 36903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockVALGRIND_PRINTF(const char *format, ...) 3692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{ 36933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(NVALGRIND) 36943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return 0; 36953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else /* NVALGRIND */ 36963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 36973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t _qzz_res; 36983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 3699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned long _qzz_res; 37003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_list vargs; 3702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_start(vargs, format); 37033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 37043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 37053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_VALIST_BY_REF, 37063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)format, 37073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)&vargs, 37083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 0, 0); 37093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 37103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 37113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_VALIST_BY_REF, 37123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned long)format, 37133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned long)&vargs, 3714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 0, 0); 37153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_end(vargs); 3717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (int)_qzz_res; 37183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif /* NVALGRIND */ 3719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__GNUC__) || defined(__INTEL_COMPILER) 3722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) 3723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __attribute__((format(__printf__, 1, 2), __unused__)); 37243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int 37263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 37273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch__inline 37283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockVALGRIND_PRINTF_BACKTRACE(const char *format, ...) 3730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block{ 37313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(NVALGRIND) 37323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return 0; 37333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else /* NVALGRIND */ 37343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 37353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t _qzz_res; 37363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 3737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned long _qzz_res; 37383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_list vargs; 3740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_start(vargs, format); 37413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(_MSC_VER) 37423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 37433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, 37443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)format, 37453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (uintptr_t)&vargs, 37463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 0, 0); 37473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 37483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, 37493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, 37503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned long)format, 37513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned long)&vargs, 3752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 0, 0); 37533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 3754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_end(vargs); 3755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (int)_qzz_res; 3756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* NVALGRIND */ 37573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 3758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* These requests allow control to move from the simulated CPU to the 3761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block real CPU, calling an arbitary function. 3762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Note that the current ThreadId is inserted as the first argument. 3764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block So this call: 3765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) 3767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block requires f to have this signature: 3769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Word f(Word tid, Word arg1, Word arg2) 3771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block where "Word" is a word-sized type. 3773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Note that these client requests are not entirely reliable. For example, 3775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if you call a function with them that subsequently calls printf(), 3776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block there's a high chance Valgrind will crash. Generally, your prospects of 3777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block these working are made higher if the called function does not refer to 3778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block any global variables, and does not refer to any libc or other functions 3779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (printf et al). Any kind of entanglement with libc or dynamic linking is 3780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block likely to have a bad outcome, for tricky reasons which we've grappled 3781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block with a lot in the past. 3782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 3783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ 37843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 37853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__CLIENT_CALL0, \ 37863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_fn, \ 37873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 0, 0, 0) 37883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 37893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ 37903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 37913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__CLIENT_CALL1, \ 37923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_fn, \ 37933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_arg1, 0, 0, 0) 37943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 37953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ 37963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 37973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__CLIENT_CALL2, \ 37983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_fn, \ 37993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_arg1, _qyy_arg2, 0, 0) 3800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ 38023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ 38033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__CLIENT_CALL3, \ 38043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_fn, \ 38053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_arg1, _qyy_arg2, \ 38063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch _qyy_arg3, 0) 3807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Counts the number of errors that have been recorded by a tool. Nb: 3810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block the tool must record the errors with VG_(maybe_record_error)() or 3811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_(unique_error)() for them to be counted. */ 3812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_COUNT_ERRORS \ 38133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ 38143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0 /* default return */, \ 3815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__COUNT_ERRORS, \ 38163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 0, 0, 0, 0) 38173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing 38193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch when heap blocks are allocated in order to give accurate results. This 38203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch happens automatically for the standard allocator functions such as 38213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, 38223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete[], etc. 38233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch But if your program uses a custom allocator, this doesn't automatically 38253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch happen, and Valgrind will not do as well. For example, if you allocate 38263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch superblocks with mmap() and then allocates chunks of the superblocks, all 38273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Valgrind's observations will be at the mmap() level and it won't know that 38283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch the chunks should be considered separate entities. In Memcheck's case, 38293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch that means you probably won't get heap block overrun detection (because 38303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch there won't be redzones marked as unaddressable) and you definitely won't 38313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch get any leak detection. 38323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch The following client requests allow a custom allocator to be annotated so 38343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch that it can be handled accurately by Valgrind. 38353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated 38373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch by a malloc()-like function. For Memcheck (an illustrative case), this 38383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch does two things: 38393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - It records that the block has been allocated. This means any addresses 38413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch within the block mentioned in error messages will be 38423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch identified as belonging to the block. It also means that if the block 38433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isn't freed it will be detected by the leak checker. 38443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - It marks the block as being addressable and undefined (if 'is_zeroed' is 38463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch not set), or addressable and defined (if 'is_zeroed' is set). This 38473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch controls how accesses to the block by the program are handled. 3848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 'addr' is the start of the usable block (ie. after any 38503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator 38513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch can apply redzones -- these are blocks of padding at the start and end of 38523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch each block. Adding redzones is recommended as it makes it much more likely 38533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Valgrind will spot block overruns. `is_zeroed' indicates if the memory is 38543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch zeroed (or filled with another predictable value), as is the case for 38553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch calloc(). 38563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a 38583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch heap block -- that will be used by the client program -- is allocated. 38593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch It's best to put it at the outermost level of the allocator if possible; 38603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for example, if you have a function my_alloc() which calls 38613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch internal_alloc(), and the client request is put inside internal_alloc(), 38623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch stack traces relating to the heap block will contain entries for both 38633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch my_alloc() and internal_alloc(), which is probably not what you want. 38643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out 38663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch custom blocks from within a heap block, B, that has been allocated with 38673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch malloc/calloc/new/etc, then block B will be *ignored* during leak-checking 38683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch -- the custom blocks will take precedence. 38693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For 38713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Memcheck, it does two things: 38723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - It records that the block has been deallocated. This assumes that the 38743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block was annotated as having been allocated via 38753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. 38763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - It marks the block as being unaddressable. 38783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a 38803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch heap block is deallocated. 38813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For 38833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Memcheck, it does four things: 38843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - It records that the size of a block has been changed. This assumes that 38863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch the block was annotated as having been allocated via 38873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. 38883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - If the block shrunk, it marks the freed memory as being unaddressable. 38903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - If the block grew, it marks the new area as undefined and defines a red 38923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch zone past the end of the new block. 38933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch - The V-bits of the overlap between the old and the new block are preserved. 38953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block 38973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch and before deallocation of the old block. 38983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 38993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch In many cases, these three client requests will not be enough to get your 39003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch allocator working well with Memcheck. More specifically, if your allocator 39013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call 39023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch will be necessary to mark the memory as addressable just before the zeroing 39033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch occurs, otherwise you'll get a lot of invalid write errors. For example, 39043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch you'll need to do this if your allocator recycles freed blocks, but it 39053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). 39063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Alternatively, if your allocator reuses freed blocks for allocator-internal 39073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. 39083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 39093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Really, what's happening is a blurring of the lines between the client 39103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the 39113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch memory should be considered unaddressable to the client program, but the 39123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch allocator knows more than the rest of the client program and so may be able 39133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch to safely access it. Extra client requests are necessary for Valgrind to 39143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch understand the distinction between the allocator and the rest of the 39153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch program. 39163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 39173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Ignored if addr == 0. 39183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 3919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ 39203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MALLOCLIKE_BLOCK, \ 39223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch addr, sizeB, rzB, is_zeroed, 0) 39233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 39243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. 39253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Ignored if addr == 0. 39263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 39273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ 39283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 39293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__RESIZEINPLACE_BLOCK, \ 39303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch addr, oldSizeB, newSizeB, rzB, 0) 3931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. 39333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Ignored if addr == 0. 39343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch*/ 3935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ 39363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__FREELIKE_BLOCK, \ 39383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch addr, rzB, 0, 0, 0) 3939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Create a memory pool. */ 3941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ 39423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__CREATE_MEMPOOL, \ 39443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, rzB, is_zeroed, 0, 0) 3945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Destroy a memory pool. */ 3947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_DESTROY_MEMPOOL(pool) \ 39483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__DESTROY_MEMPOOL, \ 39503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, 0, 0, 0, 0) 3951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Associate a piece of memory with a memory pool. */ 3953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ 39543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_ALLOC, \ 39563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, addr, size, 0, 0) 3957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Disassociate a piece of memory from a memory pool. */ 3959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MEMPOOL_FREE(pool, addr) \ 39603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_FREE, \ 39623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, addr, 0, 0, 0) 3963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Disassociate any pieces outside a particular range. */ 3965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ 39663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_TRIM, \ 39683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, addr, size, 0, 0) 3969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Resize and/or move a piece associated with a memory pool. */ 3971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ 39723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MOVE_MEMPOOL, \ 39743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch poolA, poolB, 0, 0, 0) 3975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Resize and/or move a piece associated with a memory pool. */ 3977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ 39783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_CHANGE, \ 39803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, addrA, addrB, size, 0) 3981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Return 1 if a mempool exists, else 0. */ 3983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_MEMPOOL_EXISTS(pool) \ 39843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__MEMPOOL_EXISTS, \ 39863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch pool, 0, 0, 0, 0) 3987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Mark a piece of memory as being a stack. Returns a stack id. */ 3989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_STACK_REGISTER(start, end) \ 39903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__STACK_REGISTER, \ 39923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch start, end, 0, 0, 0) 3993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Unmark the piece of memory associated with a stack id as being a 3995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack. */ 3996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_STACK_DEREGISTER(id) \ 39973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 3998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__STACK_DEREGISTER, \ 39993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch id, 0, 0, 0, 0) 4000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Change the start and end address of the stack id. */ 4002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define VALGRIND_STACK_CHANGE(id, start, end) \ 40033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 4004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VG_USERREQ__STACK_CHANGE, \ 40053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch id, start, end, 0, 0) 40063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 40073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Load PDB debug info for Wine PE image_map. */ 40083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ 40093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 40103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__LOAD_PDB_DEBUGINFO, \ 40113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fd, ptr, total_size, delta, 0) 40123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 40133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch/* Map a code address to a source file name and line number. buf64 40143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch must point to a 64-byte buffer in the caller's address space. The 40153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result will be dumped in there and is guaranteed to be zero 40163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch terminated. If no info is found, the first byte is set to zero. */ 40173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ 40183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ 40193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VG_USERREQ__MAP_IP_TO_SRCLOC, \ 40203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch addr, buf64, 0, 0, 0) 40213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 40223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 40233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_x86_darwin 40243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_amd64_darwin 40253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_x86_win32 4026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_x86_linux 4027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_amd64_linux 4028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_ppc32_linux 4029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef PLAT_ppc64_linux 40303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_arm_linux 40313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#undef PLAT_s390x_linux 4032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif /* __VALGRIND_H */ 4034