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