1
2/*--------------------------------------------------------------------*/
3/*--- Replacements for strcpy(), memcpy() et al, which run on the  ---*/
4/*--- simulated CPU.                                               ---*/
5/*---                                          mc_replace_strmem.c ---*/
6/*--------------------------------------------------------------------*/
7
8/*
9   This file is part of MemCheck, a heavyweight Valgrind tool for
10   detecting memory errors.
11
12   Copyright (C) 2000-2011 Julian Seward
13      jseward@acm.org
14
15   This program is free software; you can redistribute it and/or
16   modify it under the terms of the GNU General Public License as
17   published by the Free Software Foundation; either version 2 of the
18   License, or (at your option) any later version.
19
20   This program is distributed in the hope that it will be useful, but
21   WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   General Public License for more details.
24
25   You should have received a copy of the GNU General Public License
26   along with this program; if not, write to the Free Software
27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28   02111-1307, USA.
29
30   The GNU General Public License is contained in the file COPYING.
31*/
32
33#include "pub_tool_basics.h"
34#include "pub_tool_hashtable.h"
35#include "pub_tool_redir.h"
36#include "pub_tool_tooliface.h"
37#include "valgrind.h"
38
39#include "mc_include.h"
40#include "memcheck.h"
41
42/* ---------------------------------------------------------------------
43   We have our own versions of these functions for two reasons:
44   (a) it allows us to do overlap checking
45   (b) some of the normal versions are hyper-optimised, which fools
46       Memcheck and cause spurious value warnings.  Our versions are
47       simpler.
48
49   Note that overenthusiastic use of PLT bypassing by the glibc people also
50   means that we need to patch multiple versions of some of the functions to
51   our own implementations.
52
53   THEY RUN ON THE SIMD CPU!
54   ------------------------------------------------------------------ */
55
56/* Assignment of behavioural equivalence class tags: 2NNNP is intended
57   to be reserved for Memcheck.  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*/
98
99
100/* Figure out if [dst .. dst+dstlen-1] overlaps with
101                 [src .. src+srclen-1].
102   We assume that the address ranges do not wrap around
103   (which is safe since on Linux addresses >= 0xC0000000
104   are not accessible and the program will segfault in this
105   circumstance, presumably).
106*/
107static inline
108Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
109{
110   Addr loS, hiS, loD, hiD;
111
112   if (dstlen == 0 || srclen == 0)
113      return False;
114
115   loS = (Addr)src;
116   loD = (Addr)dst;
117   hiS = loS + srclen - 1;
118   hiD = loD + dstlen - 1;
119
120   /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
121   if (loS < loD) {
122      return !(hiS < loD);
123   }
124   else if (loD < loS) {
125      return !(hiD < loS);
126   }
127   else {
128      /* They start at same place.  Since we know neither of them has
129         zero length, they must overlap. */
130      return True;
131   }
132}
133
134
135/* Call here to exit if we can't continue.  On Android we can't call
136   _exit for some reason, so we have to blunt-instrument it. */
137__attribute__ ((__noreturn__))
138static inline void my_exit ( int x )
139{
140#  if defined(VGPV_arm_linux_android)
141   __asm__ __volatile__(".word 0xFFFFFFFF");
142   while (1) {}
143#  else
144   extern __attribute__ ((__noreturn__)) void _exit(int status);
145   _exit(x);
146#  endif
147}
148
149
150// This is a macro rather than a function because we don't want to have an
151// extra function in the stack trace.
152#define RECORD_OVERLAP_ERROR(s, src, dst, len)                  \
153  VALGRIND_DO_CLIENT_REQUEST_STMT(                              \
154                  _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR,   \
155                  s, src, dst, len, 0)
156
157
158/*---------------------- strrchr ----------------------*/
159
160#define STRRCHR(soname, fnname) \
161   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
162   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
163   { \
164      UChar  ch   = (UChar)((UInt)c); \
165      UChar* p    = (UChar*)s; \
166      UChar* last = NULL; \
167      while (True) { \
168         if (*p == ch) last = p; \
169         if (*p == 0) return last; \
170         p++; \
171      } \
172   }
173
174// Apparently rindex() is the same thing as strrchr()
175#if defined(VGO_linux)
176 STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
177 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
178 STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
179 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
180
181#elif defined(VGO_darwin)
182 //STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
183 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
184 STRRCHR(VG_Z_DYLD,          strrchr)
185 STRRCHR(VG_Z_DYLD,          rindex)
186 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
187
188#endif
189
190
191/*---------------------- strchr ----------------------*/
192
193#define STRCHR(soname, fnname) \
194   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
195   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
196   { \
197      UChar  ch = (UChar)((UInt)c); \
198      UChar* p  = (UChar*)s; \
199      while (True) { \
200         if (*p == ch) return p; \
201         if (*p == 0) return NULL; \
202         p++; \
203      } \
204   }
205
206// Apparently index() is the same thing as strchr()
207#if defined(VGO_linux)
208 STRCHR(VG_Z_LIBC_SONAME,          strchr)
209 STRCHR(VG_Z_LIBC_SONAME,          index)
210 STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
211# if !defined(VGP_x86_linux)
212  STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
213  STRCHR(VG_Z_LD_LINUX_SO_2,        index)
214  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
215  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
216# endif
217
218#elif defined(VGO_darwin)
219 //STRCHR(VG_Z_LIBC_SONAME,          strchr)
220 STRCHR(VG_Z_LIBC_SONAME,          index)
221 STRCHR(VG_Z_DYLD,                 strchr)
222 STRCHR(VG_Z_DYLD,                 index)
223 STRCHR(VG_Z_LIBC_SONAME, strchr)
224
225#endif
226
227
228/*---------------------- strcat ----------------------*/
229
230#define STRCAT(soname, fnname) \
231   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
232            ( char* dst, const char* src ); \
233   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
234            ( char* dst, const char* src ) \
235   { \
236      const Char* src_orig = src; \
237            Char* dst_orig = dst; \
238      while (*dst) dst++; \
239      while (*src) *dst++ = *src++; \
240      *dst = 0; \
241      \
242      /* This is a bit redundant, I think;  any overlap and the strcat will */ \
243      /* go forever... or until a seg fault occurs. */ \
244      if (is_overlap(dst_orig,  \
245                     src_orig,  \
246                     (Addr)dst-(Addr)dst_orig+1,  \
247                     (Addr)src-(Addr)src_orig+1)) \
248         RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
249      \
250      return dst_orig; \
251   }
252
253#if defined(VGO_linux)
254 STRCAT(VG_Z_LIBC_SONAME, strcat)
255 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
256
257#elif defined(VGO_darwin)
258 STRCAT(VG_Z_LIBC_SONAME, strcat)
259
260#endif
261
262
263/*---------------------- strncat ----------------------*/
264
265#define STRNCAT(soname, fnname) \
266   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
267            ( char* dst, const char* src, SizeT n ); \
268   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
269            ( char* dst, const char* src, SizeT n ) \
270   { \
271      const Char* src_orig = src; \
272            Char* dst_orig = dst; \
273      SizeT m = 0; \
274      \
275      while (*dst) dst++; \
276      while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
277      *dst = 0;                                       /* always add null   */ \
278      \
279      /* This checks for overlap after copying, unavoidable without */ \
280      /* pre-counting lengths... should be ok */ \
281      if (is_overlap(dst_orig,  \
282                     src_orig,  \
283                     (Addr)dst-(Addr)dst_orig+1, \
284                     (Addr)src-(Addr)src_orig+1)) \
285         RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
286      \
287      return dst_orig; \
288   }
289
290#if defined(VGO_linux)
291 STRNCAT(VG_Z_LIBC_SONAME, strncat)
292
293#elif defined(VGO_darwin)
294 STRNCAT(VG_Z_LIBC_SONAME, strncat)
295 STRNCAT(VG_Z_DYLD,        strncat)
296
297#endif
298
299
300/*---------------------- strlcat ----------------------*/
301
302/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
303   to be nul-terminated after the copy, unless n <= strlen(dst_orig).
304   Returns min(n, strlen(dst_orig)) + strlen(src_orig).
305   Truncation occurred if retval >= n.
306*/
307#define STRLCAT(soname, fnname) \
308   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
309        ( char* dst, const char* src, SizeT n ); \
310   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
311        ( char* dst, const char* src, SizeT n ) \
312   { \
313      const Char* src_orig = src; \
314      Char* dst_orig = dst; \
315      SizeT m = 0; \
316      \
317      while (m < n && *dst) { m++; dst++; } \
318      if (m < n) { \
319         /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
320         while (m < n-1 && *src) { m++; *dst++ = *src++; } \
321         *dst = 0; \
322      } else { \
323         /* No space to copy anything to dst. m == n */ \
324      } \
325      /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
326      while (*src) { m++; src++; } \
327      /* This checks for overlap after copying, unavoidable without */ \
328      /* pre-counting lengths... should be ok */ \
329      if (is_overlap(dst_orig,  \
330                     src_orig,  \
331                     (Addr)dst-(Addr)dst_orig+1,  \
332                     (Addr)src-(Addr)src_orig+1)) \
333         RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
334      \
335      return m; \
336   }
337
338#if defined(VGO_linux)
339
340#elif defined(VGO_darwin)
341 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
342 STRLCAT(VG_Z_DYLD,        strlcat)
343 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
344
345#endif
346
347
348/*---------------------- strnlen ----------------------*/
349
350#define STRNLEN(soname, fnname) \
351   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
352            ( const char* str, SizeT n ); \
353   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
354            ( const char* str, SizeT n ) \
355   { \
356      SizeT i = 0; \
357      while (i < n && str[i] != 0) i++; \
358      return i; \
359   }
360
361#if defined(VGO_linux)
362 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
363 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
364
365#elif defined(VGO_darwin)
366 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
367
368#endif
369
370
371/*---------------------- strlen ----------------------*/
372
373// Note that this replacement often doesn't get used because gcc inlines
374// calls to strlen() with its own built-in version.  This can be very
375// confusing if you aren't expecting it.  Other small functions in
376// this file may also be inline by gcc.
377
378#define STRLEN(soname, fnname) \
379   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
380      ( const char* str ); \
381   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
382      ( const char* str )  \
383   { \
384      SizeT i = 0; \
385      while (str[i] != 0) i++; \
386      return i; \
387   }
388
389#if defined(VGO_linux)
390 STRLEN(VG_Z_LIBC_SONAME,          strlen)
391 STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
392# if defined(VGPV_arm_linux_android)
393  STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
394# endif
395
396#elif defined(VGO_darwin)
397 //STRLEN(VG_Z_LIBC_SONAME,          strlen)
398 STRLEN(VG_Z_LIBC_SONAME, strlen)
399
400#endif
401
402
403/*---------------------- strcpy ----------------------*/
404
405#define STRCPY(soname, fnname) \
406   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
407      ( char* dst, const char* src ); \
408   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
409      ( char* dst, const char* src ) \
410   { \
411      const Char* src_orig = src; \
412            Char* dst_orig = dst; \
413      \
414      while (*src) *dst++ = *src++; \
415      *dst = 0; \
416      \
417      /* This checks for overlap after copying, unavoidable without */ \
418      /* pre-counting length... should be ok */ \
419      if (is_overlap(dst_orig,  \
420                     src_orig,  \
421                     (Addr)dst-(Addr)dst_orig+1, \
422                     (Addr)src-(Addr)src_orig+1)) \
423         RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
424      \
425      return dst_orig; \
426   }
427
428#if defined(VGO_linux)
429 STRCPY(VG_Z_LIBC_SONAME, strcpy)
430 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
431
432#elif defined(VGO_darwin)
433 //STRCPY(VG_Z_LIBC_SONAME, strcpy)
434 STRCPY(VG_Z_DYLD,        strcpy)
435 STRCPY(VG_Z_LIBC_SONAME, strcpy)
436
437#endif
438
439
440/*---------------------- strncpy ----------------------*/
441
442#define STRNCPY(soname, fnname) \
443   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
444            ( char* dst, const char* src, SizeT n ); \
445   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
446            ( char* dst, const char* src, SizeT n ) \
447   { \
448      const Char* src_orig = src; \
449            Char* dst_orig = dst; \
450      SizeT m = 0; \
451      \
452      while (m   < n && *src) { m++; *dst++ = *src++; } \
453      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
454      /* but only m+1 bytes of src if terminator was found */ \
455      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
456         RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
457      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
458      \
459      return dst_orig; \
460   }
461
462#if defined(VGO_linux)
463 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
464 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
465
466#elif defined(VGO_darwin)
467 //STRNCPY(VG_Z_LIBC_SONAME, strncpy)
468 STRNCPY(VG_Z_DYLD,        strncpy)
469 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
470
471#endif
472
473
474/*---------------------- strlcpy ----------------------*/
475
476/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
477   Returns strlen(src). Does not zero-fill the remainder of dst. */
478#define STRLCPY(soname, fnname) \
479   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
480       ( char* dst, const char* src, SizeT n ); \
481   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
482       ( char* dst, const char* src, SizeT n ) \
483   { \
484      const char* src_orig = src; \
485      char* dst_orig = dst; \
486      SizeT m = 0; \
487      \
488      while (m < n-1 && *src) { m++; *dst++ = *src++; } \
489      /* m non-nul bytes have now been copied, and m <= n-1. */ \
490      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
491      /* but only m+1 bytes of src if terminator was found */ \
492      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
493          RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
494      /* Nul-terminate dst. */ \
495      if (n > 0) *dst = 0; \
496      /* Finish counting strlen(src). */ \
497      while (*src) src++; \
498      return src - src_orig; \
499   }
500
501#if defined(VGO_linux)
502
503#elif defined(VGO_darwin)
504 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
505 STRLCPY(VG_Z_DYLD,        strlcpy)
506 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
507
508#endif
509
510
511/*---------------------- strncmp ----------------------*/
512
513#define STRNCMP(soname, fnname) \
514   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
515          ( const char* s1, const char* s2, SizeT nmax ); \
516   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
517          ( const char* s1, const char* s2, SizeT nmax ) \
518   { \
519      SizeT n = 0; \
520      while (True) { \
521         if (n >= nmax) return 0; \
522         if (*s1 == 0 && *s2 == 0) return 0; \
523         if (*s1 == 0) return -1; \
524         if (*s2 == 0) return 1; \
525         \
526         if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
527         if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
528         \
529         s1++; s2++; n++; \
530      } \
531   }
532
533#if defined(VGO_linux)
534 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
535 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
536
537#elif defined(VGO_darwin)
538 //STRNCMP(VG_Z_LIBC_SONAME, strncmp)
539 STRNCMP(VG_Z_DYLD,        strncmp)
540 STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
541
542#endif
543
544
545/*---------------------- strcasecmp ----------------------*/
546
547#define STRCASECMP(soname, fnname) \
548   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
549          ( const char* s1, const char* s2 ); \
550   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
551          ( const char* s1, const char* s2 ) \
552   { \
553      extern int tolower(int); \
554      register unsigned char c1; \
555      register unsigned char c2; \
556      while (True) { \
557         c1 = tolower(*(unsigned char *)s1); \
558         c2 = tolower(*(unsigned char *)s2); \
559         if (c1 != c2) break; \
560         if (c1 == 0) break; \
561         s1++; s2++; \
562      } \
563      if ((unsigned char)c1 < (unsigned char)c2) return -1; \
564      if ((unsigned char)c1 > (unsigned char)c2) return 1; \
565      return 0; \
566   }
567
568#if defined(VGO_linux)
569# if !defined(VGPV_arm_linux_android)
570  STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
571  STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
572# endif
573
574#elif defined(VGO_darwin)
575 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
576
577#endif
578
579
580/*---------------------- strncasecmp ----------------------*/
581
582#define STRNCASECMP(soname, fnname) \
583   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
584          ( const char* s1, const char* s2, SizeT nmax ); \
585   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
586          ( const char* s1, const char* s2, SizeT nmax ) \
587   { \
588      extern int tolower(int); \
589      SizeT n = 0; \
590      while (True) { \
591         if (n >= nmax) return 0; \
592         if (*s1 == 0 && *s2 == 0) return 0; \
593         if (*s1 == 0) return -1; \
594         if (*s2 == 0) return 1; \
595         \
596         if (tolower(*(unsigned char*)s1) \
597             < tolower(*(unsigned char*)s2)) return -1; \
598         if (tolower(*(unsigned char*)s1) \
599             > tolower(*(unsigned char*)s2)) return 1; \
600         \
601         s1++; s2++; n++; \
602      } \
603   }
604
605#if defined(VGO_linux)
606# if !defined(VGPV_arm_linux_android)
607  STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
608  STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
609# endif
610
611#elif defined(VGO_darwin)
612 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
613 STRNCASECMP(VG_Z_DYLD,        strncasecmp)
614
615#endif
616
617
618/*---------------------- strcasecmp_l ----------------------*/
619
620#define STRCASECMP_L(soname, fnname) \
621   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
622          ( const char* s1, const char* s2, void* locale ); \
623   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
624          ( const char* s1, const char* s2, void* locale ) \
625   { \
626      extern int tolower_l(int, void*) __attribute__((weak)); \
627      register unsigned char c1; \
628      register unsigned char c2; \
629      while (True) { \
630         c1 = tolower_l(*(unsigned char *)s1, locale); \
631         c2 = tolower_l(*(unsigned char *)s2, locale); \
632         if (c1 != c2) break; \
633         if (c1 == 0) break; \
634         s1++; s2++; \
635      } \
636      if ((unsigned char)c1 < (unsigned char)c2) return -1; \
637      if ((unsigned char)c1 > (unsigned char)c2) return 1; \
638      return 0; \
639   }
640
641#if defined(VGO_linux)
642 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
643 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
644 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
645
646#elif defined(VGO_darwin)
647 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
648
649#endif
650
651
652/*---------------------- strncasecmp_l ----------------------*/
653
654#define STRNCASECMP_L(soname, fnname) \
655   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
656          ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
657   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
658          ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
659   { \
660      extern int tolower_l(int, void*) __attribute__((weak));    \
661      SizeT n = 0; \
662      while (True) { \
663         if (n >= nmax) return 0; \
664         if (*s1 == 0 && *s2 == 0) return 0; \
665         if (*s1 == 0) return -1; \
666         if (*s2 == 0) return 1; \
667         \
668         if (tolower_l(*(unsigned char*)s1, locale) \
669             < tolower_l(*(unsigned char*)s2, locale)) return -1; \
670         if (tolower_l(*(unsigned char*)s1, locale) \
671             > tolower_l(*(unsigned char*)s2, locale)) return 1; \
672         \
673         s1++; s2++; n++; \
674      } \
675   }
676
677#if defined(VGO_linux)
678 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
679 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
680
681#elif defined(VGO_darwin)
682 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
683 STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
684
685#endif
686
687
688/*---------------------- strcmp ----------------------*/
689
690#define STRCMP(soname, fnname) \
691   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
692          ( const char* s1, const char* s2 ); \
693   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
694          ( const char* s1, const char* s2 ) \
695   { \
696      register unsigned char c1; \
697      register unsigned char c2; \
698      while (True) { \
699         c1 = *(unsigned char *)s1; \
700         c2 = *(unsigned char *)s2; \
701         if (c1 != c2) break; \
702         if (c1 == 0) break; \
703         s1++; s2++; \
704      } \
705      if ((unsigned char)c1 < (unsigned char)c2) return -1; \
706      if ((unsigned char)c1 > (unsigned char)c2) return 1; \
707      return 0; \
708   }
709
710#if defined(VGO_linux)
711 STRCMP(VG_Z_LIBC_SONAME,          strcmp)
712 STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
713 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
714 STRCMP(VG_Z_LD64_SO_1,            strcmp)
715# if defined(VGPV_arm_linux_android)
716  STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
717# endif
718
719#elif defined(VGO_darwin)
720 //STRCMP(VG_Z_LIBC_SONAME,          strcmp)
721 STRCMP(VG_Z_LIBC_SONAME, strcmp)
722
723#endif
724
725
726/*---------------------- memchr ----------------------*/
727
728#define MEMCHR(soname, fnname) \
729   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
730            (const void *s, int c, SizeT n); \
731   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
732            (const void *s, int c, SizeT n) \
733   { \
734      SizeT i; \
735      UChar c0 = (UChar)c; \
736      UChar* p = (UChar*)s; \
737      for (i = 0; i < n; i++) \
738         if (p[i] == c0) return (void*)(&p[i]); \
739      return NULL; \
740   }
741
742#if defined(VGO_linux)
743 MEMCHR(VG_Z_LIBC_SONAME, memchr)
744
745#elif defined(VGO_darwin)
746 MEMCHR(VG_Z_LIBC_SONAME, memchr)
747 MEMCHR(VG_Z_DYLD,        memchr)
748
749#endif
750
751
752/*---------------------- memcpy ----------------------*/
753
754#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
755   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
756            ( void *dst, const void *src, SizeT len ); \
757   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
758            ( void *dst, const void *src, SizeT len ) \
759   { \
760      if (do_ol_check && is_overlap(dst, src, len, len)) \
761         RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
762      \
763      const Addr WS = sizeof(UWord); /* 8 or 4 */ \
764      const Addr WM = WS - 1;        /* 7 or 3 */ \
765      \
766      if (len > 0) { \
767         if (dst < src) { \
768         \
769            /* Copying backwards. */ \
770            SizeT n = len; \
771            Addr  d = (Addr)dst; \
772            Addr  s = (Addr)src; \
773            \
774            if (((s^d) & WM) == 0) { \
775               /* s and d have same UWord alignment. */ \
776               /* Pull up to a UWord boundary. */ \
777               while ((s & WM) != 0 && n >= 1) \
778                  { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
779               /* Copy UWords. */ \
780               while (n >= WS) \
781                  { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
782               if (n == 0) \
783                  return dst; \
784            } \
785            if (((s|d) & 1) == 0) { \
786               /* Both are 16-aligned; copy what we can thusly. */ \
787               while (n >= 2) \
788                  { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
789            } \
790            /* Copy leftovers, or everything if misaligned. */ \
791            while (n >= 1) \
792               { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
793         \
794         } else if (dst > src) { \
795         \
796            SizeT n = len; \
797            Addr  d = ((Addr)dst) + n; \
798            Addr  s = ((Addr)src) + n; \
799            \
800            /* Copying forwards. */ \
801            if (((s^d) & WM) == 0) { \
802               /* s and d have same UWord alignment. */ \
803               /* Back down to a UWord boundary. */ \
804               while ((s & WM) != 0 && n >= 1) \
805                  { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
806               /* Copy UWords. */ \
807               while (n >= WS) \
808                  { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
809               if (n == 0) \
810                  return dst; \
811            } \
812            if (((s|d) & 1) == 0) { \
813               /* Both are 16-aligned; copy what we can thusly. */ \
814               while (n >= 2) \
815                  { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
816            } \
817            /* Copy leftovers, or everything if misaligned. */ \
818            while (n >= 1) \
819               { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
820            \
821         } \
822      } \
823      \
824      return dst; \
825   }
826
827#define MEMMOVE(soname, fnname)  \
828   MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
829
830#define MEMCPY(soname, fnname) \
831   MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
832
833#if defined(VGO_linux)
834 /* For older memcpy we have to use memmove-like semantics and skip
835    the overlap check; sigh; see #275284. */
836 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
837 MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
838 MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
839 MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
840 MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
841 /* icc9 blats these around all over the place.  Not only in the main
842    executable but various .so's.  They are highly tuned and read
843    memory beyond the source boundary (although work correctly and
844    never go across page boundaries), so give errors when run
845    natively, at least for misaligned source arg.  Just intercepting
846    in the exe only until we understand more about the problem.  See
847    http://bugs.kde.org/show_bug.cgi?id=139776
848 */
849 MEMCPY(NONE, ZuintelZufastZumemcpy)
850
851#elif defined(VGO_darwin)
852 // glider: see https://bugs.kde.org/show_bug.cgi?id=285662
853 MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
854 MEMCPY(VG_Z_DYLD,         memcpy)
855 MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
856 MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
857
858#endif
859
860
861/*---------------------- memcmp ----------------------*/
862
863#define MEMCMP(soname, fnname) \
864   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
865          ( const void *s1V, const void *s2V, SizeT n ); \
866   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
867          ( const void *s1V, const void *s2V, SizeT n )  \
868   { \
869      int res; \
870      unsigned char a0; \
871      unsigned char b0; \
872      unsigned char* s1 = (unsigned char*)s1V; \
873      unsigned char* s2 = (unsigned char*)s2V; \
874      \
875      while (n != 0) { \
876         a0 = s1[0]; \
877         b0 = s2[0]; \
878         s1 += 1; \
879         s2 += 1; \
880         res = ((int)a0) - ((int)b0); \
881         if (res != 0) \
882            return res; \
883         n -= 1; \
884      } \
885      return 0; \
886   }
887
888#if defined(VGO_linux)
889 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
890 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
891 MEMCMP(VG_Z_LD_SO_1,     bcmp)
892
893#elif defined(VGO_darwin)
894 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
895 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
896 MEMCMP(VG_Z_DYLD,        memcmp)
897 MEMCMP(VG_Z_DYLD,        bcmp)
898
899#endif
900
901
902/*---------------------- stpcpy ----------------------*/
903
904/* Copy SRC to DEST, returning the address of the terminating '\0' in
905   DEST. (minor variant of strcpy) */
906#define STPCPY(soname, fnname) \
907   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
908            ( char* dst, const char* src ); \
909   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
910            ( char* dst, const char* src ) \
911   { \
912      const Char* src_orig = src; \
913            Char* dst_orig = dst; \
914      \
915      while (*src) *dst++ = *src++; \
916      *dst = 0; \
917      \
918      /* This checks for overlap after copying, unavoidable without */ \
919      /* pre-counting length... should be ok */ \
920      if (is_overlap(dst_orig,  \
921                     src_orig,  \
922                     (Addr)dst-(Addr)dst_orig+1,  \
923                     (Addr)src-(Addr)src_orig+1)) \
924         RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
925      \
926      return dst; \
927   }
928
929#if defined(VGO_linux)
930 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
931 STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
932 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
933 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
934
935#elif defined(VGO_darwin)
936 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
937 STPCPY(VG_Z_DYLD,                 stpcpy)
938
939#endif
940
941
942/*---------------------- memset ----------------------*/
943
944/* Why are we bothering to intercept this?  It seems entirely
945   pointless. */
946
947#define MEMSET(soname, fnname) \
948   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
949            (void *s, Int c, SizeT n); \
950   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
951            (void *s, Int c, SizeT n) \
952   { \
953      Addr a  = (Addr)s;   \
954      UInt c4 = (c & 0xFF); \
955      c4 = (c4 << 8) | c4; \
956      c4 = (c4 << 16) | c4; \
957      while ((a & 3) != 0 && n >= 1) \
958         { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
959      while (n >= 4) \
960         { *(UInt*)a = c4; a += 4; n -= 4; } \
961      while (n >= 1) \
962         { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
963      return s; \
964   }
965
966#if defined(VGO_linux)
967 MEMSET(VG_Z_LIBC_SONAME, memset)
968
969#elif defined(VGO_darwin)
970 //MEMSET(VG_Z_LIBC_SONAME, memset)
971 MEMSET(VG_Z_DYLD,        memset)
972 MEMSET(VG_Z_LIBC_SONAME, memset)
973
974#endif
975
976
977/*---------------------- memmove ----------------------*/
978
979/* memmove -- use the MEMMOVE defn above. */
980
981#if defined(VGO_linux)
982 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
983
984#elif defined(VGO_darwin)
985 // glider: see https://bugs.kde.org/show_bug.cgi?id=285662
986 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
987 MEMMOVE(VG_Z_DYLD,        memmove)
988 MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
989 MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
990
991#endif
992
993
994/*---------------------- bcopy ----------------------*/
995
996#define BCOPY(soname, fnname) \
997   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
998            (const void *srcV, void *dstV, SizeT n); \
999   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1000            (const void *srcV, void *dstV, SizeT n) \
1001   { \
1002      SizeT i; \
1003      Char* dst = (Char*)dstV; \
1004      Char* src = (Char*)srcV; \
1005      if (dst < src) { \
1006         for (i = 0; i < n; i++) \
1007            dst[i] = src[i]; \
1008      } \
1009      else  \
1010      if (dst > src) { \
1011         for (i = 0; i < n; i++) \
1012            dst[n-i-1] = src[n-i-1]; \
1013      } \
1014   }
1015
1016// kcc: enabled bcopy interceptor on non-mac targets.
1017BCOPY(VG_Z_LIBC_SONAME, bcopy)
1018#if defined(VGO_linux)
1019
1020#elif defined(VGO_darwin)
1021 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1022 BCOPY(VG_Z_DYLD,        bcopy)
1023#endif
1024
1025/*-------------------- memmove_chk --------------------*/
1026
1027/* glibc 2.5 variant of memmove which checks the dest is big enough.
1028   There is no specific part of glibc that this is copied from. */
1029#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1030   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1031            (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1032   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1033            (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1034   { \
1035      SizeT i; \
1036      Char* dst = (Char*)dstV; \
1037      Char* src = (Char*)srcV; \
1038      if (destlen < n) \
1039         goto badness; \
1040      if (dst < src) { \
1041         for (i = 0; i < n; i++) \
1042            dst[i] = src[i]; \
1043      } \
1044      else  \
1045      if (dst > src) { \
1046         for (i = 0; i < n; i++) \
1047            dst[n-i-1] = src[n-i-1]; \
1048      } \
1049      return dst; \
1050     badness: \
1051      VALGRIND_PRINTF_BACKTRACE( \
1052         "*** memmove_chk: buffer overflow detected ***: " \
1053         "program terminated\n"); \
1054     my_exit(127); \
1055     /*NOTREACHED*/ \
1056     return NULL; \
1057   }
1058
1059#if defined(VGO_linux)
1060 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1061
1062#elif defined(VGO_darwin)
1063
1064#endif
1065
1066
1067/*-------------------- strchrnul --------------------*/
1068
1069/* Find the first occurrence of C in S or the final NUL byte.  */
1070#define GLIBC232_STRCHRNUL(soname, fnname) \
1071   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1072            (const char* s, int c_in); \
1073   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1074            (const char* s, int c_in) \
1075   { \
1076      unsigned char  c        = (unsigned char) c_in; \
1077      unsigned char* char_ptr = (unsigned char *)s; \
1078      while (1) { \
1079         if (*char_ptr == 0) return char_ptr; \
1080         if (*char_ptr == c) return char_ptr; \
1081         char_ptr++; \
1082      } \
1083   }
1084
1085#if defined(VGO_linux)
1086 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1087
1088#elif defined(VGO_darwin)
1089
1090#endif
1091
1092
1093/*---------------------- rawmemchr ----------------------*/
1094
1095/* Find the first occurrence of C in S.  */
1096#define GLIBC232_RAWMEMCHR(soname, fnname) \
1097   char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1098            (const char* s, int c_in); \
1099   char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1100            (const char* s, int c_in) \
1101   { \
1102      unsigned char  c        = (unsigned char) c_in; \
1103      unsigned char* char_ptr = (unsigned char *)s; \
1104      while (1) { \
1105         if (*char_ptr == c) return char_ptr; \
1106         char_ptr++; \
1107      } \
1108   }
1109
1110#if defined (VGO_linux)
1111 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1112 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1113
1114#elif defined(VGO_darwin)
1115
1116#endif
1117
1118
1119/*---------------------- strcpy_chk ----------------------*/
1120
1121/* glibc variant of strcpy that checks the dest is big enough.
1122   Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1123#define GLIBC25___STRCPY_CHK(soname,fnname) \
1124   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1125            (char* dst, const char* src, SizeT len); \
1126   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1127            (char* dst, const char* src, SizeT len) \
1128   { \
1129      char* ret = dst; \
1130      if (! len) \
1131         goto badness; \
1132      while ((*dst++ = *src++) != '\0') \
1133         if (--len == 0) \
1134            goto badness; \
1135      return ret; \
1136     badness: \
1137      VALGRIND_PRINTF_BACKTRACE( \
1138         "*** strcpy_chk: buffer overflow detected ***: " \
1139         "program terminated\n"); \
1140     my_exit(127); \
1141     /*NOTREACHED*/ \
1142     return NULL; \
1143   }
1144
1145#if defined(VGO_linux)
1146 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1147
1148#elif defined(VGO_darwin)
1149
1150#endif
1151
1152
1153/*---------------------- stpcpy_chk ----------------------*/
1154
1155/* glibc variant of stpcpy that checks the dest is big enough.
1156   Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1157#define GLIBC25___STPCPY_CHK(soname,fnname) \
1158   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1159            (char* dst, const char* src, SizeT len); \
1160   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1161            (char* dst, const char* src, SizeT len) \
1162   { \
1163      if (! len) \
1164         goto badness; \
1165      while ((*dst++ = *src++) != '\0') \
1166         if (--len == 0) \
1167            goto badness; \
1168      return dst - 1; \
1169     badness: \
1170      VALGRIND_PRINTF_BACKTRACE( \
1171         "*** stpcpy_chk: buffer overflow detected ***: " \
1172         "program terminated\n"); \
1173     my_exit(127); \
1174     /*NOTREACHED*/ \
1175     return NULL; \
1176   }
1177
1178#if defined(VGO_linux)
1179 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1180
1181#elif defined(VGO_darwin)
1182
1183#endif
1184
1185
1186/*---------------------- mempcpy ----------------------*/
1187
1188/* mempcpy */
1189#define GLIBC25_MEMPCPY(soname, fnname) \
1190   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1191            ( void *dst, const void *src, SizeT len ); \
1192   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1193            ( void *dst, const void *src, SizeT len ) \
1194   { \
1195      register char *d; \
1196      register char *s; \
1197      SizeT len_saved = len; \
1198      \
1199      if (len == 0) \
1200         return dst; \
1201      \
1202      if (is_overlap(dst, src, len, len)) \
1203         RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1204      \
1205      if ( dst > src ) { \
1206         d = (char *)dst + len - 1; \
1207         s = (char *)src + len - 1; \
1208         while ( len-- ) { \
1209            *d-- = *s--; \
1210         } \
1211      } else if ( dst < src ) { \
1212         d = (char *)dst; \
1213         s = (char *)src; \
1214         while ( len-- ) { \
1215            *d++ = *s++; \
1216         } \
1217      } \
1218      return (void*)( ((char*)dst) + len_saved ); \
1219   }
1220
1221#if defined(VGO_linux)
1222 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1223 GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
1224
1225#elif defined(VGO_darwin)
1226 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1227
1228#endif
1229
1230
1231/*-------------------- memcpy_chk --------------------*/
1232
1233#define GLIBC26___MEMCPY_CHK(soname, fnname) \
1234   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1235            (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1236   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1237            (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1238   { \
1239      register char *d; \
1240      register char *s; \
1241      \
1242      if (dstlen < len) goto badness; \
1243      \
1244      if (len == 0) \
1245         return dst; \
1246      \
1247      if (is_overlap(dst, src, len, len)) \
1248         RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1249      \
1250      if ( dst > src ) { \
1251         d = (char *)dst + len - 1; \
1252         s = (char *)src + len - 1; \
1253         while ( len-- ) { \
1254            *d-- = *s--; \
1255         } \
1256      } else if ( dst < src ) { \
1257         d = (char *)dst; \
1258         s = (char *)src; \
1259         while ( len-- ) { \
1260            *d++ = *s++; \
1261         } \
1262      } \
1263      return dst; \
1264     badness: \
1265      VALGRIND_PRINTF_BACKTRACE( \
1266         "*** memcpy_chk: buffer overflow detected ***: " \
1267         "program terminated\n"); \
1268     my_exit(127); \
1269     /*NOTREACHED*/ \
1270     return NULL; \
1271   }
1272
1273#if defined(VGO_linux)
1274 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1275
1276#elif defined(VGO_darwin)
1277
1278#endif
1279
1280
1281/*---------------------- strstr ----------------------*/
1282
1283#define STRSTR(soname, fnname) \
1284   void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1285         (void* haystack, void* needle); \
1286   void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1287         (void* haystack, void* needle) \
1288   { \
1289      UChar* h = (UChar*)haystack; \
1290      UChar* n = (UChar*)needle; \
1291      \
1292      /* find the length of n, not including terminating zero */ \
1293      UWord nlen = 0; \
1294      while (n[nlen]) nlen++; \
1295      \
1296      /* if n is the empty string, match immediately. */ \
1297      if (nlen == 0) return h; \
1298      \
1299      /* assert(nlen >= 1); */ \
1300      UChar n0 = n[0]; \
1301      \
1302      while (1) { \
1303         UChar hh = *h; \
1304         if (hh == 0) return NULL; \
1305         if (hh != n0) { h++; continue; } \
1306         \
1307         UWord i; \
1308         for (i = 0; i < nlen; i++) { \
1309            if (n[i] != h[i]) \
1310               break; \
1311         } \
1312         /* assert(i >= 0 && i <= nlen); */ \
1313         if (i == nlen) \
1314            return h; \
1315         \
1316         h++; \
1317      } \
1318   }
1319
1320#if defined(VGO_linux)
1321 STRSTR(VG_Z_LIBC_SONAME,          strstr)
1322
1323#elif defined(VGO_darwin)
1324
1325#endif
1326
1327
1328/*---------------------- strpbrk ----------------------*/
1329
1330#define STRPBRK(soname, fnname) \
1331   void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1332         (void* sV, void* acceptV); \
1333   void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1334         (void* sV, void* acceptV) \
1335   { \
1336      UChar* s = (UChar*)sV; \
1337      UChar* accept = (UChar*)acceptV; \
1338      \
1339      /*  find the length of 'accept', not including terminating zero */ \
1340      UWord nacc = 0; \
1341      while (accept[nacc]) nacc++; \
1342      \
1343      /* if n is the empty string, fail immediately. */ \
1344      if (nacc == 0) return NULL; \
1345      \
1346      /* assert(nacc >= 1); */ \
1347      while (1) { \
1348         UWord i; \
1349         UChar sc = *s; \
1350         if (sc == 0) \
1351            break; \
1352         for (i = 0; i < nacc; i++) { \
1353            if (sc == accept[i]) \
1354               return s; \
1355         } \
1356         s++; \
1357      } \
1358      \
1359      return NULL; \
1360   }
1361
1362#if defined(VGO_linux)
1363 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
1364
1365#elif defined(VGO_darwin)
1366
1367#endif
1368
1369
1370/*---------------------- strcspn ----------------------*/
1371
1372#define STRCSPN(soname, fnname) \
1373   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1374         (void* sV, void* rejectV); \
1375   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1376         (void* sV, void* rejectV) \
1377   { \
1378      UChar* s = (UChar*)sV; \
1379      UChar* reject = (UChar*)rejectV; \
1380      \
1381      /* find the length of 'reject', not including terminating zero */ \
1382      UWord nrej = 0; \
1383      while (reject[nrej]) nrej++; \
1384      \
1385      UWord len = 0; \
1386      while (1) { \
1387         UWord i; \
1388         UChar sc = *s; \
1389         if (sc == 0) \
1390            break; \
1391         for (i = 0; i < nrej; i++) { \
1392            if (sc == reject[i]) \
1393               break; \
1394         } \
1395         /* assert(i >= 0 && i <= nrej); */ \
1396         if (i < nrej) \
1397            break; \
1398         s++; \
1399         len++; \
1400      } \
1401      \
1402      return len; \
1403   }
1404
1405#if defined(VGO_linux)
1406 STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
1407
1408#elif defined(VGO_darwin)
1409
1410#endif
1411
1412
1413/*---------------------- strspn ----------------------*/
1414
1415#define STRSPN(soname, fnname) \
1416   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1417         (void* sV, void* acceptV); \
1418   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1419         (void* sV, void* acceptV) \
1420   { \
1421      UChar* s = (UChar*)sV; \
1422      UChar* accept = (UChar*)acceptV; \
1423      \
1424      /* find the length of 'accept', not including terminating zero */ \
1425      UWord nacc = 0; \
1426      while (accept[nacc]) nacc++; \
1427      if (nacc == 0) return 0; \
1428      \
1429      UWord len = 0; \
1430      while (1) { \
1431         UWord i; \
1432         UChar sc = *s; \
1433         if (sc == 0) \
1434            break; \
1435         for (i = 0; i < nacc; i++) { \
1436            if (sc == accept[i]) \
1437               break; \
1438         } \
1439         /* assert(i >= 0 && i <= nacc); */ \
1440         if (i == nacc) \
1441            break; \
1442         s++; \
1443         len++; \
1444      } \
1445      \
1446      return len; \
1447   }
1448
1449#if defined(VGO_linux)
1450 STRSPN(VG_Z_LIBC_SONAME,          strspn)
1451
1452#elif defined(VGO_darwin)
1453
1454#endif
1455
1456
1457/*---------------------- strcasestr ----------------------*/
1458
1459#define STRCASESTR(soname, fnname) \
1460   void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1461         (void* haystack, void* needle); \
1462   void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1463         (void* haystack, void* needle) \
1464   { \
1465      extern int tolower(int); \
1466      UChar* h = (UChar*)haystack; \
1467      UChar* n = (UChar*)needle; \
1468      \
1469      /* find the length of n, not including terminating zero */ \
1470      UWord nlen = 0; \
1471      while (n[nlen]) nlen++; \
1472      \
1473      /* if n is the empty string, match immediately. */ \
1474      if (nlen == 0) return h; \
1475      \
1476      /* assert(nlen >= 1); */ \
1477      UChar n0 = tolower(n[0]);                 \
1478      \
1479      while (1) { \
1480         UChar hh = tolower(*h);    \
1481         if (hh == 0) return NULL; \
1482         if (hh != n0) { h++; continue; } \
1483         \
1484         UWord i; \
1485         for (i = 0; i < nlen; i++) { \
1486            if (tolower(n[i]) != tolower(h[i]))  \
1487               break; \
1488         } \
1489         /* assert(i >= 0 && i <= nlen); */ \
1490         if (i == nlen) \
1491            return h; \
1492         \
1493         h++; \
1494      } \
1495   }
1496
1497#if defined(VGO_linux)
1498 STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
1499
1500#elif defined(VGO_darwin)
1501
1502#endif
1503
1504
1505/*------------------------------------------------------------*/
1506/*--- Improve definedness checking of process environment  ---*/
1507/*------------------------------------------------------------*/
1508
1509#if defined(VGO_linux)
1510
1511/* If these wind up getting generated via a macro, so that multiple
1512   versions of each function exist (as above), use the _EZU variants
1513   to assign equivalance class tags. */
1514
1515/*---------------------- putenv ----------------------*/
1516
1517int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1518int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1519{
1520    OrigFn fn;
1521    Word result;
1522    const char* p = string;
1523    VALGRIND_GET_ORIG_FN(fn);
1524    /* Now by walking over the string we magically produce
1525       traces when hitting undefined memory. */
1526    if (p)
1527        while (*p++)
1528            __asm__ __volatile__("" ::: "memory");
1529    CALL_FN_W_W(result, fn, string);
1530    return result;
1531}
1532
1533
1534/*---------------------- unsetenv ----------------------*/
1535
1536int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
1537int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1538{
1539    OrigFn fn;
1540    Word result;
1541    const char* p = name;
1542    VALGRIND_GET_ORIG_FN(fn);
1543    /* Now by walking over the string we magically produce
1544       traces when hitting undefined memory. */
1545    if (p)
1546        while (*p++)
1547            __asm__ __volatile__("" ::: "memory");
1548    CALL_FN_W_W(result, fn, name);
1549    return result;
1550}
1551
1552
1553/*---------------------- setenv ----------------------*/
1554
1555/* setenv */
1556int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1557    (const char* name, const char* value, int overwrite);
1558int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1559    (const char* name, const char* value, int overwrite)
1560{
1561    OrigFn fn;
1562    Word result;
1563    const char* p;
1564    VALGRIND_GET_ORIG_FN(fn);
1565    /* Now by walking over the string we magically produce
1566       traces when hitting undefined memory. */
1567    if (name)
1568        for (p = name; *p; p++)
1569            __asm__ __volatile__("" ::: "memory");
1570    if (value)
1571        for (p = value; *p; p++)
1572            __asm__ __volatile__("" ::: "memory");
1573    VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
1574    CALL_FN_W_WWW(result, fn, name, value, overwrite);
1575    return result;
1576}
1577
1578#endif /* defined(VGO_linux) */
1579
1580/*--------------------------------------------------------------------*/
1581/*--- end                                                          ---*/
1582/*--------------------------------------------------------------------*/
1583