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