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