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-2015 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 #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