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-2017 Julian Seward 11 jseward@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 #include "config.h" /* DARWIN_VERS */ 35 #include "pub_tool_basics.h" // Bool and HChar 36 37 /* The following macros facilitate function replacement and wrapping. 38 39 Function wrapping and function replacement are similar but not 40 identical. 41 42 A replacement for some function F simply diverts all calls to F 43 to the stated replacement. There is no way to get back to F itself 44 from the replacement. 45 46 A wrapper for a function F causes all calls to F to instead go to 47 the wrapper. However, from inside the wrapper, it is possible 48 (with some difficulty) to get to F itself. 49 50 You may notice that replacement is a special case of wrapping, in 51 which the call to the original is omitted. For implementation 52 reasons, though, it is important to use the following macros 53 correctly: in particular, if you want to write a replacement, make 54 sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_ 55 macros. 56 57 Finally there is the concept of prioritised behavioural equivalence 58 tags. A tag is a 5-digit decimal number (00000 to 99999) encoded 59 in the name. The top 4 digits are the equivalence class number, 60 and the last digit is a priority. 61 62 When processing redirections at library load time, if the set of 63 available specifications yields more than one replacement or 64 wrapper function for a given address, the system will try to 65 resolve the situation by examining the tags on the 66 replacements/wrappers. 67 68 If two replacement/wrapper functions have the same tag and 69 priority, then the redirection machinery will assume they have 70 identical behaviour and can choose between them arbitrarily. If 71 they have the same tag but different priorities, then the one with 72 higher priority will be chosen. If neither case holds, then the 73 redirection is ambiguous and the system will ignore one of them 74 arbitrarily, but print a warning when running at -v or above. 75 76 The tag is mandatory and must comprise 5 decimal digits. The tag 77 00000 is special and means "does not have behaviour identical to any 78 other replacement/wrapper function". Hence if you wish to write a 79 wrap/replacement function that is not subject to the above 80 resolution rules, use 00000 for the tag. Tags 00001 through 00009 81 may not be used for any purpose. 82 83 84 Replacement 85 ~~~~~~~~~~~ 86 To write a replacement function, do this: 87 88 ret_type 89 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. ) 90 { 91 ... body ... 92 } 93 94 zEncodedSoname should be a Z-encoded soname (see below for 95 Z-encoding details) and fnname should be an unencoded fn name. A 96 default-safe equivalence tag of 00000 is assumed (see comments 97 above). The resulting name is 98 99 _vgr00000ZU_zEncodedSoname_fnname 100 101 The "_vgr00000ZU_" is a prefix that gets discarded upon decoding. 102 It identifies this function as a replacement and specifies its 103 equivalence tag. 104 105 It is also possible to write 106 107 ret_type 108 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. ) 109 { 110 ... body ... 111 } 112 113 which means precisely the same, but the function name is also 114 Z-encoded. This can sometimes be necessary. In this case the 115 resulting function name is 116 117 _vgr00000ZZ_zEncodedSoname_zEncodedFnname 118 119 When it sees this either such name, the core's symbol-table reading 120 machinery and redirection machinery first Z-decode the soname and 121 if necessary the fnname. They are encoded so that they may include 122 arbitrary characters, and in particular they may contain '*', which 123 acts as a wildcard. 124 125 They then will conspire to cause calls to any function matching 126 'fnname' in any object whose soname matches 'soname' to actually be 127 routed to this function. This is used in Valgrind to define dozens 128 of replacements of malloc, free, etc. 129 130 The soname must be a Z-encoded bit of text because sonames can 131 contain dots etc which are not valid symbol names. The function 132 name may or may not be Z-encoded: to include wildcards it has to be, 133 but Z-encoding C++ function names which are themselves already mangled 134 using Zs in some way is tedious and error prone, so the _ZU variant 135 allows them not to be Z-encoded. 136 137 Note that the soname "NONE" is specially interpreted to match any 138 shared object which doesn't have a soname. 139 140 Note also that the replacement function should probably (must be?) in 141 client space, so it runs on the simulated CPU. So it must be in 142 either vgpreload_<tool>.so or vgpreload_core.so. It also only works 143 with functions in shared objects, I think. 144 145 It is important that the Z-encoded names contain no unencoded 146 underscores, since the intercept-handlers in m_redir.c detect the 147 end of the soname by looking for the first trailing underscore. 148 149 To write function names which explicitly state the equivalence class 150 tag, use 151 VG_REPLACE_FUNCTION_EZU(5-digit-tag,zEncodedSoname,fnname) 152 or 153 VG_REPLACE_FUNCTION_EZZ(5-digit-tag,zEncodedSoname,zEncodedFnname) 154 155 As per comments above, the tag must be a 5 digit decimal number, 156 padded with leading zeroes, in the range 00010 to 99999 inclusive. 157 158 159 Wrapping 160 ~~~~~~~~ 161 This is identical to replacement, except that you should use the 162 macro names 163 164 VG_WRAP_FUNCTION_ZU 165 VG_WRAP_FUNCTION_ZZ 166 VG_WRAP_FUNCTION_EZU 167 VG_WRAP_FUNCTION_EZZ 168 169 instead. 170 171 Z-encoding 172 ~~~~~~~~~~ 173 Z-encoding details: the scheme is like GHC's. It is just about 174 readable enough to make a preprocessor unnecessary. First the 175 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following 176 characters are transformed. 177 178 * --> Za (asterisk) 179 : --> Zc (colon) 180 . --> Zd (dot) 181 - --> Zh (hyphen) 182 + --> Zp (plus) 183 (space) --> Zs (space) 184 _ --> Zu (underscore) 185 @ --> ZA (at) 186 $ --> ZD (dollar) 187 ( --> ZL (left) 188 % --> ZP (percent) 189 ) --> ZR (right) 190 / --> ZS (slash) 191 Z --> ZZ (Z) 192 193 Everything else is left unchanged. 194 */ 195 196 /* If you change these, the code in VG_(maybe_Z_demangle) needs to be 197 changed accordingly. NOTE: duplicates 198 I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */ 199 200 /* Use an extra level of macroisation so as to ensure the soname/fnname 201 args are fully macro-expanded before pasting them together. */ 202 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd 203 204 #define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff 205 206 /* The 4 basic macros. */ 207 #define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \ 208 VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname) 209 210 #define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \ 211 VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname) 212 213 #define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \ 214 VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname) 215 216 #define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \ 217 VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname) 218 219 /* Convenience macros defined in terms of the above 4. */ 220 #define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \ 221 VG_CONCAT6(_vgr,00000,ZU_,_soname,_,_fnname) 222 223 #define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \ 224 VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname) 225 226 #define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \ 227 VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname) 228 229 #define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \ 230 VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname) 231 232 233 /* --------- Some handy Z-encoded names. --------- */ 234 235 // Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_". Why? If we applied 236 // conditional compilation inconsistently we could accidentally use an 237 // undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded 238 // name like "_vgrZU_VG_Z_LIBC_DOT_A_foo". This can't be detected at 239 // compile-time, because both the constant's name and its value are 240 // identifiers. However, by always using "VG_Z_" as a prefix, we can do a 241 // run-time check and abort if any name has "VG_Z_" in it, because that 242 // indicates that the constant has been used without being defined. 243 244 /* --- Soname of the standard C library. --- */ 245 246 #if defined(VGO_linux) || defined(VGO_solaris) 247 # if defined(MUSL_LIBC) 248 # define VG_Z_LIBC_SONAME libcZdZa // libc.* 249 #else 250 # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* 251 #endif 252 #elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6) 253 # define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib 254 255 #elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \ 256 || DARWIN_VERS == DARWIN_10_8) 257 # define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib 258 /* Note that the idea of a single name for the C library falls 259 apart on more recent Darwins (10.8 and later) since the 260 functionality (malloc, free, str*) is split between 261 libsystem_c.dylib, libsystem_malloc.dylib and 262 libsystem_platform.dylib. This makes VG_Z_LIBC_SONAME somewhat useless 263 at least inside vg_replace_strmem.c, and that hardwires some dylib 264 names directly, for OSX 10.9. */ 265 266 #elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9) 267 # define VG_Z_LIBC_SONAME libsystemZumallocZddylib // libsystem_malloc.dylib 268 269 #else 270 # error "Unknown platform" 271 272 #endif 273 274 /* --- Soname of the GNU C++ library. --- */ 275 276 // Valid on all platforms(?) 277 #define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++* 278 279 /* --- Soname of the pthreads library. --- */ 280 281 #if defined(VGO_linux) 282 # if defined(MUSL_LIBC) 283 # define VG_Z_LIBPTHREAD_SONAME libcZdZa // libc.* 284 #else 285 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 286 #endif 287 #elif defined(VGO_darwin) 288 # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib 289 #elif defined(VGO_solaris) 290 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd1 // libpthread.so.1 291 #else 292 # error "Unknown platform" 293 #endif 294 295 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */ 296 297 #if defined(VGO_linux) 298 299 #define VG_Z_LD_LINUX_SO_3 ldZhlinuxZdsoZd3 // ld-linux.so.3 300 #define VG_U_LD_LINUX_SO_3 "ld-linux.so.3" 301 302 #define VG_Z_LD_LINUX_SO_2 ldZhlinuxZdsoZd2 // ld-linux.so.2 303 #define VG_U_LD_LINUX_SO_2 "ld-linux.so.2" 304 305 #define VG_Z_LD_LINUX_X86_64_SO_2 ldZhlinuxZhx86Zh64ZdsoZd2 306 // ld-linux-x86-64.so.2 307 #define VG_U_LD_LINUX_X86_64_SO_2 "ld-linux-x86-64.so.2" 308 309 #define VG_Z_LD64_SO_1 ld64ZdsoZd1 // ld64.so.1 310 #define VG_U_LD64_SO_1 "ld64.so.1" 311 #define VG_U_LD64_SO_2 "ld64.so.2" // PPC LE loader 312 313 #define VG_Z_LD_SO_1 ldZdsoZd1 // ld.so.1 314 #define VG_U_LD_SO_1 "ld.so.1" 315 316 #define VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1" 317 #define VG_U_LD_LINUX_ARMHF_SO_3 "ld-linux-armhf.so.3" 318 319 #endif 320 321 /* --- Executable name for Darwin Mach-O linker. --- */ 322 323 #if defined(VGO_darwin) 324 325 #define VG_Z_DYLD dyld // dyld 326 #define VG_U_DYLD "dyld" 327 328 #endif 329 330 /* --- Soname for Solaris run-time linker. --- */ 331 // Note: run-time linker contains absolute pathname in the SONAME. 332 333 #if defined(VGO_solaris) 334 335 #if defined(VGP_x86_solaris) 336 # define VG_Z_LD_SO_1 ZSlibZSldZdsoZd1 // /lib/ld.so.1 337 # define VG_U_LD_SO_1 "/lib/ld.so.1" 338 #elif defined(VGP_amd64_solaris) 339 # define VG_Z_LD_SO_1 ZSlibZSamd64ZSldZdsoZd1 // /lib/amd64/ld.so.1 340 # define VG_U_LD_SO_1 "/lib/amd64/ld.so.1" 341 #else 342 # error "Unknown platform" 343 #endif 344 345 /* --- Soname for Solaris libumem allocation interposition. --- */ 346 347 #define VG_Z_LIBUMEM_SO_1 libumemZdsoZd1 // libumem.so.1 348 #define VG_U_LIBUMEM_SO_1 "libumem.so.1" 349 350 #endif 351 352 // Prefix for synonym soname synonym handling 353 #define VG_SO_SYN(name) VgSoSyn##name 354 #define VG_SO_SYN_PREFIX "VgSoSyn" 355 #define VG_SO_SYN_PREFIX_LEN 7 356 357 // Special soname synonym place holder for the malloc symbols that can 358 // be replaced using --soname-synonyms. Otherwise will match all 359 // public symbols in any shared library/executable. 360 #define SO_SYN_MALLOC VG_SO_SYN(somalloc) 361 #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc" 362 363 Bool VG_(is_soname_ld_so) (const HChar *soname); 364 365 #endif // __PUB_TOOL_REDIR_H 366 367 /*--------------------------------------------------------------------*/ 368 /*--- end ---*/ 369 /*--------------------------------------------------------------------*/ 370