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-2013 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 "pub_tool_clreq.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       HChar ch = (HChar)c;   \
     53       const HChar* p = s;       \
     54       const HChar* last = NULL; \
     55       while (True) { \
     56          if (*p == ch) last = p; \
     57          if (*p == 0) return (HChar *)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       HChar  ch = (HChar)c ; \
     79       const HChar* p  = s;   \
     80       while (True) { \
     81          if (*p == ch) return (HChar *)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       HChar* 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 (*(const unsigned char*)s1 < *(const unsigned char*)s2) return -1; \
    170          if (*(const unsigned char*)s1 > *(const 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 UChar c1; \
    191       register UChar c2; \
    192       while (True) { \
    193          c1 = *(const UChar *)s1; \
    194          c2 = *(const UChar *)s2; \
    195          if (c1 != c2) break; \
    196          if (c1 == 0) break; \
    197          s1++; s2++; \
    198       } \
    199       if ((UChar)c1 < (UChar)c2) return -1; \
    200       if ((UChar)c1 > (UChar)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       const UChar* p = (const 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 len ); \
    233    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    234             ( void *dst, const void *src, SizeT len ) \
    235    { \
    236       const Addr WS = sizeof(UWord); /* 8 or 4 */ \
    237       const Addr WM = WS - 1;        /* 7 or 3 */ \
    238       \
    239       if (len > 0) { \
    240          if (dst < src) { \
    241          \
    242             /* Copying backwards. */ \
    243             SizeT n = len; \
    244             Addr  d = (Addr)dst; \
    245             Addr  s = (Addr)src; \
    246             \
    247             if (((s^d) & WM) == 0) { \
    248                /* s and d have same UWord alignment. */ \
    249                /* Pull up to a UWord boundary. */ \
    250                while ((s & WM) != 0 && n >= 1) \
    251                   { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    252                /* Copy UWords. */ \
    253                while (n >= WS) \
    254                   { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
    255                if (n == 0) \
    256                   return dst; \
    257             } \
    258             if (((s|d) & 1) == 0) { \
    259                /* Both are 16-aligned; copy what we can thusly. */ \
    260                while (n >= 2) \
    261                   { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
    262             } \
    263             /* Copy leftovers, or everything if misaligned. */ \
    264             while (n >= 1) \
    265                { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    266          \
    267          } else if (dst > src) { \
    268          \
    269             SizeT n = len; \
    270             Addr  d = ((Addr)dst) + n; \
    271             Addr  s = ((Addr)src) + n; \
    272             \
    273             /* Copying forwards. */ \
    274             if (((s^d) & WM) == 0) { \
    275                /* s and d have same UWord alignment. */ \
    276                /* Back down to a UWord boundary. */ \
    277                while ((s & WM) != 0 && n >= 1) \
    278                   { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    279                /* Copy UWords. */ \
    280                while (n >= WS) \
    281                   { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
    282                if (n == 0) \
    283                   return dst; \
    284             } \
    285             if (((s|d) & 1) == 0) { \
    286                /* Both are 16-aligned; copy what we can thusly. */ \
    287                while (n >= 2) \
    288                   { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
    289             } \
    290             /* Copy leftovers, or everything if misaligned. */ \
    291             while (n >= 1) \
    292                { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    293             \
    294          } \
    295       } \
    296       \
    297       return dst; \
    298    }
    299 
    300 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
    301 #if defined(VGO_linux)
    302 MEMCPY(VG_Z_LD_SO_1,     memcpy) /* ld.so.1 */
    303 MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64.so.1 */
    304 #endif
    305 
    306 
    307 /* Copy SRC to DEST, returning the address of the terminating '\0' in
    308    DEST. (minor variant of strcpy) */
    309 #define STPCPY(soname, fnname) \
    310    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
    311    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
    312    { \
    313       while (*src) *dst++ = *src++; \
    314       *dst = 0; \
    315       \
    316       return dst; \
    317    }
    318 
    319 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
    320 #if defined(VGO_linux)
    321 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
    322 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
    323 #endif
    324 
    325 
    326 /* Find the first occurrence of C in S.  */
    327 #define GLIBC232_RAWMEMCHR(soname, fnname) \
    328    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void* s, int c_in); \
    329    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void* s, int c_in) \
    330    { \
    331       UChar c = (UChar)c_in; \
    332       const UChar* char_ptr = s; \
    333       while (1) { \
    334         if (*char_ptr == c) return (void *)char_ptr;    \
    335          char_ptr++; \
    336       } \
    337    }
    338 
    339 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
    340 #if defined (VGO_linux)
    341 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
    342 #endif
    343 
    344 
    345 #define STRSTR(soname, fnname) \
    346    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    347          (const char* haystack, const char* needle); \
    348    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    349          (const char* haystack, const char* needle) \
    350    { \
    351       const HChar* h = haystack; \
    352       const HChar* n = needle; \
    353       \
    354       /* find the length of n, not including terminating zero */ \
    355       UWord nlen = 0; \
    356       while (n[nlen]) nlen++; \
    357       \
    358       /* if n is the empty string, match immediately. */ \
    359       if (nlen == 0) return (HChar *)h;                  \
    360       \
    361       /* assert(nlen >= 1); */ \
    362       HChar n0 = n[0]; \
    363       \
    364       while (1) { \
    365          const HChar hh = *h; \
    366          if (hh == 0) return NULL; \
    367          if (hh != n0) { h++; continue; } \
    368          \
    369          UWord i; \
    370          for (i = 0; i < nlen; i++) { \
    371             if (n[i] != h[i]) \
    372                break; \
    373          } \
    374          /* assert(i >= 0 && i <= nlen); */ \
    375          if (i == nlen) \
    376            return (HChar *)h;                   \
    377          \
    378          h++; \
    379       } \
    380    }
    381 
    382 #if defined(VGO_linux)
    383 STRSTR(VG_Z_LIBC_SONAME,          strstr)
    384 #endif
    385 
    386 
    387 #define STRPBRK(soname, fnname) \
    388    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    389          (const char* sV, const char* acceptV); \
    390    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    391          (const char* sV, const char* acceptV) \
    392    { \
    393       const HChar* s = sV; \
    394       const HChar* accept = acceptV; \
    395       \
    396       /*  find the length of 'accept', not including terminating zero */ \
    397       UWord nacc = 0; \
    398       while (accept[nacc]) nacc++; \
    399       \
    400       /* if n is the empty string, fail immediately. */ \
    401       if (nacc == 0) return NULL; \
    402       \
    403       /* assert(nacc >= 1); */ \
    404       while (1) { \
    405          UWord i; \
    406          HChar sc = *s; \
    407          if (sc == 0) \
    408             break; \
    409          for (i = 0; i < nacc; i++) { \
    410             if (sc == accept[i]) \
    411               return (HChar *)s; \
    412          } \
    413          s++; \
    414       } \
    415       \
    416       return NULL; \
    417    }
    418 
    419 #if defined(VGO_linux)
    420 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
    421 #endif
    422 
    423 
    424 /*--------------------------------------------------------------------*/
    425 /*--- end                                          pc_intercepts.c ---*/
    426 /*--------------------------------------------------------------------*/
    427