Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:31

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 2 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) && (DARWIN_VERS <= DARWIN_10_6)
0251 #  define  VG_Z_LIBC_SONAME  libSystemZdZaZddylib    // libSystem.*.dylib
0252 
0253 #elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \
0254                               || 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 
0264 #elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9)
0265 #  define  VG_Z_LIBC_SONAME  libsystemZumallocZddylib  // libsystem_malloc.dylib
0266 
0267 #else
0268 #  error "Unknown platform"
0269 
0270 #endif
0271 
0272 /* --- Sonames of the GNU C++ library. --- */
0273 
0274 // Valid on all platforms(?)
0275 #define  VG_Z_LIBSTDCXX_SONAME  libstdcZpZpZa           // libstdc++*
0276 
0277 /* --- Soname of the clang C++ library. --- */
0278 
0279 #define  VG_Z_LIBCXX_SONAME     libcZpZpZa              // libc++*
0280 
0281 
0282 /* --- Soname of the pthreads library. --- */
0283 
0284 #if defined(VGO_linux)
0285 #  define  VG_Z_LIBPTHREAD_SONAME  libpthreadZdsoZd0     // libpthread.so.0
0286 #elif defined(VGO_freebsd)
0287 #  define  VG_Z_LIBPTHREAD_SONAME  libthrZdsoZa          // libthr.so*
0288 #elif defined(VGO_darwin)
0289 #  define  VG_Z_LIBPTHREAD_SONAME  libSystemZdZaZddylib  // libSystem.*.dylib
0290 #elif defined(VGO_solaris)
0291 #  define  VG_Z_LIBPTHREAD_SONAME  libpthreadZdsoZd1     // libpthread.so.1
0292 #else
0293 #  error "Unknown platform"
0294 #endif
0295 
0296 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */
0297 
0298 #if defined(VGO_linux)
0299 
0300 #define  VG_Z_LD_LINUX_SO_3         ldZhlinuxZdsoZd3           // ld-linux.so.3
0301 #define  VG_U_LD_LINUX_SO_3         "ld-linux.so.3"
0302 
0303 #define  VG_Z_LD_LINUX_SO_2         ldZhlinuxZdsoZd2           // ld-linux.so.2
0304 #define  VG_U_LD_LINUX_SO_2         "ld-linux.so.2"
0305 
0306 #define  VG_Z_LD_LINUX_X86_64_SO_2  ldZhlinuxZhx86Zh64ZdsoZd2
0307                                                         // ld-linux-x86-64.so.2
0308 #define  VG_U_LD_LINUX_X86_64_SO_2  "ld-linux-x86-64.so.2"
0309 
0310 #define  VG_Z_LD64_SO_1             ld64ZdsoZd1                // ld64.so.1
0311 #define  VG_U_LD64_SO_1             "ld64.so.1"
0312 #define  VG_U_LD64_SO_2             "ld64.so.2"                // PPC LE loader
0313 
0314 #define  VG_Z_LD_SO_1               ldZdsoZd1                  // ld.so.1
0315 #define  VG_U_LD_SO_1               "ld.so.1"
0316 
0317 #define  VG_Z_LD_LINUX_AARCH64_SO_1  ldZhlinuxZhaarch64ZdsoZd1
0318 #define  VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1"
0319 
0320 #define  VG_U_LD_LINUX_ARMHF_SO_3   "ld-linux-armhf.so.3"
0321 
0322 #define  VG_U_LD_LINUX_MIPSN8_S0_1  "ld-linux-mipsn8.so.1"
0323 
0324 #endif
0325 
0326 /* --- Sonames for FreeBSD ELF linkers, plus unencoded versions. --- */
0327 
0328 #if defined(VGO_freebsd)
0329 
0330 #define  VG_Z_LD_ELF_SO_1           ldZhelfZdsoZd1           // ld-elf.so.1
0331 #define  VG_U_LD_ELF_SO_1           "ld-elf.so.1"
0332 
0333 #define  VG_Z_LD_ELF32_SO_1         ldZhelf32ZdsoZd1         // ld-elf32.so.1
0334 #define  VG_U_LD_ELF32_SO_1         "ld-elf32.so.1"
0335 
0336 #endif
0337 
0338 /* --- Executable name for Darwin Mach-O linker. --- */
0339 
0340 #if defined(VGO_darwin)
0341 
0342 #define  VG_Z_DYLD               dyld                       // dyld
0343 #define  VG_U_DYLD               "dyld"
0344 
0345 #endif
0346 
0347 /* --- Soname for Solaris run-time linker. --- */
0348 // Note: run-time linker contains absolute pathname in the SONAME.
0349 
0350 #if defined(VGO_solaris)
0351 
0352 #if defined(VGP_x86_solaris)
0353 #  define  VG_Z_LD_SO_1           ZSlibZSldZdsoZd1         // /lib/ld.so.1
0354 #  define  VG_U_LD_SO_1           "/lib/ld.so.1"
0355 #elif defined(VGP_amd64_solaris)
0356 #  define  VG_Z_LD_SO_1           ZSlibZSamd64ZSldZdsoZd1  // /lib/amd64/ld.so.1
0357 #  define  VG_U_LD_SO_1           "/lib/amd64/ld.so.1"
0358 #else
0359 #  error "Unknown platform"
0360 #endif
0361 
0362 /* --- Soname for Solaris libumem allocation interposition. --- */
0363 
0364 #define  VG_Z_LIBUMEM_SO_1          libumemZdsoZd1             // libumem.so.1
0365 #define  VG_U_LIBUMEM_SO_1          "libumem.so.1"
0366 
0367 #endif
0368 
0369 // Prefix for synonym soname synonym handling
0370 #define VG_SO_SYN(name)       VgSoSyn##name
0371 #define VG_SO_SYN_PREFIX     "VgSoSyn"
0372 #define VG_SO_SYN_PREFIX_LEN 7
0373 
0374 // Special soname synonym place holder for the malloc symbols that can
0375 // be replaced using --soname-synonyms.  Otherwise will match all
0376 // public symbols in any shared library/executable.
0377 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
0378 #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc"
0379 
0380 Bool VG_(is_soname_ld_so) (const HChar *soname);
0381 
0382 // Some macros to help decide which libraries (libc or libpthread
0383 // or some platform-specific variation of these) should be used
0384 // for wrapping pthread/semaphore functions with DRD and Helgrind
0385 // The possibilities are
0386 // a) only in libpthread
0387 // b) mabye in both libpthread and libc or
0388 // c) only in libc
0389 
0390 // Linux GNU libc is moving from a) to c)
0391 // Fedora 33 has pthread functions in both libc and libpthread
0392 // and at least glibc 2.32 (Fedora 34) has an implementation of all pthread
0393 // functions in both libc and libpthread. Older glibc versions only have an
0394 // implementation of the pthread functions in libpthread.
0395 
0396 // Linux MUSL libc is c) it provides a single library that includes
0397 // pthreads functions.
0398 
0399 // Darwin is a)
0400 
0401 // Solaris is c) libpthread is just a filter library on top of libc.
0402 // Threading and synchronization functions in runtime linker are not
0403 // intercepted.
0404 
0405 // FreeBSD is b) pthread functions are lin libthr but semaphore
0406 // functions are lin libc
0407 
0408 #if defined(VGO_darwin) || defined(VGO_freebsd)
0409 #define VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY
0410 #elif defined(VGO_solaris) || (defined(VGO_linux) && defined(MUSL_LIBC))
0411 #define VG_WRAP_THREAD_FUNCTION_LIBC_ONLY
0412 #elif defined(VGO_linux)
0413 #define VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD
0414 #else
0415 #  error "Unknown platform"
0416 #endif
0417 
0418 #endif   // __PUB_TOOL_REDIR_H
0419 
0420 /*--------------------------------------------------------------------*/
0421 /*--- end                                                          ---*/
0422 /*--------------------------------------------------------------------*/