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