1 2 /*--------------------------------------------------------------------*/ 3 /*--- Redirections, etc. pub_tool_redir.h ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2010 Julian Seward 11 jseward (at) acm.org 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #ifndef __PUB_TOOL_REDIR_H 32 #define __PUB_TOOL_REDIR_H 33 34 /* The following macros facilitate function replacement and wrapping. 35 36 Function wrapping and function replacement are similar but not 37 identical. 38 39 A replacement for some function F simply diverts all calls to F 40 to the stated replacement. There is no way to get back to F itself 41 from the replacement. 42 43 A wrapper for a function F causes all calls to F to instead go to 44 the wrapper. However, from inside the wrapper, it is possible 45 (with some difficulty) to get to F itself. 46 47 You may notice that replacement is a special case of wrapping, in 48 which the call to the original is omitted. For implementation 49 reasons, though, it is important to use the following macros 50 correctly: in particular, if you want to write a replacement, make 51 sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_ 52 macros. 53 54 Replacement 55 ~~~~~~~~~~~ 56 To write a replacement function, do this: 57 58 ret_type 59 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. ) 60 { 61 ... body ... 62 } 63 64 zEncodedSoname should be a Z-encoded soname (see below for Z-encoding 65 details) and fnname should be an unencoded fn name. The resulting name is 66 67 _vgrZU_zEncodedSoname_fnname 68 69 The "_vgrZU_" is a prefix that gets discarded upon decoding. 70 71 It is also possible to write 72 73 ret_type 74 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. ) 75 { 76 ... body ... 77 } 78 79 which means precisely the same, but the function name is also 80 Z-encoded. This can sometimes be necessary. In this case the 81 resulting function name is 82 83 _vgrZZ_zEncodedSoname_zEncodedFnname 84 85 When it sees this either such name, the core's symbol-table reading 86 machinery and redirection machinery first Z-decode the soname and 87 if necessary the fnname. They are encoded so that they may include 88 arbitrary characters, and in particular they may contain '*', which 89 acts as a wildcard. 90 91 They then will conspire to cause calls to any function matching 92 'fnname' in any object whose soname matches 'soname' to actually be 93 routed to this function. This is used in Valgrind to define dozens 94 of replacements of malloc, free, etc. 95 96 The soname must be a Z-encoded bit of text because sonames can 97 contain dots etc which are not valid symbol names. The function 98 name may or may not be Z-encoded: to include wildcards it has to be, 99 but Z-encoding C++ function names which are themselves already mangled 100 using Zs in some way is tedious and error prone, so the _ZU variant 101 allows them not to be Z-encoded. 102 103 Note that the soname "NONE" is specially interpreted to match any 104 shared object which doesn't have a soname. 105 106 Note also that the replacement function should probably (must be?) in 107 client space, so it runs on the simulated CPU. So it must be in 108 either vgpreload_<tool>.so or vgpreload_core.so. It also only works 109 with functions in shared objects, I think. 110 111 It is important that the Z-encoded names contain no unencoded 112 underscores, since the intercept-handlers in m_redir.c detect the 113 end of the soname by looking for the first trailing underscore. 114 115 Wrapping 116 ~~~~~~~~ 117 This is identical to replacement, except that you should use the 118 macro names 119 120 VG_WRAP_FUNCTION_ZU 121 VG_WRAP_FUNCTION_ZZ 122 123 instead. 124 125 Z-encoding 126 ~~~~~~~~~~ 127 Z-encoding details: the scheme is like GHC's. It is just about 128 readable enough to make a preprocessor unnecessary. First the 129 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following 130 characters are transformed. 131 132 * --> Za (asterisk) 133 : --> Zc (colon) 134 . --> Zd (dot) 135 - --> Zh (hyphen) 136 + --> Zp (plus) 137 (space) --> Zs (space) 138 _ --> Zu (underscore) 139 @ --> ZA (at) 140 $ --> ZD (dollar) 141 ( --> ZL (left) 142 ) --> ZR (right) 143 Z --> ZZ (Z) 144 145 Everything else is left unchanged. 146 */ 147 148 /* If you change these, the code in VG_(maybe_Z_demangle) needs to be 149 changed accordingly. NOTE: duplicates 150 I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */ 151 152 /* Use an extra level of macroisation so as to ensure the soname/fnname 153 args are fully macro-expanded before pasting them together. */ 154 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd 155 156 #define VG_REPLACE_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgrZU_,soname,_,fnname) 157 #define VG_REPLACE_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgrZZ_,soname,_,fnname) 158 159 #define VG_WRAP_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgwZU_,soname,_,fnname) 160 #define VG_WRAP_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgwZZ_,soname,_,fnname) 161 162 /* --------- Some handy Z-encoded names. --------- */ 163 164 // Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_". Why? If we applied 165 // conditional compilation inconsistently we could accidentally use an 166 // undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded 167 // name like "_vgrZU_VG_Z_LIBC_DOT_A_foo". This can't be detected at 168 // compile-time, because both the constant's name and its value are 169 // identifiers. However, by always using "VG_Z_" as a prefix, we can do a 170 // run-time check and abort if any name has "VG_Z_" in it, because that 171 // indicates that the constant has been used without being defined. 172 173 /* --- Soname of the standard C library. --- */ 174 175 #if defined(VGO_linux) 176 # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* 177 #elif defined(VGP_ppc32_aix5) 178 /* AIX has both /usr/lib/libc.a and /usr/lib/libc_r.a. */ 179 # define VG_Z_LIBC_SONAME libcZaZdaZLshrZdoZR // libc*.a(shr.o) 180 #elif defined(VGP_ppc64_aix5) 181 # define VG_Z_LIBC_SONAME libcZaZdaZLshrZu64ZdoZR // libc*.a(shr_64.o) 182 #elif defined(VGO_darwin) 183 # define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib 184 #else 185 # error "Unknown platform" 186 #endif 187 188 /* --- Soname of the GNU C++ library. --- */ 189 190 // Valid on all platforms(?) 191 #define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++* 192 193 /* --- Soname of XLC's C++ library. --- */ 194 195 /* AIX: xlC's C++ runtime library is called libC.a, and the 196 interesting symbols appear to be in ansicore_32.o or ansicore_64.o 197 respectively. */ 198 #if defined(VGP_ppc32_aix5) 199 # define VG_Z_LIBC_DOT_A libCZdaZLansicoreZu32ZdoZR // libC.a(ansicore_32.o) 200 #elif defined(VGP_ppc64_aix5) 201 # define VG_Z_LIBC_DOT_A libCZdaZLansicoreZu64ZdoZR // libC.a(ansicore_64.o) 202 #endif 203 204 /* --- Soname of the pthreads library. --- */ 205 206 #if defined(ANDROID) 207 # define VG_Z_LIBPTHREAD_SONAME libcZdsoZa // libc.so* 208 #elif defined(VGO_linux) || defined(VGO_aix5) 209 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 210 #elif defined(VGO_darwin) 211 # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib 212 #else 213 # error "Unknown platform" 214 #endif 215 216 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */ 217 218 #if defined(VGO_linux) 219 220 #define VG_Z_LD_LINUX_SO_3 ldZhlinuxZdsoZd3 // ld-linux.so.3 221 #define VG_U_LD_LINUX_SO_3 "ld-linux.so.3" 222 223 #define VG_Z_LD_LINUX_SO_2 ldZhlinuxZdsoZd2 // ld-linux.so.2 224 #define VG_U_LD_LINUX_SO_2 "ld-linux.so.2" 225 226 #define VG_Z_LD_LINUX_X86_64_SO_2 ldZhlinuxZhx86Zh64ZdsoZd2 // ld-linux-x86-64.so.2 227 #define VG_U_LD_LINUX_X86_64_SO_2 "ld-linux-x86-64.so.2" 228 229 #define VG_Z_LD64_SO_1 ld64ZdsoZd1 // ld64.so.1 230 #define VG_U_LD64_SO_1 "ld64.so.1" 231 232 #define VG_Z_LD_SO_1 ldZdsoZd1 // ld.so.1 233 #define VG_U_LD_SO_1 "ld.so.1" 234 235 #endif 236 237 /* --- Executable name for Darwin Mach-O linker. --- */ 238 239 #if defined(VGO_darwin) 240 241 #define VG_Z_DYLD dyld // dyld 242 #define VG_U_DYLD "dyld" 243 244 #endif 245 246 247 #endif // __PUB_TOOL_REDIR_H 248 249 /*--------------------------------------------------------------------*/ 250 /*--- end ---*/ 251 /*--------------------------------------------------------------------*/ 252