Home | History | Annotate | Download | only in memcheck
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Replacements for strcpy(), memcpy() et al, which run on the  ---*/
      4 /*--- simulated CPU.                                               ---*/
      5 /*---                                          mc_replace_strmem.c ---*/
      6 /*--------------------------------------------------------------------*/
      7 
      8 /*
      9    This file is part of MemCheck, a heavyweight Valgrind tool for
     10    detecting memory errors.
     11 
     12    Copyright (C) 2000-2012 Julian Seward
     13       jseward (at) acm.org
     14 
     15    This program is free software; you can redistribute it and/or
     16    modify it under the terms of the GNU General Public License as
     17    published by the Free Software Foundation; either version 2 of the
     18    License, or (at your option) any later version.
     19 
     20    This program is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received a copy of the GNU General Public License
     26    along with this program; if not, write to the Free Software
     27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     28    02111-1307, USA.
     29 
     30    The GNU General Public License is contained in the file COPYING.
     31 */
     32 
     33 #include "pub_tool_basics.h"
     34 #include "pub_tool_poolalloc.h"
     35 #include "pub_tool_hashtable.h"
     36 #include "pub_tool_redir.h"
     37 #include "pub_tool_tooliface.h"
     38 #include "valgrind.h"
     39 
     40 #include "mc_include.h"
     41 #include "memcheck.h"
     42 
     43 /* ---------------------------------------------------------------------
     44    We have our own versions of these functions for two reasons:
     45    (a) it allows us to do overlap checking
     46    (b) some of the normal versions are hyper-optimised, which fools
     47        Memcheck and cause spurious value warnings.  Our versions are
     48        simpler.
     49 
     50    Note that overenthusiastic use of PLT bypassing by the glibc people also
     51    means that we need to patch multiple versions of some of the functions to
     52    our own implementations.
     53 
     54    THEY RUN ON THE SIMD CPU!
     55    ------------------------------------------------------------------ */
     56 
     57 /* Assignment of behavioural equivalence class tags: 2NNNP is intended
     58    to be reserved for Memcheck.  Current usage:
     59 
     60    20010 STRRCHR
     61    20020 STRCHR
     62    20030 STRCAT
     63    20040 STRNCAT
     64    20050 STRLCAT
     65    20060 STRNLEN
     66    20070 STRLEN
     67    20080 STRCPY
     68    20090 STRNCPY
     69    20100 STRLCPY
     70    20110 STRNCMP
     71    20120 STRCASECMP
     72    20130 STRNCASECMP
     73    20140 STRCASECMP_L
     74    20150 STRNCASECMP_L
     75    20160 STRCMP
     76    20170 MEMCHR
     77 
     78    20180 MEMCPY    if there's a conflict between memcpy and
     79    20181 MEMMOVE   memmove, prefer memmove
     80 
     81    20190 MEMCMP
     82    20200 STPCPY
     83    20210 MEMSET
     84    2022P unused (was previously MEMMOVE)
     85    20230 BCOPY
     86    20240 GLIBC25___MEMMOVE_CHK
     87    20250 GLIBC232_STRCHRNUL
     88    20260 GLIBC232_RAWMEMCHR
     89    20270 GLIBC25___STRCPY_CHK
     90    20280 GLIBC25___STPCPY_CHK
     91    20290 GLIBC25_MEMPCPY
     92    20300 GLIBC26___MEMCPY_CHK
     93    20310 STRSTR
     94    20320 STRPBRK
     95    20330 STRCSPN
     96    20340 STRSPN
     97    20350 STRCASESTR
     98    20360 MEMRCHR
     99    20370 WCSLEN
    100 */
    101 
    102 
    103 /* Figure out if [dst .. dst+dstlen-1] overlaps with
    104                  [src .. src+srclen-1].
    105    We assume that the address ranges do not wrap around
    106    (which is safe since on Linux addresses >= 0xC0000000
    107    are not accessible and the program will segfault in this
    108    circumstance, presumably).
    109 */
    110 static inline
    111 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
    112 {
    113    Addr loS, hiS, loD, hiD;
    114 
    115    if (dstlen == 0 || srclen == 0)
    116       return False;
    117 
    118    loS = (Addr)src;
    119    loD = (Addr)dst;
    120    hiS = loS + srclen - 1;
    121    hiD = loD + dstlen - 1;
    122 
    123    /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
    124    if (loS < loD) {
    125       return !(hiS < loD);
    126    }
    127    else if (loD < loS) {
    128       return !(hiD < loS);
    129    }
    130    else {
    131       /* They start at same place.  Since we know neither of them has
    132          zero length, they must overlap. */
    133       return True;
    134    }
    135 }
    136 
    137 
    138 /* Call here to exit if we can't continue.  On Android we can't call
    139    _exit for some reason, so we have to blunt-instrument it. */
    140 __attribute__ ((__noreturn__))
    141 static inline void my_exit ( int x )
    142 {
    143 #  if defined(VGPV_arm_linux_android)
    144    __asm__ __volatile__(".word 0xFFFFFFFF");
    145    while (1) {}
    146 #  elif defined(VGPV_x86_linux_android)
    147    __asm__ __volatile__("ud2");
    148    while (1) {}
    149 #  else
    150    extern __attribute__ ((__noreturn__)) void _exit(int status);
    151    _exit(x);
    152 #  endif
    153 }
    154 
    155 
    156 // This is a macro rather than a function because we don't want to have an
    157 // extra function in the stack trace.
    158 #define RECORD_OVERLAP_ERROR(s, src, dst, len)                  \
    159   VALGRIND_DO_CLIENT_REQUEST_STMT(                              \
    160                   _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR,   \
    161                   s, src, dst, len, 0)
    162 
    163 
    164 /*---------------------- strrchr ----------------------*/
    165 
    166 #define STRRCHR(soname, fnname) \
    167    char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
    168    char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
    169    { \
    170       UChar  ch   = (UChar)((UInt)c); \
    171       UChar* p    = (UChar*)s; \
    172       UChar* last = NULL; \
    173       while (True) { \
    174          if (*p == ch) last = p; \
    175          if (*p == 0) return last; \
    176          p++; \
    177       } \
    178    }
    179 
    180 // Apparently rindex() is the same thing as strrchr()
    181 #if defined(VGO_linux)
    182  STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
    183  STRRCHR(VG_Z_LIBC_SONAME,   rindex)
    184  STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
    185  STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
    186 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    187   STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
    188 #endif
    189 
    190 #elif defined(VGO_darwin)
    191  //STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
    192  //STRRCHR(VG_Z_LIBC_SONAME,   rindex)
    193  //STRRCHR(VG_Z_DYLD,          strrchr)
    194  //STRRCHR(VG_Z_DYLD,          rindex)
    195  STRRCHR(VG_Z_LIBC_SONAME, strrchr)
    196 
    197 #endif
    198 
    199 
    200 /*---------------------- strchr ----------------------*/
    201 
    202 #define STRCHR(soname, fnname) \
    203    char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
    204    char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
    205    { \
    206       UChar  ch = (UChar)((UInt)c); \
    207       UChar* p  = (UChar*)s; \
    208       while (True) { \
    209          if (*p == ch) return p; \
    210          if (*p == 0) return NULL; \
    211          p++; \
    212       } \
    213    }
    214 
    215 // Apparently index() is the same thing as strchr()
    216 #if defined(VGO_linux)
    217  STRCHR(VG_Z_LIBC_SONAME,          strchr)
    218  STRCHR(VG_Z_LIBC_SONAME,          index)
    219  STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
    220 # if !defined(VGP_x86_linux)
    221   STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
    222   STRCHR(VG_Z_LD_LINUX_SO_2,        index)
    223   STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
    224   STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
    225 # endif
    226 
    227 #elif defined(VGO_darwin)
    228  //STRCHR(VG_Z_LIBC_SONAME,          strchr)
    229  //STRCHR(VG_Z_LIBC_SONAME,          index)
    230  //STRCHR(VG_Z_DYLD,                 strchr)
    231  //STRCHR(VG_Z_DYLD,                 index)
    232  STRCHR(VG_Z_LIBC_SONAME, strchr)
    233 
    234 #endif
    235 
    236 
    237 /*---------------------- strcat ----------------------*/
    238 
    239 #define STRCAT(soname, fnname) \
    240    char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
    241             ( char* dst, const char* src ); \
    242    char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
    243             ( char* dst, const char* src ) \
    244    { \
    245       const Char* src_orig = src; \
    246             Char* dst_orig = dst; \
    247       while (*dst) dst++; \
    248       while (*src) *dst++ = *src++; \
    249       *dst = 0; \
    250       \
    251       /* This is a bit redundant, I think;  any overlap and the strcat will */ \
    252       /* go forever... or until a seg fault occurs. */ \
    253       if (is_overlap(dst_orig,  \
    254                      src_orig,  \
    255                      (Addr)dst-(Addr)dst_orig+1,  \
    256                      (Addr)src-(Addr)src_orig+1)) \
    257          RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
    258       \
    259       return dst_orig; \
    260    }
    261 
    262 #if defined(VGO_linux)
    263  STRCAT(VG_Z_LIBC_SONAME, strcat)
    264  STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
    265 
    266 #elif defined(VGO_darwin)
    267  //STRCAT(VG_Z_LIBC_SONAME, strcat)
    268 
    269 #endif
    270 
    271 
    272 /*---------------------- strncat ----------------------*/
    273 
    274 #define STRNCAT(soname, fnname) \
    275    char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
    276             ( char* dst, const char* src, SizeT n ); \
    277    char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
    278             ( char* dst, const char* src, SizeT n ) \
    279    { \
    280       const Char* src_orig = src; \
    281             Char* dst_orig = dst; \
    282       SizeT m = 0; \
    283       \
    284       while (*dst) dst++; \
    285       while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
    286       *dst = 0;                                       /* always add null   */ \
    287       \
    288       /* This checks for overlap after copying, unavoidable without */ \
    289       /* pre-counting lengths... should be ok */ \
    290       if (is_overlap(dst_orig,  \
    291                      src_orig,  \
    292                      (Addr)dst-(Addr)dst_orig+1, \
    293                      (Addr)src-(Addr)src_orig+1)) \
    294          RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
    295       \
    296       return dst_orig; \
    297    }
    298 
    299 #if defined(VGO_linux)
    300  STRNCAT(VG_Z_LIBC_SONAME, strncat)
    301 
    302 #elif defined(VGO_darwin)
    303  //STRNCAT(VG_Z_LIBC_SONAME, strncat)
    304  //STRNCAT(VG_Z_DYLD,        strncat)
    305 
    306 #endif
    307 
    308 
    309 /*---------------------- strlcat ----------------------*/
    310 
    311 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
    312    to be nul-terminated after the copy, unless n <= strlen(dst_orig).
    313    Returns min(n, strlen(dst_orig)) + strlen(src_orig).
    314    Truncation occurred if retval >= n.
    315 */
    316 #define STRLCAT(soname, fnname) \
    317    SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
    318         ( char* dst, const char* src, SizeT n ); \
    319    SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
    320         ( char* dst, const char* src, SizeT n ) \
    321    { \
    322       const Char* src_orig = src; \
    323       Char* dst_orig = dst; \
    324       SizeT m = 0; \
    325       \
    326       while (m < n && *dst) { m++; dst++; } \
    327       if (m < n) { \
    328          /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
    329          while (m < n-1 && *src) { m++; *dst++ = *src++; } \
    330          *dst = 0; \
    331       } else { \
    332          /* No space to copy anything to dst. m == n */ \
    333       } \
    334       /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
    335       while (*src) { m++; src++; } \
    336       /* This checks for overlap after copying, unavoidable without */ \
    337       /* pre-counting lengths... should be ok */ \
    338       if (is_overlap(dst_orig,  \
    339                      src_orig,  \
    340                      (Addr)dst-(Addr)dst_orig+1,  \
    341                      (Addr)src-(Addr)src_orig+1)) \
    342          RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
    343       \
    344       return m; \
    345    }
    346 
    347 #if defined(VGO_linux)
    348 
    349 #elif defined(VGO_darwin)
    350  //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
    351  //STRLCAT(VG_Z_DYLD,        strlcat)
    352  STRLCAT(VG_Z_LIBC_SONAME, strlcat)
    353 
    354 #endif
    355 
    356 
    357 /*---------------------- strnlen ----------------------*/
    358 
    359 #define STRNLEN(soname, fnname) \
    360    SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
    361             ( const char* str, SizeT n ); \
    362    SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
    363             ( const char* str, SizeT n ) \
    364    { \
    365       SizeT i = 0; \
    366       while (i < n && str[i] != 0) i++; \
    367       return i; \
    368    }
    369 
    370 #if defined(VGO_linux)
    371  STRNLEN(VG_Z_LIBC_SONAME, strnlen)
    372  STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
    373 
    374 #elif defined(VGO_darwin)
    375  //STRNLEN(VG_Z_LIBC_SONAME, strnlen)
    376 
    377 #endif
    378 
    379 
    380 /*---------------------- strlen ----------------------*/
    381 
    382 // Note that this replacement often doesn't get used because gcc inlines
    383 // calls to strlen() with its own built-in version.  This can be very
    384 // confusing if you aren't expecting it.  Other small functions in
    385 // this file may also be inline by gcc.
    386 
    387 #define STRLEN(soname, fnname) \
    388    SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
    389       ( const char* str ); \
    390    SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
    391       ( const char* str )  \
    392    { \
    393       SizeT i = 0; \
    394       while (str[i] != 0) i++; \
    395       return i; \
    396    }
    397 
    398 #if defined(VGO_linux)
    399  STRLEN(VG_Z_LIBC_SONAME,          strlen)
    400  STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
    401 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    402   STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
    403 # endif
    404 
    405 #elif defined(VGO_darwin)
    406  //STRLEN(VG_Z_LIBC_SONAME,          strlen)
    407  STRLEN(VG_Z_LIBC_SONAME, strlen)
    408 
    409 #endif
    410 
    411 
    412 /*---------------------- strcpy ----------------------*/
    413 
    414 #define STRCPY(soname, fnname) \
    415    char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
    416       ( char* dst, const char* src ); \
    417    char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
    418       ( char* dst, const char* src ) \
    419    { \
    420       const Char* src_orig = src; \
    421             Char* dst_orig = dst; \
    422       \
    423       while (*src) *dst++ = *src++; \
    424       *dst = 0; \
    425       \
    426       /* This checks for overlap after copying, unavoidable without */ \
    427       /* pre-counting length... should be ok */ \
    428       if (is_overlap(dst_orig,  \
    429                      src_orig,  \
    430                      (Addr)dst-(Addr)dst_orig+1, \
    431                      (Addr)src-(Addr)src_orig+1)) \
    432          RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
    433       \
    434       return dst_orig; \
    435    }
    436 
    437 #if defined(VGO_linux)
    438  STRCPY(VG_Z_LIBC_SONAME, strcpy)
    439  STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
    440 
    441 #elif defined(VGO_darwin)
    442  //STRCPY(VG_Z_LIBC_SONAME, strcpy)
    443  //STRCPY(VG_Z_DYLD,        strcpy)
    444  STRCPY(VG_Z_LIBC_SONAME, strcpy)
    445 
    446 #endif
    447 
    448 
    449 /*---------------------- strncpy ----------------------*/
    450 
    451 #define STRNCPY(soname, fnname) \
    452    char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
    453             ( char* dst, const char* src, SizeT n ); \
    454    char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
    455             ( char* dst, const char* src, SizeT n ) \
    456    { \
    457       const Char* src_orig = src; \
    458             Char* dst_orig = dst; \
    459       SizeT m = 0; \
    460       \
    461       while (m   < n && *src) { m++; *dst++ = *src++; } \
    462       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
    463       /* but only m+1 bytes of src if terminator was found */ \
    464       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
    465          RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
    466       while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
    467       \
    468       return dst_orig; \
    469    }
    470 
    471 #if defined(VGO_linux)
    472  STRNCPY(VG_Z_LIBC_SONAME, strncpy)
    473  STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
    474 
    475 #elif defined(VGO_darwin)
    476  //STRNCPY(VG_Z_LIBC_SONAME, strncpy)
    477  //STRNCPY(VG_Z_DYLD,        strncpy)
    478  STRNCPY(VG_Z_LIBC_SONAME, strncpy)
    479 
    480 #endif
    481 
    482 
    483 /*---------------------- strlcpy ----------------------*/
    484 
    485 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
    486    Returns strlen(src). Does not zero-fill the remainder of dst. */
    487 #define STRLCPY(soname, fnname) \
    488    SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
    489        ( char* dst, const char* src, SizeT n ); \
    490    SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
    491        ( char* dst, const char* src, SizeT n ) \
    492    { \
    493       const char* src_orig = src; \
    494       char* dst_orig = dst; \
    495       SizeT m = 0; \
    496       \
    497       while (m < n-1 && *src) { m++; *dst++ = *src++; } \
    498       /* m non-nul bytes have now been copied, and m <= n-1. */ \
    499       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
    500       /* but only m+1 bytes of src if terminator was found */ \
    501       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
    502           RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
    503       /* Nul-terminate dst. */ \
    504       if (n > 0) *dst = 0; \
    505       /* Finish counting strlen(src). */ \
    506       while (*src) src++; \
    507       return src - src_orig; \
    508    }
    509 
    510 #if defined(VGO_linux)
    511 
    512 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    513  STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
    514 #endif
    515 
    516 #elif defined(VGO_darwin)
    517  //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
    518  //STRLCPY(VG_Z_DYLD,        strlcpy)
    519  STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
    520 
    521 #endif
    522 
    523 
    524 /*---------------------- strncmp ----------------------*/
    525 
    526 #define STRNCMP(soname, fnname) \
    527    int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
    528           ( const char* s1, const char* s2, SizeT nmax ); \
    529    int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
    530           ( const char* s1, const char* s2, SizeT nmax ) \
    531    { \
    532       SizeT n = 0; \
    533       while (True) { \
    534          if (n >= nmax) return 0; \
    535          if (*s1 == 0 && *s2 == 0) return 0; \
    536          if (*s1 == 0) return -1; \
    537          if (*s2 == 0) return 1; \
    538          \
    539          if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
    540          if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
    541          \
    542          s1++; s2++; n++; \
    543       } \
    544    }
    545 
    546 #if defined(VGO_linux)
    547  STRNCMP(VG_Z_LIBC_SONAME, strncmp)
    548  STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
    549 
    550 #elif defined(VGO_darwin)
    551  //STRNCMP(VG_Z_LIBC_SONAME, strncmp)
    552  //STRNCMP(VG_Z_DYLD,        strncmp)
    553  STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
    554 
    555 #endif
    556 
    557 
    558 /*---------------------- strcasecmp ----------------------*/
    559 
    560 #define STRCASECMP(soname, fnname) \
    561    int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
    562           ( const char* s1, const char* s2 ); \
    563    int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
    564           ( const char* s1, const char* s2 ) \
    565    { \
    566       extern int tolower(int); \
    567       register unsigned char c1; \
    568       register unsigned char c2; \
    569       while (True) { \
    570          c1 = tolower(*(unsigned char *)s1); \
    571          c2 = tolower(*(unsigned char *)s2); \
    572          if (c1 != c2) break; \
    573          if (c1 == 0) break; \
    574          s1++; s2++; \
    575       } \
    576       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    577       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    578       return 0; \
    579    }
    580 
    581 #if defined(VGO_linux)
    582 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
    583   STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
    584   STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
    585 # endif
    586 
    587 #elif defined(VGO_darwin)
    588  //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
    589 
    590 #endif
    591 
    592 
    593 /*---------------------- strncasecmp ----------------------*/
    594 
    595 #define STRNCASECMP(soname, fnname) \
    596    int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
    597           ( const char* s1, const char* s2, SizeT nmax ); \
    598    int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
    599           ( const char* s1, const char* s2, SizeT nmax ) \
    600    { \
    601       extern int tolower(int); \
    602       SizeT n = 0; \
    603       while (True) { \
    604          if (n >= nmax) return 0; \
    605          if (*s1 == 0 && *s2 == 0) return 0; \
    606          if (*s1 == 0) return -1; \
    607          if (*s2 == 0) return 1; \
    608          \
    609          if (tolower(*(unsigned char*)s1) \
    610              < tolower(*(unsigned char*)s2)) return -1; \
    611          if (tolower(*(unsigned char*)s1) \
    612              > tolower(*(unsigned char*)s2)) return 1; \
    613          \
    614          s1++; s2++; n++; \
    615       } \
    616    }
    617 
    618 #if defined(VGO_linux)
    619 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
    620   STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
    621   STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
    622 # endif
    623 
    624 #elif defined(VGO_darwin)
    625  //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
    626  //STRNCASECMP(VG_Z_DYLD,        strncasecmp)
    627 
    628 #endif
    629 
    630 
    631 /*---------------------- strcasecmp_l ----------------------*/
    632 
    633 #define STRCASECMP_L(soname, fnname) \
    634    int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
    635           ( const char* s1, const char* s2, void* locale ); \
    636    int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
    637           ( const char* s1, const char* s2, void* locale ) \
    638    { \
    639       extern int tolower_l(int, void*) __attribute__((weak)); \
    640       register unsigned char c1; \
    641       register unsigned char c2; \
    642       while (True) { \
    643          c1 = tolower_l(*(unsigned char *)s1, locale); \
    644          c2 = tolower_l(*(unsigned char *)s2, locale); \
    645          if (c1 != c2) break; \
    646          if (c1 == 0) break; \
    647          s1++; s2++; \
    648       } \
    649       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    650       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    651       return 0; \
    652    }
    653 
    654 #if defined(VGO_linux)
    655  STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
    656  STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
    657  STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
    658 
    659 #elif defined(VGO_darwin)
    660  //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
    661 
    662 #endif
    663 
    664 
    665 /*---------------------- strncasecmp_l ----------------------*/
    666 
    667 #define STRNCASECMP_L(soname, fnname) \
    668    int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
    669           ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
    670    int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
    671           ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
    672    { \
    673       extern int tolower_l(int, void*) __attribute__((weak));    \
    674       SizeT n = 0; \
    675       while (True) { \
    676          if (n >= nmax) return 0; \
    677          if (*s1 == 0 && *s2 == 0) return 0; \
    678          if (*s1 == 0) return -1; \
    679          if (*s2 == 0) return 1; \
    680          \
    681          if (tolower_l(*(unsigned char*)s1, locale) \
    682              < tolower_l(*(unsigned char*)s2, locale)) return -1; \
    683          if (tolower_l(*(unsigned char*)s1, locale) \
    684              > tolower_l(*(unsigned char*)s2, locale)) return 1; \
    685          \
    686          s1++; s2++; n++; \
    687       } \
    688    }
    689 
    690 #if defined(VGO_linux)
    691  STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
    692  STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
    693  STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
    694 
    695 #elif defined(VGO_darwin)
    696  //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
    697  //STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
    698 
    699 #endif
    700 
    701 
    702 /*---------------------- strcmp ----------------------*/
    703 
    704 #define STRCMP(soname, fnname) \
    705    int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
    706           ( const char* s1, const char* s2 ); \
    707    int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
    708           ( const char* s1, const char* s2 ) \
    709    { \
    710       register unsigned char c1; \
    711       register unsigned char c2; \
    712       while (True) { \
    713          c1 = *(unsigned char *)s1; \
    714          c2 = *(unsigned char *)s2; \
    715          if (c1 != c2) break; \
    716          if (c1 == 0) break; \
    717          s1++; s2++; \
    718       } \
    719       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    720       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    721       return 0; \
    722    }
    723 
    724 #if defined(VGO_linux)
    725  STRCMP(VG_Z_LIBC_SONAME,          strcmp)
    726  STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
    727  STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
    728  STRCMP(VG_Z_LD64_SO_1,            strcmp)
    729 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    730   STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
    731 # endif
    732 
    733 #elif defined(VGO_darwin)
    734  //STRCMP(VG_Z_LIBC_SONAME,          strcmp)
    735  STRCMP(VG_Z_LIBC_SONAME, strcmp)
    736 
    737 #endif
    738 
    739 
    740 /*---------------------- memchr ----------------------*/
    741 
    742 #define MEMCHR(soname, fnname) \
    743    void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
    744             (const void *s, int c, SizeT n); \
    745    void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
    746             (const void *s, int c, SizeT n) \
    747    { \
    748       SizeT i; \
    749       UChar c0 = (UChar)c; \
    750       UChar* p = (UChar*)s; \
    751       for (i = 0; i < n; i++) \
    752          if (p[i] == c0) return (void*)(&p[i]); \
    753       return NULL; \
    754    }
    755 
    756 #if defined(VGO_linux)
    757  MEMCHR(VG_Z_LIBC_SONAME, memchr)
    758 
    759 #elif defined(VGO_darwin)
    760  //MEMCHR(VG_Z_LIBC_SONAME, memchr)
    761  //MEMCHR(VG_Z_DYLD,        memchr)
    762 
    763 #endif
    764 
    765 
    766 /*---------------------- memrchr ----------------------*/
    767 
    768 #define MEMRCHR(soname, fnname) \
    769    void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
    770             (const void *s, int c, SizeT n); \
    771    void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
    772             (const void *s, int c, SizeT n) \
    773    { \
    774       SizeT i; \
    775       UChar c0 = (UChar)c; \
    776       UChar* p = (UChar*)s; \
    777       for (i = 0; i < n; i++) \
    778          if (p[n-1-i] == c0) return (void*)(&p[n-1-i]); \
    779       return NULL; \
    780    }
    781 
    782 #if defined(VGO_linux)
    783  MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
    784 
    785 #elif defined(VGO_darwin)
    786  //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
    787  //MEMRCHR(VG_Z_DYLD,        memrchr)
    788 
    789 #endif
    790 
    791 
    792 /*---------------------- memcpy ----------------------*/
    793 
    794 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
    795    void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
    796             ( void *dst, const void *src, SizeT len ); \
    797    void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
    798             ( void *dst, const void *src, SizeT len ) \
    799    { \
    800       if (do_ol_check && is_overlap(dst, src, len, len)) \
    801          RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
    802       \
    803       const Addr WS = sizeof(UWord); /* 8 or 4 */ \
    804       const Addr WM = WS - 1;        /* 7 or 3 */ \
    805       \
    806       if (len > 0) { \
    807          if (dst < src) { \
    808          \
    809             /* Copying backwards. */ \
    810             SizeT n = len; \
    811             Addr  d = (Addr)dst; \
    812             Addr  s = (Addr)src; \
    813             \
    814             if (((s^d) & WM) == 0) { \
    815                /* s and d have same UWord alignment. */ \
    816                /* Pull up to a UWord boundary. */ \
    817                while ((s & WM) != 0 && n >= 1) \
    818                   { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    819                /* Copy UWords. */ \
    820                while (n >= WS) \
    821                   { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
    822                if (n == 0) \
    823                   return dst; \
    824             } \
    825             if (((s|d) & 1) == 0) { \
    826                /* Both are 16-aligned; copy what we can thusly. */ \
    827                while (n >= 2) \
    828                   { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
    829             } \
    830             /* Copy leftovers, or everything if misaligned. */ \
    831             while (n >= 1) \
    832                { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    833          \
    834          } else if (dst > src) { \
    835          \
    836             SizeT n = len; \
    837             Addr  d = ((Addr)dst) + n; \
    838             Addr  s = ((Addr)src) + n; \
    839             \
    840             /* Copying forwards. */ \
    841             if (((s^d) & WM) == 0) { \
    842                /* s and d have same UWord alignment. */ \
    843                /* Back down to a UWord boundary. */ \
    844                while ((s & WM) != 0 && n >= 1) \
    845                   { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    846                /* Copy UWords. */ \
    847                while (n >= WS) \
    848                   { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
    849                if (n == 0) \
    850                   return dst; \
    851             } \
    852             if (((s|d) & 1) == 0) { \
    853                /* Both are 16-aligned; copy what we can thusly. */ \
    854                while (n >= 2) \
    855                   { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
    856             } \
    857             /* Copy leftovers, or everything if misaligned. */ \
    858             while (n >= 1) \
    859                { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    860             \
    861          } \
    862       } \
    863       \
    864       return dst; \
    865    }
    866 
    867 #define MEMMOVE(soname, fnname)  \
    868    MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
    869 
    870 #define MEMCPY(soname, fnname) \
    871    MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
    872 
    873 #if defined(VGO_linux)
    874  /* For older memcpy we have to use memmove-like semantics and skip
    875     the overlap check; sigh; see #275284. */
    876  MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy (at) GLIBC_2.2.5 */
    877  MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
    878  MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
    879  MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
    880  MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
    881  /* icc9 blats these around all over the place.  Not only in the main
    882     executable but various .so's.  They are highly tuned and read
    883     memory beyond the source boundary (although work correctly and
    884     never go across page boundaries), so give errors when run
    885     natively, at least for misaligned source arg.  Just intercepting
    886     in the exe only until we understand more about the problem.  See
    887     http://bugs.kde.org/show_bug.cgi?id=139776
    888  */
    889  MEMCPY(NONE, ZuintelZufastZumemcpy)
    890 
    891 #elif defined(VGO_darwin)
    892 # if DARWIN_VERS <= DARWIN_10_6
    893   MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
    894 # endif
    895  MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
    896  MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
    897 
    898 #endif
    899 
    900 
    901 /*---------------------- memcmp ----------------------*/
    902 
    903 #define MEMCMP(soname, fnname) \
    904    int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
    905           ( const void *s1V, const void *s2V, SizeT n ); \
    906    int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
    907           ( const void *s1V, const void *s2V, SizeT n )  \
    908    { \
    909       int res; \
    910       unsigned char a0; \
    911       unsigned char b0; \
    912       unsigned char* s1 = (unsigned char*)s1V; \
    913       unsigned char* s2 = (unsigned char*)s2V; \
    914       \
    915       while (n != 0) { \
    916          a0 = s1[0]; \
    917          b0 = s2[0]; \
    918          s1 += 1; \
    919          s2 += 1; \
    920          res = ((int)a0) - ((int)b0); \
    921          if (res != 0) \
    922             return res; \
    923          n -= 1; \
    924       } \
    925       return 0; \
    926    }
    927 
    928 #if defined(VGO_linux)
    929  MEMCMP(VG_Z_LIBC_SONAME, memcmp)
    930  MEMCMP(VG_Z_LIBC_SONAME, bcmp)
    931  MEMCMP(VG_Z_LD_SO_1,     bcmp)
    932 
    933 #elif defined(VGO_darwin)
    934  //MEMCMP(VG_Z_LIBC_SONAME, memcmp)
    935  //MEMCMP(VG_Z_LIBC_SONAME, bcmp)
    936  //MEMCMP(VG_Z_DYLD,        memcmp)
    937  //MEMCMP(VG_Z_DYLD,        bcmp)
    938 
    939 #endif
    940 
    941 
    942 /*---------------------- stpcpy ----------------------*/
    943 
    944 /* Copy SRC to DEST, returning the address of the terminating '\0' in
    945    DEST. (minor variant of strcpy) */
    946 #define STPCPY(soname, fnname) \
    947    char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
    948             ( char* dst, const char* src ); \
    949    char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
    950             ( char* dst, const char* src ) \
    951    { \
    952       const Char* src_orig = src; \
    953             Char* dst_orig = dst; \
    954       \
    955       while (*src) *dst++ = *src++; \
    956       *dst = 0; \
    957       \
    958       /* This checks for overlap after copying, unavoidable without */ \
    959       /* pre-counting length... should be ok */ \
    960       if (is_overlap(dst_orig,  \
    961                      src_orig,  \
    962                      (Addr)dst-(Addr)dst_orig+1,  \
    963                      (Addr)src-(Addr)src_orig+1)) \
    964          RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
    965       \
    966       return dst; \
    967    }
    968 
    969 #if defined(VGO_linux)
    970  STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
    971  STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
    972  STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
    973  STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
    974 
    975 #elif defined(VGO_darwin)
    976  //STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
    977  //STPCPY(VG_Z_DYLD,                 stpcpy)
    978 
    979 #endif
    980 
    981 
    982 /*---------------------- memset ----------------------*/
    983 
    984 /* Why are we bothering to intercept this?  It seems entirely
    985    pointless. */
    986 
    987 #define MEMSET(soname, fnname) \
    988    void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
    989             (void *s, Int c, SizeT n); \
    990    void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
    991             (void *s, Int c, SizeT n) \
    992    { \
    993       Addr a  = (Addr)s;   \
    994       UInt c4 = (c & 0xFF); \
    995       c4 = (c4 << 8) | c4; \
    996       c4 = (c4 << 16) | c4; \
    997       while ((a & 3) != 0 && n >= 1) \
    998          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
    999       while (n >= 4) \
   1000          { *(UInt*)a = c4; a += 4; n -= 4; } \
   1001       while (n >= 1) \
   1002          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
   1003       return s; \
   1004    }
   1005 
   1006 #if defined(VGO_linux)
   1007  MEMSET(VG_Z_LIBC_SONAME, memset)
   1008 
   1009 #elif defined(VGO_darwin)
   1010  //MEMSET(VG_Z_LIBC_SONAME, memset)
   1011  //MEMSET(VG_Z_DYLD,        memset)
   1012  MEMSET(VG_Z_LIBC_SONAME, memset)
   1013 
   1014 #endif
   1015 
   1016 
   1017 /*---------------------- memmove ----------------------*/
   1018 
   1019 /* memmove -- use the MEMMOVE defn above. */
   1020 
   1021 #if defined(VGO_linux)
   1022  MEMMOVE(VG_Z_LIBC_SONAME, memmove)
   1023  MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
   1024 
   1025 #elif defined(VGO_darwin)
   1026 # if DARWIN_VERS <= DARWIN_10_6
   1027   MEMMOVE(VG_Z_LIBC_SONAME, memmove)
   1028 # endif
   1029  MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
   1030  MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
   1031 
   1032 #endif
   1033 
   1034 
   1035 /*---------------------- bcopy ----------------------*/
   1036 
   1037 #define BCOPY(soname, fnname) \
   1038    void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
   1039             (const void *srcV, void *dstV, SizeT n); \
   1040    void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
   1041             (const void *srcV, void *dstV, SizeT n) \
   1042    { \
   1043       SizeT i; \
   1044       Char* dst = (Char*)dstV; \
   1045       Char* src = (Char*)srcV; \
   1046       if (dst < src) { \
   1047          for (i = 0; i < n; i++) \
   1048             dst[i] = src[i]; \
   1049       } \
   1050       else  \
   1051       if (dst > src) { \
   1052          for (i = 0; i < n; i++) \
   1053             dst[n-i-1] = src[n-i-1]; \
   1054       } \
   1055    }
   1056 
   1057 #if defined(VGO_linux)
   1058 
   1059 #elif defined(VGO_darwin)
   1060  //BCOPY(VG_Z_LIBC_SONAME, bcopy)
   1061  //BCOPY(VG_Z_DYLD,        bcopy)
   1062 
   1063 #endif
   1064 
   1065 
   1066 /*-------------------- memmove_chk --------------------*/
   1067 
   1068 /* glibc 2.5 variant of memmove which checks the dest is big enough.
   1069    There is no specific part of glibc that this is copied from. */
   1070 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
   1071    void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
   1072             (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
   1073    void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
   1074             (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
   1075    { \
   1076       SizeT i; \
   1077       Char* dst = (Char*)dstV; \
   1078       Char* src = (Char*)srcV; \
   1079       if (destlen < n) \
   1080          goto badness; \
   1081       if (dst < src) { \
   1082          for (i = 0; i < n; i++) \
   1083             dst[i] = src[i]; \
   1084       } \
   1085       else  \
   1086       if (dst > src) { \
   1087          for (i = 0; i < n; i++) \
   1088             dst[n-i-1] = src[n-i-1]; \
   1089       } \
   1090       return dst; \
   1091      badness: \
   1092       VALGRIND_PRINTF_BACKTRACE( \
   1093          "*** memmove_chk: buffer overflow detected ***: " \
   1094          "program terminated\n"); \
   1095      my_exit(127); \
   1096      /*NOTREACHED*/ \
   1097      return NULL; \
   1098    }
   1099 
   1100 #if defined(VGO_linux)
   1101  GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
   1102 
   1103 #elif defined(VGO_darwin)
   1104 
   1105 #endif
   1106 
   1107 
   1108 /*-------------------- strchrnul --------------------*/
   1109 
   1110 /* Find the first occurrence of C in S or the final NUL byte.  */
   1111 #define GLIBC232_STRCHRNUL(soname, fnname) \
   1112    char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
   1113             (const char* s, int c_in); \
   1114    char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
   1115             (const char* s, int c_in) \
   1116    { \
   1117       unsigned char  c        = (unsigned char) c_in; \
   1118       unsigned char* char_ptr = (unsigned char *)s; \
   1119       while (1) { \
   1120          if (*char_ptr == 0) return char_ptr; \
   1121          if (*char_ptr == c) return char_ptr; \
   1122          char_ptr++; \
   1123       } \
   1124    }
   1125 
   1126 #if defined(VGO_linux)
   1127  GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
   1128 
   1129 #elif defined(VGO_darwin)
   1130 
   1131 #endif
   1132 
   1133 
   1134 /*---------------------- rawmemchr ----------------------*/
   1135 
   1136 /* Find the first occurrence of C in S.  */
   1137 #define GLIBC232_RAWMEMCHR(soname, fnname) \
   1138    char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
   1139             (const char* s, int c_in); \
   1140    char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
   1141             (const char* s, int c_in) \
   1142    { \
   1143       unsigned char  c        = (unsigned char) c_in; \
   1144       unsigned char* char_ptr = (unsigned char *)s; \
   1145       while (1) { \
   1146          if (*char_ptr == c) return char_ptr; \
   1147          char_ptr++; \
   1148       } \
   1149    }
   1150 
   1151 #if defined (VGO_linux)
   1152  GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
   1153  GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
   1154 
   1155 #elif defined(VGO_darwin)
   1156 
   1157 #endif
   1158 
   1159 
   1160 /*---------------------- strcpy_chk ----------------------*/
   1161 
   1162 /* glibc variant of strcpy that checks the dest is big enough.
   1163    Copied from glibc-2.5/debug/test-strcpy_chk.c. */
   1164 #define GLIBC25___STRCPY_CHK(soname,fnname) \
   1165    char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
   1166             (char* dst, const char* src, SizeT len); \
   1167    char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
   1168             (char* dst, const char* src, SizeT len) \
   1169    { \
   1170       char* ret = dst; \
   1171       if (! len) \
   1172          goto badness; \
   1173       while ((*dst++ = *src++) != '\0') \
   1174          if (--len == 0) \
   1175             goto badness; \
   1176       return ret; \
   1177      badness: \
   1178       VALGRIND_PRINTF_BACKTRACE( \
   1179          "*** strcpy_chk: buffer overflow detected ***: " \
   1180          "program terminated\n"); \
   1181      my_exit(127); \
   1182      /*NOTREACHED*/ \
   1183      return NULL; \
   1184    }
   1185 
   1186 #if defined(VGO_linux)
   1187  GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
   1188 
   1189 #elif defined(VGO_darwin)
   1190 
   1191 #endif
   1192 
   1193 
   1194 /*---------------------- stpcpy_chk ----------------------*/
   1195 
   1196 /* glibc variant of stpcpy that checks the dest is big enough.
   1197    Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
   1198 #define GLIBC25___STPCPY_CHK(soname,fnname) \
   1199    char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
   1200             (char* dst, const char* src, SizeT len); \
   1201    char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
   1202             (char* dst, const char* src, SizeT len) \
   1203    { \
   1204       if (! len) \
   1205          goto badness; \
   1206       while ((*dst++ = *src++) != '\0') \
   1207          if (--len == 0) \
   1208             goto badness; \
   1209       return dst - 1; \
   1210      badness: \
   1211       VALGRIND_PRINTF_BACKTRACE( \
   1212          "*** stpcpy_chk: buffer overflow detected ***: " \
   1213          "program terminated\n"); \
   1214      my_exit(127); \
   1215      /*NOTREACHED*/ \
   1216      return NULL; \
   1217    }
   1218 
   1219 #if defined(VGO_linux)
   1220  GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
   1221 
   1222 #elif defined(VGO_darwin)
   1223 
   1224 #endif
   1225 
   1226 
   1227 /*---------------------- mempcpy ----------------------*/
   1228 
   1229 /* mempcpy */
   1230 #define GLIBC25_MEMPCPY(soname, fnname) \
   1231    void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
   1232             ( void *dst, const void *src, SizeT len ); \
   1233    void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
   1234             ( void *dst, const void *src, SizeT len ) \
   1235    { \
   1236       register char *d; \
   1237       register char *s; \
   1238       SizeT len_saved = len; \
   1239       \
   1240       if (len == 0) \
   1241          return dst; \
   1242       \
   1243       if (is_overlap(dst, src, len, len)) \
   1244          RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
   1245       \
   1246       if ( dst > src ) { \
   1247          d = (char *)dst + len - 1; \
   1248          s = (char *)src + len - 1; \
   1249          while ( len-- ) { \
   1250             *d-- = *s--; \
   1251          } \
   1252       } else if ( dst < src ) { \
   1253          d = (char *)dst; \
   1254          s = (char *)src; \
   1255          while ( len-- ) { \
   1256             *d++ = *s++; \
   1257          } \
   1258       } \
   1259       return (void*)( ((char*)dst) + len_saved ); \
   1260    }
   1261 
   1262 #if defined(VGO_linux)
   1263  GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
   1264  GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
   1265 
   1266 #elif defined(VGO_darwin)
   1267  //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
   1268 
   1269 #endif
   1270 
   1271 
   1272 /*-------------------- memcpy_chk --------------------*/
   1273 
   1274 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
   1275    void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
   1276             (void* dst, const void* src, SizeT len, SizeT dstlen ); \
   1277    void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
   1278             (void* dst, const void* src, SizeT len, SizeT dstlen ) \
   1279    { \
   1280       register char *d; \
   1281       register char *s; \
   1282       \
   1283       if (dstlen < len) goto badness; \
   1284       \
   1285       if (len == 0) \
   1286          return dst; \
   1287       \
   1288       if (is_overlap(dst, src, len, len)) \
   1289          RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
   1290       \
   1291       if ( dst > src ) { \
   1292          d = (char *)dst + len - 1; \
   1293          s = (char *)src + len - 1; \
   1294          while ( len-- ) { \
   1295             *d-- = *s--; \
   1296          } \
   1297       } else if ( dst < src ) { \
   1298          d = (char *)dst; \
   1299          s = (char *)src; \
   1300          while ( len-- ) { \
   1301             *d++ = *s++; \
   1302          } \
   1303       } \
   1304       return dst; \
   1305      badness: \
   1306       VALGRIND_PRINTF_BACKTRACE( \
   1307          "*** memcpy_chk: buffer overflow detected ***: " \
   1308          "program terminated\n"); \
   1309      my_exit(127); \
   1310      /*NOTREACHED*/ \
   1311      return NULL; \
   1312    }
   1313 
   1314 #if defined(VGO_linux)
   1315  GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
   1316 
   1317 #elif defined(VGO_darwin)
   1318 
   1319 #endif
   1320 
   1321 
   1322 /*---------------------- strstr ----------------------*/
   1323 
   1324 #define STRSTR(soname, fnname) \
   1325    void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
   1326          (void* haystack, void* needle); \
   1327    void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
   1328          (void* haystack, void* needle) \
   1329    { \
   1330       UChar* h = (UChar*)haystack; \
   1331       UChar* n = (UChar*)needle; \
   1332       \
   1333       /* find the length of n, not including terminating zero */ \
   1334       UWord nlen = 0; \
   1335       while (n[nlen]) nlen++; \
   1336       \
   1337       /* if n is the empty string, match immediately. */ \
   1338       if (nlen == 0) return h; \
   1339       \
   1340       /* assert(nlen >= 1); */ \
   1341       UChar n0 = n[0]; \
   1342       \
   1343       while (1) { \
   1344          UChar hh = *h; \
   1345          if (hh == 0) return NULL; \
   1346          if (hh != n0) { h++; continue; } \
   1347          \
   1348          UWord i; \
   1349          for (i = 0; i < nlen; i++) { \
   1350             if (n[i] != h[i]) \
   1351                break; \
   1352          } \
   1353          /* assert(i >= 0 && i <= nlen); */ \
   1354          if (i == nlen) \
   1355             return h; \
   1356          \
   1357          h++; \
   1358       } \
   1359    }
   1360 
   1361 #if defined(VGO_linux)
   1362  STRSTR(VG_Z_LIBC_SONAME,          strstr)
   1363 
   1364 #elif defined(VGO_darwin)
   1365 
   1366 #endif
   1367 
   1368 
   1369 /*---------------------- strpbrk ----------------------*/
   1370 
   1371 #define STRPBRK(soname, fnname) \
   1372    void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
   1373          (void* sV, void* acceptV); \
   1374    void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
   1375          (void* sV, void* acceptV) \
   1376    { \
   1377       UChar* s = (UChar*)sV; \
   1378       UChar* accept = (UChar*)acceptV; \
   1379       \
   1380       /*  find the length of 'accept', not including terminating zero */ \
   1381       UWord nacc = 0; \
   1382       while (accept[nacc]) nacc++; \
   1383       \
   1384       /* if n is the empty string, fail immediately. */ \
   1385       if (nacc == 0) return NULL; \
   1386       \
   1387       /* assert(nacc >= 1); */ \
   1388       while (1) { \
   1389          UWord i; \
   1390          UChar sc = *s; \
   1391          if (sc == 0) \
   1392             break; \
   1393          for (i = 0; i < nacc; i++) { \
   1394             if (sc == accept[i]) \
   1395                return s; \
   1396          } \
   1397          s++; \
   1398       } \
   1399       \
   1400       return NULL; \
   1401    }
   1402 
   1403 #if defined(VGO_linux)
   1404  STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
   1405 
   1406 #elif defined(VGO_darwin)
   1407 
   1408 #endif
   1409 
   1410 
   1411 /*---------------------- strcspn ----------------------*/
   1412 
   1413 #define STRCSPN(soname, fnname) \
   1414    SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
   1415          (void* sV, void* rejectV); \
   1416    SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
   1417          (void* sV, void* rejectV) \
   1418    { \
   1419       UChar* s = (UChar*)sV; \
   1420       UChar* reject = (UChar*)rejectV; \
   1421       \
   1422       /* find the length of 'reject', not including terminating zero */ \
   1423       UWord nrej = 0; \
   1424       while (reject[nrej]) nrej++; \
   1425       \
   1426       UWord len = 0; \
   1427       while (1) { \
   1428          UWord i; \
   1429          UChar sc = *s; \
   1430          if (sc == 0) \
   1431             break; \
   1432          for (i = 0; i < nrej; i++) { \
   1433             if (sc == reject[i]) \
   1434                break; \
   1435          } \
   1436          /* assert(i >= 0 && i <= nrej); */ \
   1437          if (i < nrej) \
   1438             break; \
   1439          s++; \
   1440          len++; \
   1441       } \
   1442       \
   1443       return len; \
   1444    }
   1445 
   1446 #if defined(VGO_linux)
   1447  STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
   1448 
   1449 #elif defined(VGO_darwin)
   1450 
   1451 #endif
   1452 
   1453 
   1454 /*---------------------- strspn ----------------------*/
   1455 
   1456 #define STRSPN(soname, fnname) \
   1457    SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
   1458          (void* sV, void* acceptV); \
   1459    SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
   1460          (void* sV, void* acceptV) \
   1461    { \
   1462       UChar* s = (UChar*)sV; \
   1463       UChar* accept = (UChar*)acceptV; \
   1464       \
   1465       /* find the length of 'accept', not including terminating zero */ \
   1466       UWord nacc = 0; \
   1467       while (accept[nacc]) nacc++; \
   1468       if (nacc == 0) return 0; \
   1469       \
   1470       UWord len = 0; \
   1471       while (1) { \
   1472          UWord i; \
   1473          UChar sc = *s; \
   1474          if (sc == 0) \
   1475             break; \
   1476          for (i = 0; i < nacc; i++) { \
   1477             if (sc == accept[i]) \
   1478                break; \
   1479          } \
   1480          /* assert(i >= 0 && i <= nacc); */ \
   1481          if (i == nacc) \
   1482             break; \
   1483          s++; \
   1484          len++; \
   1485       } \
   1486       \
   1487       return len; \
   1488    }
   1489 
   1490 #if defined(VGO_linux)
   1491  STRSPN(VG_Z_LIBC_SONAME,          strspn)
   1492 
   1493 #elif defined(VGO_darwin)
   1494 
   1495 #endif
   1496 
   1497 
   1498 /*---------------------- strcasestr ----------------------*/
   1499 
   1500 #define STRCASESTR(soname, fnname) \
   1501    void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
   1502          (void* haystack, void* needle); \
   1503    void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
   1504          (void* haystack, void* needle) \
   1505    { \
   1506       extern int tolower(int); \
   1507       UChar* h = (UChar*)haystack; \
   1508       UChar* n = (UChar*)needle; \
   1509       \
   1510       /* find the length of n, not including terminating zero */ \
   1511       UWord nlen = 0; \
   1512       while (n[nlen]) nlen++; \
   1513       \
   1514       /* if n is the empty string, match immediately. */ \
   1515       if (nlen == 0) return h; \
   1516       \
   1517       /* assert(nlen >= 1); */ \
   1518       UChar n0 = tolower(n[0]);                 \
   1519       \
   1520       while (1) { \
   1521          UChar hh = tolower(*h);    \
   1522          if (hh == 0) return NULL; \
   1523          if (hh != n0) { h++; continue; } \
   1524          \
   1525          UWord i; \
   1526          for (i = 0; i < nlen; i++) { \
   1527             if (tolower(n[i]) != tolower(h[i]))  \
   1528                break; \
   1529          } \
   1530          /* assert(i >= 0 && i <= nlen); */ \
   1531          if (i == nlen) \
   1532             return h; \
   1533          \
   1534          h++; \
   1535       } \
   1536    }
   1537 
   1538 #if defined(VGO_linux)
   1539 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
   1540   STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
   1541 # endif
   1542 
   1543 #elif defined(VGO_darwin)
   1544 
   1545 #endif
   1546 
   1547 
   1548 /*---------------------- wcslen ----------------------*/
   1549 
   1550 // This is a wchar_t equivalent to strlen.  Unfortunately
   1551 // we don't have wchar_t available here, but it looks like
   1552 // a 32 bit int on Linux.  I don't know if that is also
   1553 // valid on MacOSX.
   1554 
   1555 #define WCSLEN(soname, fnname) \
   1556    SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
   1557       ( const UInt* str ); \
   1558    SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
   1559       ( const UInt* str )  \
   1560    { \
   1561       SizeT i = 0; \
   1562       while (str[i] != 0) i++; \
   1563       return i; \
   1564    }
   1565 
   1566 #if defined(VGO_linux)
   1567  WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
   1568 
   1569 #elif defined(VGO_darwin)
   1570 
   1571 #endif
   1572 
   1573 
   1574 /*------------------------------------------------------------*/
   1575 /*--- Improve definedness checking of process environment  ---*/
   1576 /*------------------------------------------------------------*/
   1577 
   1578 #if defined(VGO_linux)
   1579 
   1580 /* If these wind up getting generated via a macro, so that multiple
   1581    versions of each function exist (as above), use the _EZU variants
   1582    to assign equivalance class tags. */
   1583 
   1584 /*---------------------- putenv ----------------------*/
   1585 
   1586 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
   1587 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
   1588 {
   1589     OrigFn fn;
   1590     Word result;
   1591     const char* p = string;
   1592     VALGRIND_GET_ORIG_FN(fn);
   1593     /* Now by walking over the string we magically produce
   1594        traces when hitting undefined memory. */
   1595     if (p)
   1596         while (*p++)
   1597             __asm__ __volatile__("" ::: "memory");
   1598     CALL_FN_W_W(result, fn, string);
   1599     return result;
   1600 }
   1601 
   1602 
   1603 /*---------------------- unsetenv ----------------------*/
   1604 
   1605 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
   1606 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
   1607 {
   1608     OrigFn fn;
   1609     Word result;
   1610     const char* p = name;
   1611     VALGRIND_GET_ORIG_FN(fn);
   1612     /* Now by walking over the string we magically produce
   1613        traces when hitting undefined memory. */
   1614     if (p)
   1615         while (*p++)
   1616             __asm__ __volatile__("" ::: "memory");
   1617     CALL_FN_W_W(result, fn, name);
   1618     return result;
   1619 }
   1620 
   1621 
   1622 /*---------------------- setenv ----------------------*/
   1623 
   1624 /* setenv */
   1625 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
   1626     (const char* name, const char* value, int overwrite);
   1627 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
   1628     (const char* name, const char* value, int overwrite)
   1629 {
   1630     OrigFn fn;
   1631     Word result;
   1632     const char* p;
   1633     VALGRIND_GET_ORIG_FN(fn);
   1634     /* Now by walking over the string we magically produce
   1635        traces when hitting undefined memory. */
   1636     if (name)
   1637         for (p = name; *p; p++)
   1638             __asm__ __volatile__("" ::: "memory");
   1639     if (value)
   1640         for (p = value; *p; p++)
   1641             __asm__ __volatile__("" ::: "memory");
   1642     VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
   1643     CALL_FN_W_WWW(result, fn, name, value, overwrite);
   1644     return result;
   1645 }
   1646 
   1647 #endif /* defined(VGO_linux) */
   1648 
   1649 /*--------------------------------------------------------------------*/
   1650 /*--- end                                                          ---*/
   1651 /*--------------------------------------------------------------------*/
   1652