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