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