• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
110 static inline
is_overlap(void * dst,const void * src,SizeT dstlen,SizeT srclen)111 Bool 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__))
my_exit(int x)141 static 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 
1586 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,putenv)1587 int 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 
1605 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,unsetenv)1606 int 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 */
1625 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1626     (const char* name, const char* value, int overwrite);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,setenv)1627 int 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