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*/
123static inline
124Bool 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__))
154static 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
1986int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1987int 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
2005int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2006int 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 */
2025int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2026    (const char* name, const char* value, int overwrite);
2027int 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