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-2010 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_hashtable.h"
     35 #include "pub_tool_redir.h"
     36 #include "pub_tool_tooliface.h"
     37 #include "valgrind.h"
     38 
     39 #include "mc_include.h"
     40 #include "memcheck.h"
     41 
     42 /* ---------------------------------------------------------------------
     43    We have our own versions of these functions for two reasons:
     44    (a) it allows us to do overlap checking
     45    (b) some of the normal versions are hyper-optimised, which fools
     46        Memcheck and cause spurious value warnings.  Our versions are
     47        simpler.
     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 /* Figure out if [dst .. dst+dstlen-1] overlaps with
     57                  [src .. src+srclen-1].
     58    We assume that the address ranges do not wrap around
     59    (which is safe since on Linux addresses >= 0xC0000000
     60    are not accessible and the program will segfault in this
     61    circumstance, presumably).
     62 */
     63 static __inline__
     64 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
     65 {
     66    Addr loS, hiS, loD, hiD;
     67 
     68    if (dstlen == 0 || srclen == 0)
     69       return False;
     70 
     71    loS = (Addr)src;
     72    loD = (Addr)dst;
     73    hiS = loS + srclen - 1;
     74    hiD = loD + dstlen - 1;
     75 
     76    /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
     77    if (loS < loD) {
     78       return !(hiS < loD);
     79    }
     80    else if (loD < loS) {
     81       return !(hiD < loS);
     82    }
     83    else {
     84       /* They start at same place.  Since we know neither of them has
     85          zero length, they must overlap. */
     86       return True;
     87    }
     88 }
     89 
     90 // This is a macro rather than a function because we don't want to have an
     91 // extra function in the stack trace.
     92 #define RECORD_OVERLAP_ERROR(s, src, dst, len) \
     93 { \
     94    Word unused_res; \
     95    VALGRIND_DO_CLIENT_REQUEST(unused_res, 0, \
     96 			      _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR, \
     97 			      s, src, dst, len, 0); \
     98 }
     99 
    100 
    101 #define STRRCHR(soname, fnname) \
    102    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \
    103    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \
    104    { \
    105       UChar  ch   = (UChar)((UInt)c); \
    106       UChar* p    = (UChar*)s; \
    107       UChar* last = NULL; \
    108       while (True) { \
    109          if (*p == ch) last = p; \
    110          if (*p == 0) return last; \
    111          p++; \
    112       } \
    113    }
    114 
    115 // Apparently rindex() is the same thing as strrchr()
    116 STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
    117 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
    118 #if defined(VGO_linux)
    119 STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
    120 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
    121 #elif defined(VGO_darwin)
    122 STRRCHR(VG_Z_DYLD,          strrchr)
    123 STRRCHR(VG_Z_DYLD,          rindex)
    124 #endif
    125 
    126 
    127 #define STRCHR(soname, fnname) \
    128    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
    129    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
    130    { \
    131       UChar  ch = (UChar)((UInt)c); \
    132       UChar* p  = (UChar*)s; \
    133       while (True) { \
    134          if (*p == ch) return p; \
    135          if (*p == 0) return NULL; \
    136          p++; \
    137       } \
    138    }
    139 
    140 // Apparently index() is the same thing as strchr()
    141 STRCHR(VG_Z_LIBC_SONAME,          strchr)
    142 STRCHR(VG_Z_LIBC_SONAME,          index)
    143 #if defined(VGO_linux)
    144 STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
    145 STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
    146 STRCHR(VG_Z_LD_LINUX_SO_2,        index)
    147 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
    148 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
    149 #elif defined(VGO_darwin)
    150 STRCHR(VG_Z_DYLD,                 strchr)
    151 STRCHR(VG_Z_DYLD,                 index)
    152 #endif
    153 
    154 
    155 #define STRCAT(soname, fnname) \
    156    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
    157    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
    158    { \
    159       const Char* src_orig = src; \
    160             Char* dst_orig = dst; \
    161       while (*dst) dst++; \
    162       while (*src) *dst++ = *src++; \
    163       *dst = 0; \
    164       \
    165       /* This is a bit redundant, I think;  any overlap and the strcat will */ \
    166       /* go forever... or until a seg fault occurs. */ \
    167       if (is_overlap(dst_orig,  \
    168                      src_orig,  \
    169                      (Addr)dst-(Addr)dst_orig+1,  \
    170                      (Addr)src-(Addr)src_orig+1)) \
    171          RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
    172       \
    173       return dst_orig; \
    174    }
    175 
    176 STRCAT(VG_Z_LIBC_SONAME, strcat)
    177 #if defined(VGO_linux)
    178 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
    179 #endif
    180 
    181 #define STRNCAT(soname, fnname) \
    182    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    183             ( char* dst, const char* src, SizeT n ); \
    184    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    185             ( char* dst, const char* src, SizeT n ) \
    186    { \
    187       const Char* src_orig = src; \
    188             Char* dst_orig = dst; \
    189       SizeT m = 0; \
    190       \
    191       while (*dst) dst++; \
    192       while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
    193       *dst = 0;                                       /* always add null   */ \
    194       \
    195       /* This checks for overlap after copying, unavoidable without */ \
    196       /* pre-counting lengths... should be ok */ \
    197       if (is_overlap(dst_orig,  \
    198                      src_orig,  \
    199                      (Addr)dst-(Addr)dst_orig+1,  \
    200                      (Addr)src-(Addr)src_orig+1)) \
    201          RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
    202       \
    203       return dst_orig; \
    204    }
    205 
    206 STRNCAT(VG_Z_LIBC_SONAME, strncat)
    207 #if defined(VGO_darwin)
    208 STRNCAT(VG_Z_DYLD,        strncat)
    209 #endif
    210 
    211 
    212 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
    213    to be nul-terminated after the copy, unless n <= strlen(dst_orig).
    214    Returns min(n, strlen(dst_orig)) + strlen(src_orig).
    215    Truncation occurred if retval >= n.
    216 */
    217 #define STRLCAT(soname, fnname) \
    218     SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    219         ( char* dst, const char* src, SizeT n ); \
    220     SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    221         ( char* dst, const char* src, SizeT n ) \
    222    { \
    223       const Char* src_orig = src; \
    224       Char* dst_orig = dst; \
    225       SizeT m = 0; \
    226 \
    227       while (m < n && *dst) { m++; dst++; } \
    228       if (m < n) { \
    229          /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
    230          while (m < n-1 && *src) { m++; *dst++ = *src++; } \
    231          *dst = 0; \
    232       } else { \
    233          /* No space to copy anything to dst. m == n */ \
    234       } \
    235       /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
    236       while (*src) { m++; src++; } \
    237       /* This checks for overlap after copying, unavoidable without */ \
    238       /* pre-counting lengths... should be ok */ \
    239       if (is_overlap(dst_orig,  \
    240                      src_orig,  \
    241                      (Addr)dst-(Addr)dst_orig+1,  \
    242                      (Addr)src-(Addr)src_orig+1)) \
    243          RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
    244 \
    245       return m; \
    246    }
    247 
    248 #if defined(VGO_darwin)
    249 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
    250 STRLCAT(VG_Z_DYLD,        strlcat)
    251 #endif
    252 
    253 
    254 #define STRNLEN(soname, fnname) \
    255    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
    256    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
    257    { \
    258       SizeT i = 0; \
    259       while (i < n && str[i] != 0) i++; \
    260       return i; \
    261    }
    262 
    263 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
    264 #if defined(VGO_linux)
    265 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
    266 #endif
    267 
    268 
    269 // Note that this replacement often doesn't get used because gcc inlines
    270 // calls to strlen() with its own built-in version.  This can be very
    271 // confusing if you aren't expecting it.  Other small functions in this file
    272 // may also be inline by gcc.
    273 #define STRLEN(soname, fnname) \
    274    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
    275    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
    276    { \
    277       SizeT i = 0; \
    278       while (str[i] != 0) i++; \
    279       return i; \
    280    }
    281 
    282 STRLEN(VG_Z_LIBC_SONAME,          strlen)
    283 #if defined(VGO_linux)
    284 STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
    285 STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
    286 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
    287 #endif
    288 
    289 
    290 #define STRCPY(soname, fnname) \
    291    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
    292    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
    293    { \
    294       const Char* src_orig = src; \
    295             Char* dst_orig = dst; \
    296       \
    297       while (*src) *dst++ = *src++; \
    298       *dst = 0; \
    299       \
    300       /* This checks for overlap after copying, unavoidable without */ \
    301       /* pre-counting length... should be ok */ \
    302       if (is_overlap(dst_orig,  \
    303                      src_orig,  \
    304                      (Addr)dst-(Addr)dst_orig+1,  \
    305                      (Addr)src-(Addr)src_orig+1)) \
    306          RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
    307       \
    308       return dst_orig; \
    309    }
    310 
    311 STRCPY(VG_Z_LIBC_SONAME, strcpy)
    312 #if defined(VGO_linux)
    313 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
    314 #elif defined(VGO_darwin)
    315 STRCPY(VG_Z_DYLD,        strcpy)
    316 #endif
    317 
    318 
    319 #define STRNCPY(soname, fnname) \
    320    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
    321             ( char* dst, const char* src, SizeT n ); \
    322    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
    323             ( char* dst, const char* src, SizeT n ) \
    324    { \
    325       const Char* src_orig = src; \
    326             Char* dst_orig = dst; \
    327       SizeT m = 0; \
    328       \
    329       while (m   < n && *src) { m++; *dst++ = *src++; } \
    330       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
    331       /* but only m+1 bytes of src if terminator was found */ \
    332       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
    333          RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
    334       while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
    335  \
    336       return dst_orig; \
    337    }
    338 
    339 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
    340 #if defined(VGO_linux)
    341 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
    342 #elif defined(VGO_darwin)
    343 STRNCPY(VG_Z_DYLD,        strncpy)
    344 #endif
    345 
    346 
    347 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
    348    Returns strlen(src). Does not zero-fill the remainder of dst. */
    349 #define STRLCPY(soname, fnname) \
    350    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
    351        ( char* dst, const char* src, SizeT n ); \
    352    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
    353        ( char* dst, const char* src, SizeT n ) \
    354    { \
    355       const char* src_orig = src; \
    356       char* dst_orig = dst; \
    357       SizeT m = 0; \
    358 \
    359       while (m < n-1 && *src) { m++; *dst++ = *src++; } \
    360       /* m non-nul bytes have now been copied, and m <= n-1. */ \
    361       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
    362       /* but only m+1 bytes of src if terminator was found */ \
    363       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
    364           RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
    365       /* Nul-terminate dst. */ \
    366       if (n > 0) *dst = 0; \
    367       /* Finish counting strlen(src). */ \
    368       while (*src) src++; \
    369       return src - src_orig; \
    370    }
    371 
    372 #if defined(VGO_darwin)
    373 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
    374 STRLCPY(VG_Z_DYLD,        strlcpy)
    375 #endif
    376 
    377 
    378 #define STRNCMP(soname, fnname) \
    379    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    380           ( const char* s1, const char* s2, SizeT nmax ); \
    381    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    382           ( const char* s1, const char* s2, SizeT nmax ) \
    383    { \
    384       SizeT n = 0; \
    385       while (True) { \
    386          if (n >= nmax) return 0; \
    387          if (*s1 == 0 && *s2 == 0) return 0; \
    388          if (*s1 == 0) return -1; \
    389          if (*s2 == 0) return 1; \
    390          \
    391          if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
    392          if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
    393          \
    394          s1++; s2++; n++; \
    395       } \
    396    }
    397 
    398 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
    399 #if defined(VGO_linux)
    400 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
    401 #elif defined(VGO_darwin)
    402 STRNCMP(VG_Z_DYLD,        strncmp)
    403 #endif
    404 
    405 
    406 #define STRCASECMP(soname, fnname) \
    407    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    408           ( const char* s1, const char* s2 ); \
    409    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    410           ( const char* s1, const char* s2 ) \
    411    { \
    412       extern int tolower(int); \
    413       register unsigned char c1; \
    414       register unsigned char c2; \
    415       while (True) { \
    416          c1 = tolower(*(unsigned char *)s1); \
    417          c2 = tolower(*(unsigned char *)s2); \
    418          if (c1 != c2) break; \
    419          if (c1 == 0) break; \
    420          s1++; s2++; \
    421       } \
    422       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    423       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    424       return 0; \
    425    }
    426 
    427 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
    428 #if defined(VGO_linux)
    429 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
    430 #endif
    431 
    432 
    433 #define STRNCASECMP(soname, fnname) \
    434    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    435           ( const char* s1, const char* s2, SizeT nmax ); \
    436    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    437           ( const char* s1, const char* s2, SizeT nmax ) \
    438    { \
    439       extern int tolower(int); \
    440       SizeT n = 0; \
    441       while (True) { \
    442          if (n >= nmax) return 0; \
    443          if (*s1 == 0 && *s2 == 0) return 0; \
    444          if (*s1 == 0) return -1; \
    445          if (*s2 == 0) return 1; \
    446          \
    447          if (tolower(*(unsigned char*)s1) < tolower(*(unsigned char*)s2)) return -1; \
    448          if (tolower(*(unsigned char*)s1) > tolower(*(unsigned char*)s2)) return 1; \
    449          \
    450          s1++; s2++; n++; \
    451       } \
    452    }
    453 
    454 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
    455 #if defined(VGO_linux)
    456 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
    457 #elif defined(VGO_darwin)
    458 STRNCASECMP(VG_Z_DYLD,        strncasecmp)
    459 #endif
    460 
    461 
    462 #define STRCASECMP_L(soname, fnname) \
    463    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    464           ( const char* s1, const char* s2, void* locale ); \
    465    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    466           ( const char* s1, const char* s2, void* locale ) \
    467    { \
    468       extern int tolower_l(int, void*) __attribute__((weak));    \
    469       register unsigned char c1; \
    470       register unsigned char c2; \
    471       while (True) { \
    472          c1 = tolower_l(*(unsigned char *)s1, locale); \
    473          c2 = tolower_l(*(unsigned char *)s2, locale); \
    474          if (c1 != c2) break; \
    475          if (c1 == 0) break; \
    476          s1++; s2++; \
    477       } \
    478       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    479       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    480       return 0; \
    481    }
    482 
    483 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
    484 #if defined(VGO_linux)
    485 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
    486 #endif
    487 
    488 
    489 #define STRNCASECMP_L(soname, fnname) \
    490    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    491           ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
    492    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    493           ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
    494    { \
    495       extern int tolower_l(int, void*) __attribute__((weak));    \
    496       SizeT n = 0; \
    497       while (True) { \
    498          if (n >= nmax) return 0; \
    499          if (*s1 == 0 && *s2 == 0) return 0; \
    500          if (*s1 == 0) return -1; \
    501          if (*s2 == 0) return 1; \
    502          \
    503          if (tolower_l(*(unsigned char*)s1, locale) < tolower_l(*(unsigned char*)s2, locale)) return -1; \
    504          if (tolower_l(*(unsigned char*)s1, locale) > tolower_l(*(unsigned char*)s2, locale)) return 1; \
    505          \
    506          s1++; s2++; n++; \
    507       } \
    508    }
    509 
    510 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
    511 #if defined(VGO_linux)
    512 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
    513 #elif defined(VGO_darwin)
    514 STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
    515 #endif
    516 
    517 
    518 #define STRCMP(soname, fnname) \
    519    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    520           ( const char* s1, const char* s2 ); \
    521    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    522           ( const char* s1, const char* s2 ) \
    523    { \
    524       register unsigned char c1; \
    525       register unsigned char c2; \
    526       while (True) { \
    527          c1 = *(unsigned char *)s1; \
    528          c2 = *(unsigned char *)s2; \
    529          if (c1 != c2) break; \
    530          if (c1 == 0) break; \
    531          s1++; s2++; \
    532       } \
    533       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
    534       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
    535       return 0; \
    536    }
    537 
    538 STRCMP(VG_Z_LIBC_SONAME,          strcmp)
    539 #if defined(VGO_linux)
    540 STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
    541 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
    542 STRCMP(VG_Z_LD64_SO_1,            strcmp)
    543 #endif
    544 
    545 
    546 #define MEMCHR(soname, fnname) \
    547    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
    548    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \
    549    { \
    550       SizeT i; \
    551       UChar c0 = (UChar)c; \
    552       UChar* p = (UChar*)s; \
    553       for (i = 0; i < n; i++) \
    554          if (p[i] == c0) return (void*)(&p[i]); \
    555       return NULL; \
    556    }
    557 
    558 MEMCHR(VG_Z_LIBC_SONAME, memchr)
    559 #if defined(VGO_darwin)
    560 MEMCHR(VG_Z_DYLD,        memchr)
    561 #endif
    562 
    563 
    564 #define MEMCPY(soname, fnname) \
    565    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    566             ( void *dst, const void *src, SizeT len ); \
    567    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    568             ( void *dst, const void *src, SizeT len ) \
    569    { \
    570       if (is_overlap(dst, src, len, len)) \
    571          RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
    572       \
    573       const Addr WS = sizeof(UWord); /* 8 or 4 */ \
    574       const Addr WM = WS - 1;        /* 7 or 3 */ \
    575       \
    576       if (dst < src) { \
    577       \
    578          /* Copying backwards. */ \
    579          SizeT n = len; \
    580          Addr  d = (Addr)dst; \
    581          Addr  s = (Addr)src; \
    582          \
    583          if (((s^d) & WM) == 0) { \
    584             /* s and d have same UWord alignment. */ \
    585             /* Pull up to a UWord boundary. */ \
    586             while ((s & WM) != 0 && n >= 1) \
    587                { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    588             /* Copy UWords. */ \
    589             while (n >= WS) \
    590                { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
    591             if (n == 0) \
    592                return dst; \
    593          } \
    594          if (((s|d) & 1) == 0) { \
    595             /* Both are 16-aligned; copy what we can thusly. */ \
    596             while (n >= 2) \
    597                { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
    598          } \
    599          /* Copy leftovers, or everything if misaligned. */ \
    600          while (n >= 1) \
    601             { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
    602       \
    603       } else if (dst > src) { \
    604       \
    605          SizeT n = len; \
    606          Addr  d = ((Addr)dst) + n; \
    607          Addr  s = ((Addr)src) + n; \
    608          \
    609          /* Copying forwards. */ \
    610          if (((s^d) & WM) == 0) { \
    611             /* s and d have same UWord alignment. */ \
    612             /* Back down to a UWord boundary. */ \
    613             while ((s & WM) != 0 && n >= 1) \
    614                { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    615             /* Copy UWords. */ \
    616             while (n >= WS) \
    617                { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
    618             if (n == 0) \
    619                return dst; \
    620          } \
    621          if (((s|d) & 1) == 0) { \
    622             /* Both are 16-aligned; copy what we can thusly. */ \
    623             while (n >= 2) \
    624                { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
    625          } \
    626          /* Copy leftovers, or everything if misaligned. */ \
    627          while (n >= 1) \
    628             { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
    629          \
    630       } \
    631       \
    632       return dst; \
    633    }
    634 
    635 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
    636 #if defined(VGO_linux)
    637 MEMCPY(VG_Z_LD_SO_1,     memcpy) /* ld.so.1 */
    638 MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64.so.1 */
    639 #elif defined(VGO_darwin)
    640 MEMCPY(VG_Z_DYLD,        memcpy)
    641 #endif
    642 /* icc9 blats these around all over the place.  Not only in the main
    643    executable but various .so's.  They are highly tuned and read
    644    memory beyond the source boundary (although work correctly and
    645    never go across page boundaries), so give errors when run natively,
    646    at least for misaligned source arg.  Just intercepting in the exe
    647    only until we understand more about the problem.  See
    648    http://bugs.kde.org/show_bug.cgi?id=139776
    649  */
    650 MEMCPY(NONE, _intel_fast_memcpy)
    651 
    652 
    653 #define MEMCMP(soname, fnname) \
    654    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    655           ( const void *s1V, const void *s2V, SizeT n ); \
    656    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    657           ( const void *s1V, const void *s2V, SizeT n ) \
    658    { \
    659       int res; \
    660       unsigned char a0; \
    661       unsigned char b0; \
    662       unsigned char* s1 = (unsigned char*)s1V; \
    663       unsigned char* s2 = (unsigned char*)s2V; \
    664       \
    665       while (n != 0) { \
    666          a0 = s1[0]; \
    667          b0 = s2[0]; \
    668          s1 += 1; \
    669          s2 += 1; \
    670          res = ((int)a0) - ((int)b0); \
    671          if (res != 0) \
    672             return res; \
    673          n -= 1; \
    674       } \
    675       return 0; \
    676    }
    677 
    678 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
    679 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
    680 #if defined(VGO_linux)
    681 MEMCMP(VG_Z_LD_SO_1,     bcmp)
    682 #elif defined(VGO_darwin)
    683 MEMCMP(VG_Z_DYLD,        memcmp)
    684 MEMCMP(VG_Z_DYLD,        bcmp)
    685 #endif
    686 
    687 
    688 /* Copy SRC to DEST, returning the address of the terminating '\0' in
    689    DEST. (minor variant of strcpy) */
    690 #define STPCPY(soname, fnname) \
    691    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
    692    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
    693    { \
    694       const Char* src_orig = src; \
    695             Char* dst_orig = dst; \
    696       \
    697       while (*src) *dst++ = *src++; \
    698       *dst = 0; \
    699       \
    700       /* This checks for overlap after copying, unavoidable without */ \
    701       /* pre-counting length... should be ok */ \
    702       if (is_overlap(dst_orig,  \
    703                      src_orig,  \
    704                      (Addr)dst-(Addr)dst_orig+1,  \
    705                      (Addr)src-(Addr)src_orig+1)) \
    706          RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
    707       \
    708       return dst; \
    709    }
    710 
    711 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
    712 #if defined(VGO_linux)
    713 STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
    714 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
    715 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
    716 #elif defined(VGO_darwin)
    717 STPCPY(VG_Z_DYLD,                 stpcpy)
    718 #endif
    719 
    720 
    721 #define MEMSET(soname, fnname) \
    722    void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n); \
    723    void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n) \
    724    { \
    725       Addr a  = (Addr)s;   \
    726       UInt c4 = (c & 0xFF); \
    727       c4 = (c4 << 8) | c4; \
    728       c4 = (c4 << 16) | c4; \
    729       while ((a & 3) != 0 && n >= 1) \
    730          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
    731       while (n >= 4) \
    732          { *(UInt*)a = c4; a += 4; n -= 4; } \
    733       while (n >= 1) \
    734          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
    735       return s; \
    736    }
    737 
    738 MEMSET(VG_Z_LIBC_SONAME, memset)
    739 #if defined(VGO_darwin)
    740 MEMSET(VG_Z_DYLD,        memset)
    741 #endif
    742 
    743 
    744 #define MEMMOVE(soname, fnname) \
    745    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    746             (void *dstV, const void *srcV, SizeT n); \
    747    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    748             (void *dstV, const void *srcV, SizeT n) \
    749    { \
    750       SizeT i; \
    751       Char* dst = (Char*)dstV; \
    752       Char* src = (Char*)srcV; \
    753       if (dst < src) { \
    754          for (i = 0; i < n; i++) \
    755             dst[i] = src[i]; \
    756       } \
    757       else  \
    758       if (dst > src) { \
    759          for (i = 0; i < n; i++) \
    760             dst[n-i-1] = src[n-i-1]; \
    761       } \
    762       return dst; \
    763    }
    764 
    765 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
    766 #if defined(VGO_darwin)
    767 MEMMOVE(VG_Z_DYLD,        memmove)
    768 #endif
    769 
    770 
    771 #define BCOPY(soname, fnname) \
    772    void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    773             (const void *srcV, void *dstV, SizeT n); \
    774    void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    775             (const void *srcV, void *dstV, SizeT n) \
    776    { \
    777       SizeT i; \
    778       Char* dst = (Char*)dstV; \
    779       Char* src = (Char*)srcV; \
    780       if (dst < src) { \
    781          for (i = 0; i < n; i++) \
    782             dst[i] = src[i]; \
    783       } \
    784       else  \
    785       if (dst > src) { \
    786          for (i = 0; i < n; i++) \
    787             dst[n-i-1] = src[n-i-1]; \
    788       } \
    789    }
    790 
    791 BCOPY(VG_Z_LIBC_SONAME, bcopy)
    792 #if defined(VGO_darwin)
    793 BCOPY(VG_Z_DYLD,        bcopy)
    794 #endif
    795 
    796 
    797 /* glibc 2.5 variant of memmove which checks the dest is big enough.
    798    There is no specific part of glibc that this is copied from. */
    799 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
    800    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    801             (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
    802    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    803             (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
    804    { \
    805       extern void _exit(int status); \
    806       SizeT i; \
    807       Char* dst = (Char*)dstV; \
    808       Char* src = (Char*)srcV; \
    809       if (destlen < n) \
    810          goto badness; \
    811       if (dst < src) { \
    812          for (i = 0; i < n; i++) \
    813             dst[i] = src[i]; \
    814       } \
    815       else  \
    816       if (dst > src) { \
    817          for (i = 0; i < n; i++) \
    818             dst[n-i-1] = src[n-i-1]; \
    819       } \
    820       return dst; \
    821      badness: \
    822       VALGRIND_PRINTF_BACKTRACE( \
    823          "*** memmove_chk: buffer overflow detected ***: " \
    824          "program terminated\n"); \
    825      _exit(127); \
    826      /*NOTREACHED*/ \
    827      return NULL; \
    828    }
    829 
    830 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
    831 
    832 
    833 /* Find the first occurrence of C in S or the final NUL byte.  */
    834 #define GLIBC232_STRCHRNUL(soname, fnname) \
    835    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
    836    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
    837    { \
    838       unsigned char  c        = (unsigned char) c_in; \
    839       unsigned char* char_ptr = (unsigned char *)s; \
    840       while (1) { \
    841          if (*char_ptr == 0) return char_ptr; \
    842          if (*char_ptr == c) return char_ptr; \
    843          char_ptr++; \
    844       } \
    845    }
    846 
    847 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
    848 
    849 
    850 /* Find the first occurrence of C in S.  */
    851 #define GLIBC232_RAWMEMCHR(soname, fnname) \
    852    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
    853    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
    854    { \
    855       unsigned char  c        = (unsigned char) c_in; \
    856       unsigned char* char_ptr = (unsigned char *)s; \
    857       while (1) { \
    858          if (*char_ptr == c) return char_ptr; \
    859          char_ptr++; \
    860       } \
    861    }
    862 
    863 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
    864 #if defined (VGO_linux)
    865 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
    866 #endif
    867 
    868 /* glibc variant of strcpy that checks the dest is big enough.
    869    Copied from glibc-2.5/debug/test-strcpy_chk.c. */
    870 #define GLIBC25___STRCPY_CHK(soname,fnname) \
    871    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    872                                (char* dst, const char* src, SizeT len); \
    873    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    874                                (char* dst, const char* src, SizeT len) \
    875    { \
    876       extern void _exit(int status); \
    877       char* ret = dst; \
    878       if (! len) \
    879          goto badness; \
    880       while ((*dst++ = *src++) != '\0') \
    881          if (--len == 0) \
    882             goto badness; \
    883       return ret; \
    884      badness: \
    885       VALGRIND_PRINTF_BACKTRACE( \
    886          "*** strcpy_chk: buffer overflow detected ***: " \
    887          "program terminated\n"); \
    888      _exit(127); \
    889      /*NOTREACHED*/ \
    890      return NULL; \
    891    }
    892 
    893 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
    894 
    895 
    896 /* glibc variant of stpcpy that checks the dest is big enough.
    897    Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
    898 #define GLIBC25___STPCPY_CHK(soname,fnname) \
    899    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    900                                (char* dst, const char* src, SizeT len); \
    901    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    902                                (char* dst, const char* src, SizeT len) \
    903    { \
    904       extern void _exit(int status); \
    905       if (! len) \
    906          goto badness; \
    907       while ((*dst++ = *src++) != '\0') \
    908          if (--len == 0) \
    909             goto badness; \
    910       return dst - 1; \
    911      badness: \
    912       VALGRIND_PRINTF_BACKTRACE( \
    913          "*** stpcpy_chk: buffer overflow detected ***: " \
    914          "program terminated\n"); \
    915      _exit(127); \
    916      /*NOTREACHED*/ \
    917      return NULL; \
    918    }
    919 
    920 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
    921 
    922 
    923 /* mempcpy */
    924 #define GLIBC25_MEMPCPY(soname, fnname) \
    925    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    926             ( void *dst, const void *src, SizeT len ); \
    927    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    928             ( void *dst, const void *src, SizeT len ) \
    929    { \
    930       register char *d; \
    931       register char *s; \
    932       SizeT len_saved = len; \
    933       \
    934       if (len == 0) \
    935          return dst; \
    936       \
    937       if (is_overlap(dst, src, len, len)) \
    938          RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
    939       \
    940       if ( dst > src ) { \
    941          d = (char *)dst + len - 1; \
    942          s = (char *)src + len - 1; \
    943          while ( len-- ) { \
    944             *d-- = *s--; \
    945          } \
    946       } else if ( dst < src ) { \
    947          d = (char *)dst; \
    948          s = (char *)src; \
    949          while ( len-- ) { \
    950             *d++ = *s++; \
    951          } \
    952       } \
    953       return (void*)( ((char*)dst) + len_saved ); \
    954    }
    955 
    956 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
    957 #if defined(VGO_linux)
    958 GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
    959 #endif
    960 
    961 
    962 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
    963    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    964             (void* dst, const void* src, SizeT len, SizeT dstlen ); \
    965    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
    966             (void* dst, const void* src, SizeT len, SizeT dstlen ) \
    967    { \
    968       extern void _exit(int status); \
    969       register char *d; \
    970       register char *s; \
    971       \
    972       if (dstlen < len) goto badness; \
    973       \
    974       if (len == 0) \
    975          return dst; \
    976       \
    977       if (is_overlap(dst, src, len, len)) \
    978          RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
    979       \
    980       if ( dst > src ) { \
    981          d = (char *)dst + len - 1; \
    982          s = (char *)src + len - 1; \
    983          while ( len-- ) { \
    984             *d-- = *s--; \
    985          } \
    986       } else if ( dst < src ) { \
    987          d = (char *)dst; \
    988          s = (char *)src; \
    989          while ( len-- ) { \
    990             *d++ = *s++; \
    991          } \
    992       } \
    993       return dst; \
    994      badness: \
    995       VALGRIND_PRINTF_BACKTRACE( \
    996          "*** memcpy_chk: buffer overflow detected ***: " \
    997          "program terminated\n"); \
    998      _exit(127); \
    999      /*NOTREACHED*/ \
   1000      return NULL; \
   1001    }
   1002 
   1003 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
   1004 
   1005 
   1006 #define STRSTR(soname, fnname) \
   1007    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1008          (void* haystack, void* needle); \
   1009    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1010          (void* haystack, void* needle) \
   1011    { \
   1012       UChar* h = (UChar*)haystack; \
   1013       UChar* n = (UChar*)needle; \
   1014       \
   1015       /* find the length of n, not including terminating zero */ \
   1016       UWord nlen = 0; \
   1017       while (n[nlen]) nlen++; \
   1018       \
   1019       /* if n is the empty string, match immediately. */ \
   1020       if (nlen == 0) return h; \
   1021       \
   1022       /* assert(nlen >= 1); */ \
   1023       UChar n0 = n[0]; \
   1024       \
   1025       while (1) { \
   1026          UChar hh = *h; \
   1027          if (hh == 0) return NULL; \
   1028          if (hh != n0) { h++; continue; } \
   1029          \
   1030          UWord i; \
   1031          for (i = 0; i < nlen; i++) { \
   1032             if (n[i] != h[i]) \
   1033                break; \
   1034          } \
   1035          /* assert(i >= 0 && i <= nlen); */ \
   1036          if (i == nlen) \
   1037             return h; \
   1038          \
   1039          h++; \
   1040       } \
   1041    }
   1042 
   1043 #if defined(VGO_linux)
   1044 STRSTR(VG_Z_LIBC_SONAME,          strstr)
   1045 #endif
   1046 
   1047 
   1048 #define STRPBRK(soname, fnname) \
   1049    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1050          (void* sV, void* acceptV); \
   1051    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1052          (void* sV, void* acceptV) \
   1053    { \
   1054       UChar* s = (UChar*)sV; \
   1055       UChar* accept = (UChar*)acceptV; \
   1056       \
   1057       /*  find the length of 'accept', not including terminating zero */ \
   1058       UWord nacc = 0; \
   1059       while (accept[nacc]) nacc++; \
   1060       \
   1061       /* if n is the empty string, fail immediately. */ \
   1062       if (nacc == 0) return NULL; \
   1063       \
   1064       /* assert(nacc >= 1); */ \
   1065       while (1) { \
   1066          UWord i; \
   1067          UChar sc = *s; \
   1068          if (sc == 0) \
   1069             break; \
   1070          for (i = 0; i < nacc; i++) { \
   1071             if (sc == accept[i]) \
   1072                return s; \
   1073          } \
   1074          s++; \
   1075       } \
   1076       \
   1077       return NULL; \
   1078    }
   1079 
   1080 #if defined(VGO_linux)
   1081 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
   1082 #endif
   1083 
   1084 
   1085 #define STRCSPN(soname, fnname) \
   1086    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1087          (void* sV, void* rejectV); \
   1088    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
   1089          (void* sV, void* rejectV) \
   1090    { \
   1091       UChar* s = (UChar*)sV; \
   1092       UChar* reject = (UChar*)rejectV; \
   1093       \
   1094       /* find the length of 'reject', not including terminating zero */ \
   1095       UWord nrej = 0; \
   1096       while (reject[nrej]) nrej++; \
   1097       \
   1098       UWord len = 0; \
   1099       while (1) { \
   1100          UWord i; \
   1101          UChar sc = *s; \
   1102          if (sc == 0) \
   1103             break; \
   1104          for (i = 0; i < nrej; i++) { \
   1105             if (sc == reject[i]) \
   1106                break; \
   1107          } \
   1108          /* assert(i >= 0 && i <= nrej); */ \
   1109          if (i < nrej) \
   1110             break; \
   1111          s++; \
   1112          len++; \
   1113       } \
   1114       \
   1115       return len; \
   1116    }
   1117 
   1118 #if defined(VGO_linux)
   1119 STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
   1120 #endif
   1121 
   1122 
   1123 // And here's a validated strspn replacement, should it
   1124 // become necessary.
   1125 //UWord mystrspn( UChar* s, UChar* accept )
   1126 //{
   1127 //   /* find the length of 'accept', not including terminating zero */
   1128 //   UWord nacc = 0;
   1129 //   while (accept[nacc]) nacc++;
   1130 //   if (nacc == 0) return 0;
   1131 //
   1132 //   UWord len = 0;
   1133 //   while (1) {
   1134 //      UWord i;
   1135 //      UChar sc = *s;
   1136 //      if (sc == 0)
   1137 //         break;
   1138 //      for (i = 0; i < nacc; i++) {
   1139 //         if (sc == accept[i])
   1140 //            break;
   1141 //      }
   1142 //      assert(i >= 0 && i <= nacc);
   1143 //      if (i == nacc)
   1144 //         break;
   1145 //      s++;
   1146 //      len++;
   1147 //   }
   1148 //
   1149 //   return len;
   1150 //}
   1151 
   1152 
   1153 /*------------------------------------------------------------*/
   1154 /*--- Improve definedness checking of process environment  ---*/
   1155 /*------------------------------------------------------------*/
   1156 
   1157 #if defined(VGO_linux)
   1158 
   1159 /* putenv */
   1160 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
   1161 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
   1162 {
   1163     OrigFn fn;
   1164     Word result;
   1165     const char* p = string;
   1166     VALGRIND_GET_ORIG_FN(fn);
   1167     /* Now by walking over the string we magically produce
   1168        traces when hitting undefined memory. */
   1169     if (p)
   1170         while (*p++)
   1171             ;
   1172     CALL_FN_W_W(result, fn, string);
   1173     return result;
   1174 }
   1175 
   1176 /* unsetenv */
   1177 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
   1178 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
   1179 {
   1180     OrigFn fn;
   1181     Word result;
   1182     const char* p = name;
   1183     VALGRIND_GET_ORIG_FN(fn);
   1184     /* Now by walking over the string we magically produce
   1185        traces when hitting undefined memory. */
   1186     if (p)
   1187         while (*p++)
   1188             ;
   1189     CALL_FN_W_W(result, fn, name);
   1190     return result;
   1191 }
   1192 
   1193 /* setenv */
   1194 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
   1195     (const char* name, const char* value, int overwrite);
   1196 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
   1197     (const char* name, const char* value, int overwrite)
   1198 {
   1199     OrigFn fn;
   1200     Word result;
   1201     const char* p;
   1202     VALGRIND_GET_ORIG_FN(fn);
   1203     /* Now by walking over the string we magically produce
   1204        traces when hitting undefined memory. */
   1205     if (name)
   1206         for (p = name; *p; p++)
   1207             ;
   1208     if (value)
   1209         for (p = value; *p; p++)
   1210             ;
   1211     VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
   1212     CALL_FN_W_WWW(result, fn, name, value, overwrite);
   1213     return result;
   1214 }
   1215 
   1216 #endif /* defined(VGO_linux) */
   1217 
   1218 
   1219 /*------------------------------------------------------------*/
   1220 /*--- AIX stuff only after this point                      ---*/
   1221 /*------------------------------------------------------------*/
   1222 
   1223 /* Generate replacements for strcat, strncat, strcpy, strncpy, strcmp
   1224    in the given soname. */
   1225 #define Str5FNs(_soname)       \
   1226     STRCAT(_soname, strcat)    \
   1227    STRNCAT(_soname, strncat)   \
   1228     STRCPY(_soname, strcpy)    \
   1229    STRNCPY(_soname, strncpy)   \
   1230     STRCMP(_soname, strcmp)
   1231 
   1232 #if defined(VGP_ppc32_aix5)
   1233 Str5FNs(NONE)                             /* in main exe */
   1234 Str5FNs(libCZdaZLshrcoreZdoZR)            /* libC.a(shrcore.o) */
   1235 Str5FNs(libX11ZdaZLshr4ZdoZR)             /* libX11.a(shr4.o) */
   1236 Str5FNs(libXmZdaZLshrZaZdoZR)             /* libXm.a(shr*.o) */
   1237 Str5FNs(libXtZdaZLshr4ZdoZR)              /* libXt.a(shr4.o) */
   1238 Str5FNs(libppeZurZdaZLdynamicZdoZR)       /* libppe_r.a(dynamic.o) */
   1239 Str5FNs(libodmZdaZLshrZdoZR)              /* libodm.a(shr.o) */
   1240 Str5FNs(libmpiZurZdaZLmpicoreZurZdoZR)    /* libmpi_r.a(mpicore_r.o) */
   1241 Str5FNs(libmpiZurZdaZLmpipoeZurZdoZR)     /* libmpi_r.a(mpipoe_r.o) */
   1242 Str5FNs(libmpiZurZdaZLmpciZurZdoZR)       /* libmpi_r.a(mpci_r.o) */
   1243 Str5FNs(libslurmZdso)                     /* libslurm.so */
   1244 Str5FNs(libglibZdso)                      /* libglib.so */
   1245 Str5FNs(libIMZdaZLshrZdoZR)               /* libIM.a(shr.o) */
   1246 Str5FNs(libiconvZdaZLshr4ZdoZR)           /* libiconv.a(shr4.o) */
   1247 Str5FNs(libGLZdaZLshrZdoZR)               /* libGL.a(shr.o) */
   1248 Str5FNs(libgdkZdso)                       /* libgdk.so */
   1249 Str5FNs(libcursesZdaZLshr42ZdoZR)         /* libcurses.a(shr42.o) */
   1250 Str5FNs(libqtZda)                         /* libqt.a */
   1251 Str5FNs(ZaZLlibglibZhZaZdsoZaZR)          /* *(libglib-*.so*) */
   1252 Str5FNs(ZaZLlibfontconfigZdsoZaZR)        /* *(libfontconfig.so*) */
   1253 Str5FNs(libQtZaa)                         /* libQt*.a */
   1254 #endif
   1255 #if defined(VGP_ppc64_aix5)
   1256 Str5FNs(NONE)                             /* in main exe */
   1257 Str5FNs(libX11ZdaZLshrZu64ZdoZR)          /* libX11.a(shr_64.o) */
   1258 Str5FNs(libiconvZdaZLshr4Zu64ZdoZR)       /* libiconv.a(shr4_64.o) */
   1259 Str5FNs(libGLZdaZLshrZu64ZdoZR)           /* libGL.a(shr_64.o) */
   1260 Str5FNs(libppeZurZdaZLdynamic64ZdoZR)     /* libppe_r.a(dynamic64.o) */
   1261 Str5FNs(libodmZdaZLshrZu64ZdoZR)          /* libodm.a(shr_64.o) */
   1262 Str5FNs(libmpiZurZdaZLmpicore64ZurZdoZR)  /* libmpi_r.a(mpicore64_r.o) */
   1263 Str5FNs(libmpiZurZdaZLmpipoe64ZurZdoZR)   /* libmpi_r.a(mpipoe64_r.o) */
   1264 Str5FNs(libCZdaZLshrcoreZu64ZdoZR)        /* libC.a(shrcore_64.o) */
   1265 Str5FNs(libmpiZurZdaZLmpci64ZurZdoZR)     /* libmpi_r.a(mpci64_r.o) */
   1266 Str5FNs(libqtZda)                         /* libqt.a */
   1267 Str5FNs(ZaZLlibglibZhZaZdsoZaZR)          /* *(libglib-*.so*) */
   1268 Str5FNs(ZaZLlibfontconfigZdsoZaZR)        /* *(libfontconfig.so*) */
   1269 Str5FNs(libQtZaa)                         /* libQt*.a */
   1270 #endif
   1271 
   1272 
   1273 /* AIX's libm contains a sqrt implementation which does a nasty thing:
   1274    it loads the initial estimate of the root into a FP register, but
   1275    only the upper half of the number is initialised data.  Hence the
   1276    least significant 32 mantissa bits are undefined, and it then uses
   1277    Newton-Raphson iteration to compute the final, defined result.
   1278    This fools memcheck completely; the only solution I can think of is
   1279    provide our own substitute.  The _FAST variant is almost right
   1280    except the result is not correctly rounded.  The _EXACT variant,
   1281    which is selected by default, is always right; but it's also pretty
   1282    darn slow. */
   1283 
   1284 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
   1285 #define SQRT_FAST(soname, fnname) \
   1286    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \
   1287    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \
   1288    { \
   1289       static UInt T1[32] =  \
   1290          { 0,       1024,   3062,   5746,   9193,  13348, \
   1291            18162,  23592,  29598,  36145,  43202,  50740, \
   1292            58733,  67158,  75992,  85215,  83599,  71378, \
   1293            60428,  50647,  41945,  34246,  27478,  21581, \
   1294            16499,  12183,   8588,   5674,   3403,   1742, \
   1295            661,    130 }; \
   1296       UInt x0, x1, sign, expo, mant0, bIGENDIAN = 1; \
   1297       union { UInt w[2]; double d; } u; \
   1298       u.d   = x; \
   1299       x0    = u.w[1 - bIGENDIAN]; /* high half */ \
   1300       x1    = u.w[bIGENDIAN];  /* low half */ \
   1301       sign  = x0 >> 31; \
   1302       expo  = (x0 >> 20) & 0x7FF; \
   1303       mant0 = x0 & 0xFFFFF; \
   1304       if ( (sign == 0 && expo >= 1 && expo <= 0x7FE) /* +normal */ \
   1305            || (sign == 0 && expo == 0  \
   1306                          && (mant0 | x1) > 0) /* +denorm */) { \
   1307          /* common case; do Newton-Raphson */ \
   1308          /* technically k should be signed int32, but since we're \
   1309             always entering here with x > 0, doesn't matter that it's \
   1310             unsigned. */ \
   1311          double y; \
   1312          UInt k = (x0>>1) + 0x1ff80000; \
   1313          u.w[1 - bIGENDIAN] = k - T1[31&(k>>15)]; \
   1314          u.w[bIGENDIAN] = 0; \
   1315          y = u.d; \
   1316          y = (y+x/y)/2.0 ; \
   1317          y = (y+x/y)/2.0 ; \
   1318          y = y-(y-x/y)/2.0 ; \
   1319          return y; \
   1320       } \
   1321       if ( (sign == 1 && expo >= 1 && expo <= 0x7FE) /* -normal */ \
   1322            || (sign == 1 && expo == 0  \
   1323                          && (mant0 | x1) > 0) /* -denorm */) { \
   1324          u.w[1 - bIGENDIAN] = 0xFFF00000; \
   1325          u.w[bIGENDIAN] = 0x1; \
   1326          return u.d; /* -Inf -> NaN */ \
   1327       } \
   1328       if ((expo | mant0 | x1) == 0) \
   1329          return x; /* +/-zero -> self */ \
   1330       if (expo == 0x7FF && (mant0 | x1) == 0) { \
   1331          if (sign == 0) \
   1332             return x; /* +Inf -> self */ \
   1333          u.w[1 - bIGENDIAN] = 0xFFF00000; \
   1334          u.w[bIGENDIAN] = 0x1; \
   1335          return u.d; /* -Inf -> NaN */ \
   1336       } \
   1337       /* must be +/- NaN */ \
   1338       return x; /* +/-NaN -> self */ \
   1339    }
   1340 
   1341 #define SQRT_EXACT(soname, fnname) \
   1342    /* \
   1343     * ==================================================== \
   1344     * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. \
   1345     * \
   1346     * Developed at SunPro, a Sun Microsystems, Inc. business. \
   1347     * Permission to use, copy, modify, and distribute this \
   1348     * software is freely granted, provided that this notice \
   1349     * is preserved. \
   1350     * ==================================================== \
   1351     */ \
   1352    /* \
   1353     * Return correctly rounded sqrt. \
   1354     *           ------------------------------------------ \
   1355     *           |  Use the hardware sqrt if you have one | \
   1356     *           ------------------------------------------ \
   1357     * Method: \
   1358     *   Bit by bit method using integer arithmetic. (Slow, but portable) \
   1359     *   1. Normalization \
   1360     *      Scale x to y in [1,4) with even powers of 2: \
   1361     *      find an integer k such that  1 <= (y=x*2^(2k)) < 4, then \
   1362     *              sqrt(x) = 2^k * sqrt(y) \
   1363     *   2. Bit by bit computation \
   1364     *      Let q  = sqrt(y) truncated to i bit after binary point (q = 1), \
   1365     *           i                                                   0 \
   1366     *                                     i+1         2 \
   1367     *          s  = 2*q , and      y  =  2   * ( y - q  ).         (1) \
   1368     *           i      i            i                 i \
   1369     * \
   1370     *      To compute q    from q , one checks whether \
   1371     *                  i+1       i \
   1372     * \
   1373     *                            -(i+1) 2 \
   1374     *                      (q + 2      ) <= y.                     (2) \
   1375     *                        i \
   1376     *                                                            -(i+1) \
   1377     *      If (2) is false, then q   = q ; otherwise q   = q  + 2      . \
   1378     *                             i+1   i             i+1   i \
   1379     * \
   1380     *      With some algebric manipulation, it is not difficult to see \
   1381     *      that (2) is equivalent to \
   1382     *                             -(i+1) \
   1383     *                      s  +  2       <= y                      (3) \
   1384     *                       i                i \
   1385     * \
   1386     *      The advantage of (3) is that s  and y  can be computed by \
   1387     *                                    i      i \
   1388     *      the following recurrence formula: \
   1389     *          if (3) is false \
   1390     * \
   1391     *          s     =  s  ,       y    = y   ;                    (4) \
   1392     *           i+1      i          i+1    i \
   1393     * \
   1394     *          otherwise, \
   1395     *                         -i                     -(i+1) \
   1396     *          s     =  s  + 2  ,  y    = y  -  s  - 2             (5) \
   1397     *           i+1      i          i+1    i     i \
   1398     * \
   1399     * \
   1400     *      One may easily use induction to prove (4) and (5). \
   1401     *      Note. Since the left hand side of (3) contain only i+2 bits, \
   1402     *            it does not necessary to do a full (53-bit) comparison \
   1403     *            in (3). \
   1404     *   3. Final rounding \
   1405     *      After generating the 53 bits result, we compute one more bit. \
   1406     *      Together with the remainder, we can decide whether the \
   1407     *      result is exact, bigger than 1/2ulp, or less than 1/2ulp \
   1408     *      (it will never equal to 1/2ulp). \
   1409     *      The rounding mode can be detected by checking whether \
   1410     *      huge + tiny is equal to huge, and whether huge - tiny is \
   1411     *      equal to huge for some floating point number "huge" and "tiny". \
   1412     * \
   1413     * Special cases: \
   1414     *      sqrt(+-0) = +-0         ... exact \
   1415     *      sqrt(inf) = inf \
   1416     *      sqrt(-ve) = NaN         ... with invalid signal \
   1417     *      sqrt(NaN) = NaN         ... with invalid signal for signaling NaN \
   1418     * \
   1419     */ \
   1420    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \
   1421    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \
   1422    {  \
   1423       const Int    bIGENDIAN = 1; \
   1424       const double one = 1.0, tiny=1.0e-300; \
   1425       double z; \
   1426       Int sign = (Int)0x80000000; \
   1427       Int ix0,s0,q,m,t,i; \
   1428       UInt r,t1,s1,ix1,q1; \
   1429       union { UInt w[2]; double d; } u; \
   1430       u.d = x; \
   1431       ix0 = u.w[1-bIGENDIAN]; \
   1432       ix1 = u.w[bIGENDIAN];    \
   1433       \
   1434       /* take care of Inf and NaN */ \
   1435       if((ix0&0x7ff00000)==0x7ff00000) { \
   1436          return x*x+x;               /* sqrt(NaN)=NaN, sqrt(+inf)=+inf \
   1437                                         sqrt(-inf)=sNaN */ \
   1438       } \
   1439       /* take care of zero */ \
   1440       if(ix0<=0) { \
   1441          if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ \
   1442          else if(ix0<0) \
   1443               return (x-x)/(x-x);             /* sqrt(-ve) = sNaN */ \
   1444       } \
   1445       /* normalize x */ \
   1446       m = (ix0>>20); \
   1447       if(m==0) {                              /* subnormal x */ \
   1448          while(ix0==0) { \
   1449             m -= 21; \
   1450             ix0 |= (ix1>>11); ix1 <<= 21; \
   1451          } \
   1452          for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; \
   1453          m -= i-1; \
   1454          ix0 |= (ix1>>(32-i)); \
   1455          ix1 <<= i; \
   1456       } \
   1457       m -= 1023;      /* unbias exponent */ \
   1458       ix0 = (ix0&0x000fffff)|0x00100000; \
   1459       if(m&1){        /* odd m, double x to make it even */ \
   1460          ix0 += ix0 + ((ix1&sign)>>31); \
   1461          ix1 += ix1; \
   1462       } \
   1463       m >>= 1;        /* m = [m/2] */ \
   1464       /* generate sqrt(x) bit by bit */ \
   1465       ix0 += ix0 + ((ix1&sign)>>31); \
   1466       ix1 += ix1; \
   1467       q = q1 = s0 = s1 = 0;   /* [q,q1] = sqrt(x) */ \
   1468       r = 0x00200000;         /* r = moving bit from right to left */ \
   1469       while(r!=0) { \
   1470          t = s0+r; \
   1471          if(t<=ix0) { \
   1472             s0   = t+r; \
   1473             ix0 -= t; \
   1474             q   += r; \
   1475          } \
   1476          ix0 += ix0 + ((ix1&sign)>>31); \
   1477          ix1 += ix1; \
   1478          r>>=1; \
   1479       } \
   1480       r = sign; \
   1481       while(r!=0) { \
   1482          t1 = s1+r; \
   1483          t  = s0; \
   1484          if((t<ix0)||((t==ix0)&&(t1<=ix1))) { \
   1485             s1  = t1+r; \
   1486             if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1; \
   1487             ix0 -= t; \
   1488             if (ix1 < t1) ix0 -= 1; \
   1489             ix1 -= t1; \
   1490             q1  += r; \
   1491          } \
   1492          ix0 += ix0 + ((ix1&sign)>>31); \
   1493          ix1 += ix1; \
   1494          r>>=1; \
   1495       } \
   1496       /* use floating add to find out rounding direction */ \
   1497       if((ix0|ix1)!=0) { \
   1498          z = one-tiny; /* trigger inexact flag */ \
   1499          if (z>=one) { \
   1500             z = one+tiny; \
   1501             if (q1==(UInt)0xffffffff) { q1=0; q += 1;} \
   1502             else if (z>one) { \
   1503                     if (q1==(UInt)0xfffffffe) q+=1; \
   1504                     q1+=2; \
   1505                  } else \
   1506                     q1 += (q1&1); \
   1507          } \
   1508       } \
   1509       ix0 = (q>>1)+0x3fe00000; \
   1510       ix1 = q1>>1; \
   1511       if ((q&1)==1) ix1 |= sign; \
   1512       ix0 += (m <<20); \
   1513       ix0 = u.w[1-bIGENDIAN] = ix0; \
   1514       ix1 = u.w[bIGENDIAN] = ix1;    \
   1515       z = u.d; \
   1516       return z; \
   1517    }
   1518 
   1519 #if 0
   1520 SQRT_FAST(NONE, sqrt)  /* xlC generates these */
   1521 SQRT_FAST(NONE, _sqrt) /* xlf generates these */
   1522 #else
   1523 SQRT_EXACT(NONE, sqrt)  /* xlC generates these */
   1524 SQRT_EXACT(NONE, _sqrt) /* xlf generates these */
   1525 #endif
   1526 
   1527 #endif /* defined(VGP_ppc32_aix5) */
   1528 
   1529 /*--------------------------------------------------------------------*/
   1530 /*--- end                                                          ---*/
   1531 /*--------------------------------------------------------------------*/
   1532