Home | History | Annotate | Download | only in include
      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