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