Home | History | Annotate | Download | only in exp-sgcheck
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Ptrcheck: a pointer-use checker.             pc_intercepts.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Ptrcheck, a Valgrind tool for checking pointer
      8    use in programs.
      9 
     10    Copyright (C) 2003-2011 Nicholas Nethercote
     11       njn (at) valgrind.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 /* Nothing actually in here.  However it appears this file is needed
     32    to make malloc intercepting work. (jrs, 2 july 08 -- not sure about
     33    that).
     34 */
     35 
     36 #include "pub_tool_basics.h"
     37 #include "pub_tool_hashtable.h"
     38 #include "pub_tool_redir.h"
     39 #include "pub_tool_tooliface.h"
     40 #include "valgrind.h"
     41 
     42 
     43 /* The following intercepts are copied verbatim from
     44    memcheck/mc_replace_strmem.c.  If you copy more in, please keep
     45    them in the same order as in mc_replace_strmem.c. */
     46 
     47 
     48 #define STRRCHR(soname, fnname) \
     49    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \
     50    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \
     51    { \
     52       UChar  ch   = (UChar)((UInt)c); \
     53       UChar* p    = (UChar*)s; \
     54       UChar* last = NULL; \
     55       while (True) { \
     56          if (*p == ch) last = p; \
     57          if (*p == 0) return last; \
     58          p++; \
     59       } \
     60    }
     61 
     62 // Apparently rindex() is the same thing as strrchr()
     63 STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
     64 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
     65 #if defined(VGO_linux)
     66 STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
     67 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
     68 #elif defined(VGO_darwin)
     69 STRRCHR(VG_Z_DYLD,          strrchr)
     70 STRRCHR(VG_Z_DYLD,          rindex)
     71 #endif
     72 
     73 
     74 #define STRCHR(soname, fnname) \
     75    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
     76    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
     77    { \
     78       UChar  ch = (UChar)((UInt)c); \
     79       UChar* p  = (UChar*)s; \
     80       while (True) { \
     81          if (*p == ch) return p; \
     82          if (*p == 0) return NULL; \
     83          p++; \
     84       } \
     85    }
     86 
     87 // Apparently index() is the same thing as strchr()
     88 STRCHR(VG_Z_LIBC_SONAME,          strchr)
     89 STRCHR(VG_Z_LIBC_SONAME,          index)
     90 #if defined(VGO_linux)
     91 STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
     92 STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
     93 STRCHR(VG_Z_LD_LINUX_SO_2,        index)
     94 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
     95 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
     96 #elif defined(VGO_darwin)
     97 STRCHR(VG_Z_DYLD,                 strchr)
     98 STRCHR(VG_Z_DYLD,                 index)
     99 #endif
    100 
    101 
    102 #define STRNLEN(soname, fnname) \
    103    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
    104    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
    105    { \
    106       SizeT i = 0; \
    107       while (i < n && str[i] != 0) i++; \
    108       return i; \
    109    }
    110 
    111 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
    112 
    113 
    114 // Note that this replacement often doesn't get used because gcc inlines
    115 // calls to strlen() with its own built-in version.  This can be very
    116 // confusing if you aren't expecting it.  Other small functions in this file
    117 // may also be inline by gcc.
    118 #define STRLEN(soname, fnname) \
    119    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
    120    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
    121    { \
    122       SizeT i = 0; \
    123       while (str[i] != 0) i++; \
    124       return i; \
    125    }
    126 
    127 STRLEN(VG_Z_LIBC_SONAME,          strlen)
    128 #if defined(VGO_linux)
    129 STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
    130 STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
    131 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
    132 STRLEN(VG_Z_LD_SO_1,              strlen)
    133 #endif
    134 
    135 
    136 #define STRCPY(soname, fnname) \
    137    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
    138    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
    139    { \
    140       Char* dst_orig = dst; \
    141       \
    142       while (*src) *dst++ = *src++; \
    143       *dst = 0; \
    144       \
    145       return dst_orig; \
    146    }
    147 
    148 STRCPY(VG_Z_LIBC_SONAME, strcpy)
    149 #if defined(VGO_linux)
    150 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
    151 #elif defined(VGO_darwin)
    152 STRCPY(VG_Z_DYLD,        strcpy)
    153 #endif
    154 
    155 
    156 #define STRNCMP(soname, fnname) \
    157    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    158           ( const char* s1, const char* s2, SizeT nmax ); \
    159    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    160           ( const char* s1, const char* s2, SizeT nmax ) \
    161    { \
    162       SizeT n = 0; \
    163       while (True) { \
    164          if (n >= nmax) return 0; \
    165          if (*s1 == 0 && *s2 == 0) return 0; \
    166          if (*s1 == 0) return -1; \
    167          if (*s2 == 0) return 1; \
    168          \
    169          if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
    170          if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
    171          \
    172          s1++; s2++; n++; \
    173       } \
    174    }
    175 
    176 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
    177 #if defined(VGO_linux)
    178 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
    179 #elif defined(VGO_darwin)
    180 STRNCMP(VG_Z_DYLD,        strncmp)
    181 #endif
    182 
    183 
    184 #define STRCMP(soname, fnname) \
    185    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    186           ( const char* s1, const char* s2 ); \
    187    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    188           ( const char* s1, const char* s2 ) \
    189    { \
    190       register unsigned char c1; \
    191       register unsigned char c2; \
    192       while (True) { \
    193          c1 = *(unsigned char *)s1; \
    194          c2 = *(unsigned char *)s2; \
    195          if (c1 != c2) break; \
    196          if (c1 == 0) break; \
    197          s1++; s2++; \
    198       } \
    199       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    200       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    201       return 0; \
    202    }
    203 
    204 STRCMP(VG_Z_LIBC_SONAME,          strcmp)
    205 #if defined(VGO_linux)
    206 STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
    207 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
    208 STRCMP(VG_Z_LD64_SO_1,            strcmp)
    209 #endif
    210 
    211 
    212 #define MEMCHR(soname, fnname) \
    213    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
    214    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \
    215    { \
    216       SizeT i; \
    217       UChar c0 = (UChar)c; \
    218       UChar* p = (UChar*)s; \
    219       for (i = 0; i < n; i++) \
    220          if (p[i] == c0) return (void*)(&p[i]); \
    221       return NULL; \
    222    }
    223 
    224 MEMCHR(VG_Z_LIBC_SONAME, memchr)
    225 #if defined(VGO_darwin)
    226 MEMCHR(VG_Z_DYLD,        memchr)
    227 #endif
    228 
    229 
    230 #define MEMCPY(soname, fnname) \
    231    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    232             ( void *dst, const void *src, SizeT sz ); \
    233    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    234             ( void *dest, const void *src, SizeT sz ) \
    235    { \
    236    const UChar*  s  = (const UChar*)src; \
    237          UChar*  d  =       (UChar*)dest; \
    238    const UWord*  sW = (const UWord*)src; \
    239          UWord*  dW =       (UWord*)dest; \
    240    const UWord   al = sizeof(UWord)-1; \
    241    \
    242    if (0 == (((UWord)dW) & al) && 0 == (((UWord)sW) & al)) { \
    243       while (sz >= 4 * sizeof(UWord)) { \
    244          dW[0] = sW[0]; \
    245          dW[1] = sW[1]; \
    246          dW[2] = sW[2]; \
    247          dW[3] = sW[3]; \
    248          sz -= 4 * sizeof(UWord); \
    249          dW += 4; \
    250          sW += 4; \
    251       } \
    252       if (sz == 0) \
    253          return dest; \
    254       while (sz >= 1 * sizeof(UWord)) { \
    255          dW[0] = sW[0]; \
    256          sz -= 1 * sizeof(UWord); \
    257          dW += 1; \
    258          sW += 1; \
    259       } \
    260       if (sz == 0) \
    261          return dest; \
    262       s = (const UChar*)sW; \
    263       d = (UChar*)dW; \
    264    } \
    265    \
    266    while (sz--) \
    267       *d++ = *s++; \
    268    \
    269    return dest; \
    270    }
    271 
    272 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
    273 #if defined(VGO_linux)
    274 MEMCPY(VG_Z_LD_SO_1,     memcpy) /* ld.so.1 */
    275 MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64.so.1 */
    276 #endif
    277 
    278 
    279 /* Copy SRC to DEST, returning the address of the terminating '\0' in
    280    DEST. (minor variant of strcpy) */
    281 #define STPCPY(soname, fnname) \
    282    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
    283    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
    284    { \
    285       while (*src) *dst++ = *src++; \
    286       *dst = 0; \
    287       \
    288       return dst; \
    289    }
    290 
    291 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
    292 #if defined(VGO_linux)
    293 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
    294 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
    295 #endif
    296 
    297 
    298 /* Find the first occurrence of C in S.  */
    299 #define GLIBC232_RAWMEMCHR(soname, fnname) \
    300    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
    301    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
    302    { \
    303       unsigned char  c        = (unsigned char) c_in; \
    304       unsigned char* char_ptr = (unsigned char *)s; \
    305       while (1) { \
    306          if (*char_ptr == c) return char_ptr; \
    307          char_ptr++; \
    308       } \
    309    }
    310 
    311 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
    312 #if defined (VGO_linux)
    313 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
    314 #endif
    315 
    316 
    317 #define STRSTR(soname, fnname) \
    318    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    319          (void* haystack, void* needle); \
    320    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    321          (void* haystack, void* needle) \
    322    { \
    323       UChar* h = (UChar*)haystack; \
    324       UChar* n = (UChar*)needle; \
    325       \
    326       /* find the length of n, not including terminating zero */ \
    327       UWord nlen = 0; \
    328       while (n[nlen]) nlen++; \
    329       \
    330       /* if n is the empty string, match immediately. */ \
    331       if (nlen == 0) return h; \
    332       \
    333       /* assert(nlen >= 1); */ \
    334       UChar n0 = n[0]; \
    335       \
    336       while (1) { \
    337          UChar hh = *h; \
    338          if (hh == 0) return NULL; \
    339          if (hh != n0) { h++; continue; } \
    340          \
    341          UWord i; \
    342          for (i = 0; i < nlen; i++) { \
    343             if (n[i] != h[i]) \
    344                break; \
    345          } \
    346          /* assert(i >= 0 && i <= nlen); */ \
    347          if (i == nlen) \
    348             return h; \
    349          \
    350          h++; \
    351       } \
    352    }
    353 
    354 #if defined(VGO_linux)
    355 STRSTR(VG_Z_LIBC_SONAME,          strstr)
    356 #endif
    357 
    358 
    359 #define STRPBRK(soname, fnname) \
    360    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    361          (void* sV, void* acceptV); \
    362    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    363          (void* sV, void* acceptV) \
    364    { \
    365       UChar* s = (UChar*)sV; \
    366       UChar* accept = (UChar*)acceptV; \
    367       \
    368       /*  find the length of 'accept', not including terminating zero */ \
    369       UWord nacc = 0; \
    370       while (accept[nacc]) nacc++; \
    371       \
    372       /* if n is the empty string, fail immediately. */ \
    373       if (nacc == 0) return NULL; \
    374       \
    375       /* assert(nacc >= 1); */ \
    376       while (1) { \
    377          UWord i; \
    378          UChar sc = *s; \
    379          if (sc == 0) \
    380             break; \
    381          for (i = 0; i < nacc; i++) { \
    382             if (sc == accept[i]) \
    383                return s; \
    384          } \
    385          s++; \
    386       } \
    387       \
    388       return NULL; \
    389    }
    390 
    391 #if defined(VGO_linux)
    392 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
    393 #endif
    394 
    395 
    396 /*--------------------------------------------------------------------*/
    397 /*--- end                                          pc_intercepts.c ---*/
    398 /*--------------------------------------------------------------------*/
    399