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