|
|
|||
Warning, file /include/valgrind/pub_tool_redir.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 0002 /*--------------------------------------------------------------------*/ 0003 /*--- Redirections, etc. pub_tool_redir.h ---*/ 0004 /*--------------------------------------------------------------------*/ 0005 0006 /* 0007 This file is part of Valgrind, a dynamic binary instrumentation 0008 framework. 0009 0010 Copyright (C) 2000-2017 Julian Seward 0011 jseward@acm.org 0012 0013 This program is free software; you can redistribute it and/or 0014 modify it under the terms of the GNU General Public License as 0015 published by the Free Software Foundation; either version 3 of the 0016 License, or (at your option) any later version. 0017 0018 This program is distributed in the hope that it will be useful, but 0019 WITHOUT ANY WARRANTY; without even the implied warranty of 0020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0021 General Public License for more details. 0022 0023 You should have received a copy of the GNU General Public License 0024 along with this program; if not, see <http://www.gnu.org/licenses/>. 0025 0026 The GNU General Public License is contained in the file COPYING. 0027 */ 0028 0029 #ifndef __PUB_TOOL_REDIR_H 0030 #define __PUB_TOOL_REDIR_H 0031 0032 #include "config.h" /* DARWIN_VERS */ 0033 #include "pub_tool_basics.h" // Bool and HChar 0034 0035 /* The following macros facilitate function replacement and wrapping. 0036 0037 Function wrapping and function replacement are similar but not 0038 identical. 0039 0040 A replacement for some function F simply diverts all calls to F 0041 to the stated replacement. There is no way to get back to F itself 0042 from the replacement. 0043 0044 A wrapper for a function F causes all calls to F to instead go to 0045 the wrapper. However, from inside the wrapper, it is possible 0046 (with some difficulty) to get to F itself. 0047 0048 You may notice that replacement is a special case of wrapping, in 0049 which the call to the original is omitted. For implementation 0050 reasons, though, it is important to use the following macros 0051 correctly: in particular, if you want to write a replacement, make 0052 sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_ 0053 macros. 0054 0055 Finally there is the concept of prioritised behavioural equivalence 0056 tags. A tag is a 5-digit decimal number (00000 to 99999) encoded 0057 in the name. The top 4 digits are the equivalence class number, 0058 and the last digit is a priority. 0059 0060 When processing redirections at library load time, if the set of 0061 available specifications yields more than one replacement or 0062 wrapper function for a given address, the system will try to 0063 resolve the situation by examining the tags on the 0064 replacements/wrappers. 0065 0066 If two replacement/wrapper functions have the same tag and 0067 priority, then the redirection machinery will assume they have 0068 identical behaviour and can choose between them arbitrarily. If 0069 they have the same tag but different priorities, then the one with 0070 higher priority will be chosen. If neither case holds, then the 0071 redirection is ambiguous and the system will ignore one of them 0072 arbitrarily, but print a warning when running at -v or above. 0073 0074 The tag is mandatory and must comprise 5 decimal digits. The tag 0075 00000 is special and means "does not have behaviour identical to any 0076 other replacement/wrapper function". Hence if you wish to write a 0077 wrap/replacement function that is not subject to the above 0078 resolution rules, use 00000 for the tag. Tags 00001 through 00009 0079 may not be used for any purpose. 0080 0081 0082 Replacement 0083 ~~~~~~~~~~~ 0084 To write a replacement function, do this: 0085 0086 ret_type 0087 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. ) 0088 { 0089 ... body ... 0090 } 0091 0092 zEncodedSoname should be a Z-encoded soname (see below for 0093 Z-encoding details) and fnname should be an unencoded fn name. A 0094 default-safe equivalence tag of 00000 is assumed (see comments 0095 above). The resulting name is 0096 0097 _vgr00000ZU_zEncodedSoname_fnname 0098 0099 The "_vgr00000ZU_" is a prefix that gets discarded upon decoding. 0100 It identifies this function as a replacement and specifies its 0101 equivalence tag. 0102 0103 It is also possible to write 0104 0105 ret_type 0106 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. ) 0107 { 0108 ... body ... 0109 } 0110 0111 which means precisely the same, but the function name is also 0112 Z-encoded. This can sometimes be necessary. In this case the 0113 resulting function name is 0114 0115 _vgr00000ZZ_zEncodedSoname_zEncodedFnname 0116 0117 When it sees this either such name, the core's symbol-table reading 0118 machinery and redirection machinery first Z-decode the soname and 0119 if necessary the fnname. They are encoded so that they may include 0120 arbitrary characters, and in particular they may contain '*', which 0121 acts as a wildcard. 0122 0123 They then will conspire to cause calls to any function matching 0124 'fnname' in any object whose soname matches 'soname' to actually be 0125 routed to this function. This is used in Valgrind to define dozens 0126 of replacements of malloc, free, etc. 0127 0128 The soname must be a Z-encoded bit of text because sonames can 0129 contain dots etc which are not valid symbol names. The function 0130 name may or may not be Z-encoded: to include wildcards it has to be, 0131 but Z-encoding C++ function names which are themselves already mangled 0132 using Zs in some way is tedious and error prone, so the _ZU variant 0133 allows them not to be Z-encoded. 0134 0135 Note that the soname "NONE" is specially interpreted to match any 0136 shared object which doesn't have a soname. 0137 0138 Note also that the replacement function should probably (must be?) in 0139 client space, so it runs on the simulated CPU. So it must be in 0140 either vgpreload_<tool>.so or vgpreload_core.so. It also only works 0141 with functions in shared objects, I think. 0142 0143 It is important that the Z-encoded names contain no unencoded 0144 underscores, since the intercept-handlers in m_redir.c detect the 0145 end of the soname by looking for the first trailing underscore. 0146 0147 To write function names which explicitly state the equivalence class 0148 tag, use 0149 VG_REPLACE_FUNCTION_EZU(5-digit-tag,zEncodedSoname,fnname) 0150 or 0151 VG_REPLACE_FUNCTION_EZZ(5-digit-tag,zEncodedSoname,zEncodedFnname) 0152 0153 As per comments above, the tag must be a 5 digit decimal number, 0154 padded with leading zeroes, in the range 00010 to 99999 inclusive. 0155 0156 0157 Wrapping 0158 ~~~~~~~~ 0159 This is identical to replacement, except that you should use the 0160 macro names 0161 0162 VG_WRAP_FUNCTION_ZU 0163 VG_WRAP_FUNCTION_ZZ 0164 VG_WRAP_FUNCTION_EZU 0165 VG_WRAP_FUNCTION_EZZ 0166 0167 instead. 0168 0169 Z-encoding 0170 ~~~~~~~~~~ 0171 Z-encoding details: the scheme is like GHC's. It is just about 0172 readable enough to make a preprocessor unnecessary. First the 0173 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following 0174 characters are transformed. 0175 0176 * --> Za (asterisk) 0177 : --> Zc (colon) 0178 . --> Zd (dot) 0179 - --> Zh (hyphen) 0180 + --> Zp (plus) 0181 (space) --> Zs (space) 0182 _ --> Zu (underscore) 0183 @ --> ZA (at) 0184 $ --> ZD (dollar) 0185 ( --> ZL (left) 0186 % --> ZP (percent) 0187 ) --> ZR (right) 0188 / --> ZS (slash) 0189 Z --> ZZ (Z) 0190 0191 Everything else is left unchanged. 0192 */ 0193 0194 /* If you change these, the code in VG_(maybe_Z_demangle) needs to be 0195 changed accordingly. NOTE: duplicates 0196 I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */ 0197 0198 /* Use an extra level of macroisation so as to ensure the soname/fnname 0199 args are fully macro-expanded before pasting them together. */ 0200 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd 0201 0202 #define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff 0203 0204 /* The 4 basic macros. */ 0205 #define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \ 0206 VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname) 0207 0208 #define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \ 0209 VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname) 0210 0211 #define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \ 0212 VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname) 0213 0214 #define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \ 0215 VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname) 0216 0217 /* Convenience macros defined in terms of the above 4. */ 0218 #define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \ 0219 VG_CONCAT6(_vgr,00000,ZU_,_soname,_,_fnname) 0220 0221 #define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \ 0222 VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname) 0223 0224 #define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \ 0225 VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname) 0226 0227 #define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \ 0228 VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname) 0229 0230 0231 /* --------- Some handy Z-encoded names. --------- */ 0232 0233 // Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_". Why? If we applied 0234 // conditional compilation inconsistently we could accidentally use an 0235 // undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded 0236 // name like "_vgrZU_VG_Z_LIBC_DOT_A_foo". This can't be detected at 0237 // compile-time, because both the constant's name and its value are 0238 // identifiers. However, by always using "VG_Z_" as a prefix, we can do a 0239 // run-time check and abort if any name has "VG_Z_" in it, because that 0240 // indicates that the constant has been used without being defined. 0241 0242 /* --- Soname of the standard C library. --- */ 0243 0244 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) 0245 # if defined(MUSL_LIBC) 0246 # define VG_Z_LIBC_SONAME libcZdZa // libc.* 0247 #else 0248 # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* 0249 #endif 0250 #elif defined(VGO_darwin) 0251 0252 #if (DARWIN_VERS <= DARWIN_10_6) 0253 # define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib 0254 #elif (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8) 0255 # define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib 0256 /* Note that the idea of a single name for the C library falls 0257 apart on more recent Darwins (10.8 and later) since the 0258 functionality (malloc, free, str*) is split between 0259 libsystem_c.dylib, libsystem_malloc.dylib and 0260 libsystem_platform.dylib. This makes VG_Z_LIBC_SONAME somewhat useless 0261 at least inside vg_replace_strmem.c, and that hardwires some dylib 0262 names directly, for OSX 10.9. */ 0263 #elif (DARWIN_VERS >= DARWIN_10_9) 0264 # define VG_Z_LIBC_SONAME libsystemZumallocZddylib // libsystem_malloc.dylib 0265 #endif 0266 0267 /* Not tested on systems older than OSX 10.13 */ 0268 #define VG_Z_LIBSYSTEM_C_SONAME libsystemZucZddylib 0269 #define VG_Z_LIBSYSTEM_PLATFORM_SONAME libsystemZuplatformZddylib 0270 #define VG_Z_LIBSYSTEM_KERNEL_SONAME libsystemZukernelZddylib 0271 0272 #else 0273 # error "Unknown platform" 0274 #endif 0275 0276 /* --- Sonames of the GNU C++ library. --- */ 0277 0278 // Valid on all platforms(?) 0279 #define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++* 0280 0281 /* --- Soname of the clang C++ library. --- */ 0282 0283 #define VG_Z_LIBCXX_SONAME libcZpZpZa // libc++* 0284 0285 0286 /* --- Soname of the pthreads library. --- */ 0287 0288 #if defined(VGO_linux) 0289 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 0290 #elif defined(VGO_freebsd) 0291 # define VG_Z_LIBPTHREAD_SONAME libthrZdsoZa // libthr.so* 0292 #elif defined(VGO_darwin) 0293 //# define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib 0294 # define VG_Z_LIBPTHREAD_SONAME libsystemZupthreadZddylib // libSystem.*.dylib 0295 #elif defined(VGO_solaris) 0296 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd1 // libpthread.so.1 0297 #else 0298 # error "Unknown platform" 0299 #endif 0300 0301 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */ 0302 0303 #if defined(VGO_linux) 0304 0305 #define VG_Z_LD_LINUX_SO_3 ldZhlinuxZdsoZd3 // ld-linux.so.3 0306 #define VG_U_LD_LINUX_SO_3 "ld-linux.so.3" 0307 0308 #define VG_Z_LD_LINUX_SO_2 ldZhlinuxZdsoZd2 // ld-linux.so.2 0309 #define VG_U_LD_LINUX_SO_2 "ld-linux.so.2" 0310 0311 #define VG_Z_LD_LINUX_X86_64_SO_2 ldZhlinuxZhx86Zh64ZdsoZd2 0312 // ld-linux-x86-64.so.2 0313 #define VG_U_LD_LINUX_X86_64_SO_2 "ld-linux-x86-64.so.2" 0314 0315 #define VG_Z_LD64_SO_1 ld64ZdsoZd1 // ld64.so.1 0316 #define VG_U_LD64_SO_1 "ld64.so.1" 0317 #define VG_U_LD64_SO_2 "ld64.so.2" // PPC LE loader 0318 0319 #define VG_Z_LD_SO_1 ldZdsoZd1 // ld.so.1 0320 #define VG_U_LD_SO_1 "ld.so.1" 0321 0322 #define VG_Z_LD_LINUX_AARCH64_SO_1 ldZhlinuxZhaarch64ZdsoZd1 0323 #define VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1" 0324 0325 #define VG_U_LD_LINUX_ARMHF_SO_3 "ld-linux-armhf.so.3" 0326 0327 #define VG_U_LD_LINUX_MIPSN8_S0_1 "ld-linux-mipsn8.so.1" 0328 0329 #define VG_U_LD_LINUX_RISCV64_SO_1 "ld-linux-riscv64-lp64d.so.1" 0330 0331 #endif 0332 0333 /* --- Sonames for FreeBSD ELF linkers, plus unencoded versions. --- */ 0334 0335 #if defined(VGO_freebsd) 0336 0337 #define VG_Z_LD_ELF_SO_1 ldZhelfZdsoZd1 // ld-elf.so.1 0338 #define VG_U_LD_ELF_SO_1 "ld-elf.so.1" 0339 0340 #define VG_Z_LD_ELF32_SO_1 ldZhelf32ZdsoZd1 // ld-elf32.so.1 0341 #define VG_U_LD_ELF32_SO_1 "ld-elf32.so.1" 0342 0343 #endif 0344 0345 /* --- Executable name for Darwin Mach-O linker. --- */ 0346 0347 #if defined(VGO_darwin) 0348 0349 #define VG_Z_DYLD dyld // dyld 0350 #define VG_U_DYLD "dyld" 0351 0352 #endif 0353 0354 /* --- Soname for Solaris run-time linker. --- */ 0355 // Note: run-time linker contains absolute pathname in the SONAME. 0356 0357 #if defined(VGO_solaris) 0358 0359 #if defined(VGP_x86_solaris) 0360 # define VG_Z_LD_SO_1 ZSlibZSldZdsoZd1 // /lib/ld.so.1 0361 # define VG_U_LD_SO_1 "/lib/ld.so.1" 0362 #elif defined(VGP_amd64_solaris) 0363 # define VG_Z_LD_SO_1 ZSlibZSamd64ZSldZdsoZd1 // /lib/amd64/ld.so.1 0364 # define VG_U_LD_SO_1 "/lib/amd64/ld.so.1" 0365 #else 0366 # error "Unknown platform" 0367 #endif 0368 0369 /* --- Soname for Solaris libumem allocation interposition. --- */ 0370 0371 #define VG_Z_LIBUMEM_SO_1 libumemZdsoZd1 // libumem.so.1 0372 #define VG_U_LIBUMEM_SO_1 "libumem.so.1" 0373 0374 #endif 0375 0376 // Prefix for synonym soname synonym handling 0377 #define VG_SO_SYN(name) VgSoSyn##name 0378 #define VG_SO_SYN_PREFIX "VgSoSyn" 0379 #define VG_SO_SYN_PREFIX_LEN 7 0380 0381 // Special soname synonym place holder for the malloc symbols that can 0382 // be replaced using --soname-synonyms. Otherwise will match all 0383 // public symbols in any shared library/executable. 0384 #define SO_SYN_MALLOC VG_SO_SYN(somalloc) 0385 #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc" 0386 0387 Bool VG_(is_soname_ld_so) (const HChar *soname); 0388 0389 // Some macros to help decide which libraries (libc or libpthread 0390 // or some platform-specific variation of these) should be used 0391 // for wrapping pthread/semaphore functions with DRD and Helgrind 0392 // The possibilities are 0393 // a) only in libpthread 0394 // b) mabye in both libpthread and libc or 0395 // c) only in libc 0396 0397 // Linux GNU libc is moving from a) to c) 0398 // Fedora 33 has pthread functions in both libc and libpthread 0399 // and at least glibc 2.32 (Fedora 34) has an implementation of all pthread 0400 // functions in both libc and libpthread. Older glibc versions only have an 0401 // implementation of the pthread functions in libpthread. 0402 0403 // Linux MUSL libc is c) it provides a single library that includes 0404 // pthreads functions. 0405 0406 // Darwin is a) 0407 0408 // Solaris is c) libpthread is just a filter library on top of libc. 0409 // Threading and synchronization functions in runtime linker are not 0410 // intercepted. 0411 0412 // FreeBSD is b) pthread functions are lin libthr but semaphore 0413 // functions are lin libc 0414 0415 #if defined(VGO_darwin) || defined(VGO_freebsd) 0416 #define VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY 0417 #elif defined(VGO_solaris) || (defined(VGO_linux) && defined(MUSL_LIBC)) 0418 #define VG_WRAP_THREAD_FUNCTION_LIBC_ONLY 0419 #elif defined(VGO_linux) 0420 #define VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD 0421 #else 0422 # error "Unknown platform" 0423 #endif 0424 0425 #endif // __PUB_TOOL_REDIR_H 0426 0427 /*--------------------------------------------------------------------*/ 0428 /*--- end ---*/ 0429 /*--------------------------------------------------------------------*/
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|