xen: Handle XEN_DOMCTL_SHADOW_OP_{GET,SET}_ALLOCATION
[valgrind.git] / shared / vg_replace_strmem.c
blobd4e54492df4ae99fdd0c5eb31229def258ecb340
2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/
4 /*--- simulated CPU. ---*/
5 /*--- vg_replace_strmem.c ---*/
6 /*--------------------------------------------------------------------*/
8 /*
9 This file is part of Valgrind.
11 Copyright (C) 2000-2013 Julian Seward
12 jseward@acm.org
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_tool_basics.h"
33 #include "pub_tool_poolalloc.h"
34 #include "pub_tool_hashtable.h"
35 #include "pub_tool_redir.h"
36 #include "pub_tool_tooliface.h"
37 #include "pub_tool_clreq.h"
39 /* ---------------------------------------------------------------------
40 We have our own versions of these functions for two reasons:
41 (a) it allows us to do overlap checking
42 (b) some of the normal versions are hyper-optimised, which fools
43 Memcheck and cause spurious value warnings. Our versions are
44 simpler.
45 (c) the glibc SSE-variants can read past the end of the input data
46 ranges. This can cause false-positive Memcheck / Helgrind / DRD
47 reports.
49 Note that overenthusiastic use of PLT bypassing by the glibc people also
50 means that we need to patch multiple versions of some of the functions to
51 our own implementations.
53 THEY RUN ON THE SIMD CPU!
54 ------------------------------------------------------------------ */
56 /* Assignment of behavioural equivalence class tags: 2NNNP is intended
57 to be reserved for str/mem intercepts. Current usage:
59 20010 STRRCHR
60 20020 STRCHR
61 20030 STRCAT
62 20040 STRNCAT
63 20050 STRLCAT
64 20060 STRNLEN
65 20070 STRLEN
66 20080 STRCPY
67 20090 STRNCPY
68 20100 STRLCPY
69 20110 STRNCMP
70 20120 STRCASECMP
71 20130 STRNCASECMP
72 20140 STRCASECMP_L
73 20150 STRNCASECMP_L
74 20160 STRCMP
75 20170 MEMCHR
77 20180 MEMCPY if there's a conflict between memcpy and
78 20181 MEMMOVE memmove, prefer memmove
80 20190 MEMCMP
81 20200 STPCPY
82 20210 MEMSET
83 2022P unused (was previously MEMMOVE)
84 20230 BCOPY
85 20240 GLIBC25___MEMMOVE_CHK
86 20250 GLIBC232_STRCHRNUL
87 20260 GLIBC232_RAWMEMCHR
88 20270 GLIBC25___STRCPY_CHK
89 20280 GLIBC25___STPCPY_CHK
90 20290 GLIBC25_MEMPCPY
91 20300 GLIBC26___MEMCPY_CHK
92 20310 STRSTR
93 20320 STRPBRK
94 20330 STRCSPN
95 20340 STRSPN
96 20350 STRCASESTR
97 20360 MEMRCHR
98 20370 WCSLEN
99 20380 WCSCMP
100 20390 WCSCPY
101 20400 WCSCHR
102 20410 WCSRCHR
103 20420 STPNCPY
107 /* Figure out if [dst .. dst+dstlen-1] overlaps with
108 [src .. src+srclen-1].
109 We assume that the address ranges do not wrap around
110 (which is safe since on Linux addresses >= 0xC0000000
111 are not accessible and the program will segfault in this
112 circumstance, presumably).
114 static inline
115 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
117 Addr loS, hiS, loD, hiD;
119 if (dstlen == 0 || srclen == 0)
120 return False;
122 loS = (Addr)src;
123 loD = (Addr)dst;
124 hiS = loS + srclen - 1;
125 hiD = loD + dstlen - 1;
127 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
128 if (loS < loD) {
129 return !(hiS < loD);
131 else if (loD < loS) {
132 return !(hiD < loS);
134 else {
135 /* They start at same place. Since we know neither of them has
136 zero length, they must overlap. */
137 return True;
142 /* Call here to exit if we can't continue. On Android we can't call
143 _exit for some reason, so we have to blunt-instrument it. */
144 __attribute__ ((__noreturn__))
145 static inline void my_exit ( int x )
147 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
148 || defined(VGPV_arm64_linux_android)
149 __asm__ __volatile__(".word 0xFFFFFFFF");
150 while (1) {}
151 # elif defined(VGPV_x86_linux_android)
152 __asm__ __volatile__("ud2");
153 while (1) {}
154 # else
155 extern __attribute__ ((__noreturn__)) void _exit(int status);
156 _exit(x);
157 # endif
161 // This is a macro rather than a function because we don't want to have an
162 // extra function in the stack trace.
163 #ifndef RECORD_OVERLAP_ERROR
164 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
165 #endif
166 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
167 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
168 #endif
171 /*---------------------- strrchr ----------------------*/
173 #define STRRCHR(soname, fnname) \
174 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
175 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
177 HChar ch = (HChar)c; \
178 const HChar* p = s; \
179 const HChar* last = NULL; \
180 while (True) { \
181 if (*p == ch) last = p; \
182 if (*p == 0) return CONST_CAST(HChar *,last); \
183 p++; \
187 // Apparently rindex() is the same thing as strrchr()
188 #if defined(VGO_linux)
189 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
190 STRRCHR(VG_Z_LIBC_SONAME, rindex)
191 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
192 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
193 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
194 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
195 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
196 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
197 || defined(VGPV_mips32_linux_android)
198 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
199 #endif
201 #elif defined(VGO_darwin)
202 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
203 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
204 //STRRCHR(VG_Z_DYLD, strrchr)
205 //STRRCHR(VG_Z_DYLD, rindex)
206 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
207 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
208 STRRCHR(libsystemZucZddylib, strrchr)
209 # endif
211 #endif
214 /*---------------------- strchr ----------------------*/
216 #define STRCHR(soname, fnname) \
217 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
218 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
220 HChar ch = (HChar)c ; \
221 const HChar* p = s; \
222 while (True) { \
223 if (*p == ch) return CONST_CAST(HChar *,p); \
224 if (*p == 0) return NULL; \
225 p++; \
229 // Apparently index() is the same thing as strchr()
230 #if defined(VGO_linux)
231 STRCHR(VG_Z_LIBC_SONAME, strchr)
232 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
233 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
234 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
235 STRCHR(VG_Z_LIBC_SONAME, index)
236 # if !defined(VGP_x86_linux)
237 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
238 STRCHR(VG_Z_LD_LINUX_SO_2, index)
239 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
240 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
241 # endif
243 #elif defined(VGO_darwin)
244 STRCHR(VG_Z_LIBC_SONAME, strchr)
245 # if DARWIN_VERS == DARWIN_10_9
246 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
247 # endif
248 # if DARWIN_VERS == DARWIN_10_10
249 /* _platform_strchr$VARIANT$Generic */
250 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
251 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
252 # endif
253 #endif
256 /*---------------------- strcat ----------------------*/
258 #define STRCAT(soname, fnname) \
259 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
260 ( char* dst, const char* src ); \
261 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
262 ( char* dst, const char* src ) \
264 const HChar* src_orig = src; \
265 HChar* dst_orig = dst; \
266 while (*dst) dst++; \
267 while (*src) *dst++ = *src++; \
268 *dst = 0; \
270 /* This is a bit redundant, I think; any overlap and the strcat will */ \
271 /* go forever... or until a seg fault occurs. */ \
272 if (is_overlap(dst_orig, \
273 src_orig, \
274 (Addr)dst-(Addr)dst_orig+1, \
275 (Addr)src-(Addr)src_orig+1)) \
276 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
278 return dst_orig; \
281 #if defined(VGO_linux)
282 STRCAT(VG_Z_LIBC_SONAME, strcat)
283 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
285 #elif defined(VGO_darwin)
286 //STRCAT(VG_Z_LIBC_SONAME, strcat)
288 #endif
291 /*---------------------- strncat ----------------------*/
293 #define STRNCAT(soname, fnname) \
294 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
295 ( char* dst, const char* src, SizeT n ); \
296 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
297 ( char* dst, const char* src, SizeT n ) \
299 const HChar* src_orig = src; \
300 HChar* dst_orig = dst; \
301 SizeT m = 0; \
303 while (*dst) dst++; \
304 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
305 *dst = 0; /* always add null */ \
307 /* This checks for overlap after copying, unavoidable without */ \
308 /* pre-counting lengths... should be ok */ \
309 if (is_overlap(dst_orig, \
310 src_orig, \
311 (Addr)dst-(Addr)dst_orig+1, \
312 (Addr)src-(Addr)src_orig+1)) \
313 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
315 return dst_orig; \
318 #if defined(VGO_linux)
319 STRNCAT(VG_Z_LIBC_SONAME, strncat)
321 #elif defined(VGO_darwin)
322 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
323 //STRNCAT(VG_Z_DYLD, strncat)
325 #endif
328 /*---------------------- strlcat ----------------------*/
330 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
331 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
332 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
333 Truncation occurred if retval >= n.
335 #define STRLCAT(soname, fnname) \
336 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
337 ( char* dst, const char* src, SizeT n ); \
338 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
339 ( char* dst, const char* src, SizeT n ) \
341 const HChar* src_orig = src; \
342 HChar* dst_orig = dst; \
343 SizeT m = 0; \
345 while (m < n && *dst) { m++; dst++; } \
346 if (m < n) { \
347 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
348 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
349 *dst = 0; \
350 } else { \
351 /* No space to copy anything to dst. m == n */ \
353 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
354 while (*src) { m++; src++; } \
355 /* This checks for overlap after copying, unavoidable without */ \
356 /* pre-counting lengths... should be ok */ \
357 if (is_overlap(dst_orig, \
358 src_orig, \
359 (Addr)dst-(Addr)dst_orig+1, \
360 (Addr)src-(Addr)src_orig+1)) \
361 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
363 return m; \
366 #if defined(VGO_linux)
368 #elif defined(VGO_darwin)
369 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
370 //STRLCAT(VG_Z_DYLD, strlcat)
371 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
373 #endif
376 /*---------------------- strnlen ----------------------*/
378 #define STRNLEN(soname, fnname) \
379 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
380 ( const char* str, SizeT n ); \
381 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
382 ( const char* str, SizeT n ) \
384 SizeT i = 0; \
385 while (i < n && str[i] != 0) i++; \
386 return i; \
389 #if defined(VGO_linux)
390 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
391 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
393 #elif defined(VGO_darwin)
394 # if DARWIN_VERS == DARWIN_10_9
395 STRNLEN(libsystemZucZddylib, strnlen)
396 # endif
398 #endif
401 /*---------------------- strlen ----------------------*/
403 // Note that this replacement often doesn't get used because gcc inlines
404 // calls to strlen() with its own built-in version. This can be very
405 // confusing if you aren't expecting it. Other small functions in
406 // this file may also be inline by gcc.
408 #define STRLEN(soname, fnname) \
409 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
410 ( const char* str ); \
411 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
412 ( const char* str ) \
414 SizeT i = 0; \
415 while (str[i] != 0) i++; \
416 return i; \
419 #if defined(VGO_linux)
420 STRLEN(VG_Z_LIBC_SONAME, strlen)
421 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
422 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
423 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
424 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
425 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
426 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
427 # if defined(VGPV_arm_linux_android) \
428 || defined(VGPV_x86_linux_android) \
429 || defined(VGPV_mips32_linux_android)
430 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
431 # endif
433 #elif defined(VGO_darwin)
434 STRLEN(VG_Z_LIBC_SONAME, strlen)
435 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
436 STRLEN(libsystemZucZddylib, strlen)
437 # endif
438 #endif
441 /*---------------------- strcpy ----------------------*/
443 #define STRCPY(soname, fnname) \
444 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
445 ( char* dst, const char* src ); \
446 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
447 ( char* dst, const char* src ) \
449 const HChar* src_orig = src; \
450 HChar* dst_orig = dst; \
452 while (*src) *dst++ = *src++; \
453 *dst = 0; \
455 /* This checks for overlap after copying, unavoidable without */ \
456 /* pre-counting length... should be ok */ \
457 if (is_overlap(dst_orig, \
458 src_orig, \
459 (Addr)dst-(Addr)dst_orig+1, \
460 (Addr)src-(Addr)src_orig+1)) \
461 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
463 return dst_orig; \
466 #if defined(VGO_linux)
467 STRCPY(VG_Z_LIBC_SONAME, strcpy)
468 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
470 #elif defined(VGO_darwin)
471 STRCPY(VG_Z_LIBC_SONAME, strcpy)
472 # if DARWIN_VERS == DARWIN_10_9
473 STRCPY(libsystemZucZddylib, strcpy)
474 # endif
476 #endif
479 /*---------------------- strncpy ----------------------*/
481 #define STRNCPY(soname, fnname) \
482 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
483 ( char* dst, const char* src, SizeT n ); \
484 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
485 ( char* dst, const char* src, SizeT n ) \
487 const HChar* src_orig = src; \
488 HChar* dst_orig = dst; \
489 SizeT m = 0; \
491 while (m < n && *src) { m++; *dst++ = *src++; } \
492 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
493 /* but only m+1 bytes of src if terminator was found */ \
494 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
495 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
496 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
498 return dst_orig; \
501 #if defined(VGO_linux)
502 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
503 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
504 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
505 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
507 #elif defined(VGO_darwin)
508 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
509 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
510 STRNCPY(libsystemZucZddylib, strncpy)
511 # endif
513 #endif
516 /*---------------------- strlcpy ----------------------*/
518 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
519 Returns strlen(src). Does not zero-fill the remainder of dst. */
520 #define STRLCPY(soname, fnname) \
521 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
522 ( char* dst, const char* src, SizeT n ); \
523 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
524 ( char* dst, const char* src, SizeT n ) \
526 const HChar* src_orig = src; \
527 HChar* dst_orig = dst; \
528 SizeT m = 0; \
530 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
531 /* m non-nul bytes have now been copied, and m <= n-1. */ \
532 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
533 /* but only m+1 bytes of src if terminator was found */ \
534 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
535 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
536 /* Nul-terminate dst. */ \
537 if (n > 0) *dst = 0; \
538 /* Finish counting strlen(src). */ \
539 while (*src) src++; \
540 return src - src_orig; \
543 #if defined(VGO_linux)
545 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
546 || defined(VGPV_mips32_linux_android)
547 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
548 #endif
550 #elif defined(VGO_darwin)
551 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
552 //STRLCPY(VG_Z_DYLD, strlcpy)
553 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
555 #endif
558 /*---------------------- strncmp ----------------------*/
560 #define STRNCMP(soname, fnname) \
561 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
562 ( const char* s1, const char* s2, SizeT nmax ); \
563 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
564 ( const char* s1, const char* s2, SizeT nmax ) \
566 SizeT n = 0; \
567 while (True) { \
568 if (n >= nmax) return 0; \
569 if (*s1 == 0 && *s2 == 0) return 0; \
570 if (*s1 == 0) return -1; \
571 if (*s2 == 0) return 1; \
573 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
574 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
576 s1++; s2++; n++; \
580 #if defined(VGO_linux)
581 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
582 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
583 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
584 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
586 #elif defined(VGO_darwin)
587 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
588 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
589 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
590 # endif
592 #endif
595 /*---------------------- strcasecmp ----------------------*/
597 #define STRCASECMP(soname, fnname) \
598 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
599 ( const char* s1, const char* s2 ); \
600 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
601 ( const char* s1, const char* s2 ) \
603 extern int tolower(int); \
604 register UChar c1; \
605 register UChar c2; \
606 while (True) { \
607 c1 = tolower(*(const UChar *)s1); \
608 c2 = tolower(*(const UChar *)s2); \
609 if (c1 != c2) break; \
610 if (c1 == 0) break; \
611 s1++; s2++; \
613 if ((UChar)c1 < (UChar)c2) return -1; \
614 if ((UChar)c1 > (UChar)c2) return 1; \
615 return 0; \
618 #if defined(VGO_linux)
619 # if !defined(VGPV_arm_linux_android) \
620 && !defined(VGPV_x86_linux_android) \
621 && !defined(VGPV_mips32_linux_android) \
622 && !defined(VGPV_arm64_linux_android)
623 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
624 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
625 # endif
627 #elif defined(VGO_darwin)
628 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
630 #endif
633 /*---------------------- strncasecmp ----------------------*/
635 #define STRNCASECMP(soname, fnname) \
636 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
637 ( const char* s1, const char* s2, SizeT nmax ); \
638 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
639 ( const char* s1, const char* s2, SizeT nmax ) \
641 extern int tolower(int); \
642 SizeT n = 0; \
643 while (True) { \
644 if (n >= nmax) return 0; \
645 if (*s1 == 0 && *s2 == 0) return 0; \
646 if (*s1 == 0) return -1; \
647 if (*s2 == 0) return 1; \
649 if (tolower(*(const UChar *)s1) \
650 < tolower(*(const UChar*)s2)) return -1; \
651 if (tolower(*(const UChar *)s1) \
652 > tolower(*(const UChar *)s2)) return 1; \
654 s1++; s2++; n++; \
658 #if defined(VGO_linux)
659 # if !defined(VGPV_arm_linux_android) \
660 && !defined(VGPV_x86_linux_android) \
661 && !defined(VGPV_mips32_linux_android) \
662 && !defined(VGPV_arm64_linux_android)
663 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
664 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
665 # endif
667 #elif defined(VGO_darwin)
668 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
669 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
671 #endif
674 /*---------------------- strcasecmp_l ----------------------*/
676 #define STRCASECMP_L(soname, fnname) \
677 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
678 ( const char* s1, const char* s2, void* locale ); \
679 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
680 ( const char* s1, const char* s2, void* locale ) \
682 extern int tolower_l(int, void*) __attribute__((weak)); \
683 register UChar c1; \
684 register UChar c2; \
685 while (True) { \
686 c1 = tolower_l(*(const UChar *)s1, locale); \
687 c2 = tolower_l(*(const UChar *)s2, locale); \
688 if (c1 != c2) break; \
689 if (c1 == 0) break; \
690 s1++; s2++; \
692 if ((UChar)c1 < (UChar)c2) return -1; \
693 if ((UChar)c1 > (UChar)c2) return 1; \
694 return 0; \
697 #if defined(VGO_linux)
698 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
699 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
700 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
702 #elif defined(VGO_darwin)
703 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
705 #endif
708 /*---------------------- strncasecmp_l ----------------------*/
710 #define STRNCASECMP_L(soname, fnname) \
711 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
712 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
713 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
714 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
716 extern int tolower_l(int, void*) __attribute__((weak)); \
717 SizeT n = 0; \
718 while (True) { \
719 if (n >= nmax) return 0; \
720 if (*s1 == 0 && *s2 == 0) return 0; \
721 if (*s1 == 0) return -1; \
722 if (*s2 == 0) return 1; \
724 if (tolower_l(*(const UChar *)s1, locale) \
725 < tolower_l(*(const UChar *)s2, locale)) return -1; \
726 if (tolower_l(*(const UChar *)s1, locale) \
727 > tolower_l(*(const UChar *)s2, locale)) return 1; \
729 s1++; s2++; n++; \
733 #if defined(VGO_linux)
734 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
735 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
736 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
738 #elif defined(VGO_darwin)
739 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
740 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
742 #endif
745 /*---------------------- strcmp ----------------------*/
747 #define STRCMP(soname, fnname) \
748 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
749 ( const char* s1, const char* s2 ); \
750 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
751 ( const char* s1, const char* s2 ) \
753 register UChar c1; \
754 register UChar c2; \
755 while (True) { \
756 c1 = *(const UChar *)s1; \
757 c2 = *(const UChar *)s2; \
758 if (c1 != c2) break; \
759 if (c1 == 0) break; \
760 s1++; s2++; \
762 if ((UChar)c1 < (UChar)c2) return -1; \
763 if ((UChar)c1 > (UChar)c2) return 1; \
764 return 0; \
767 #if defined(VGO_linux)
768 STRCMP(VG_Z_LIBC_SONAME, strcmp)
769 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
770 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
771 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
772 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
773 STRCMP(VG_Z_LD64_SO_1, strcmp)
774 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
775 || defined(VGPV_mips32_linux_android)
776 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
777 # endif
779 #elif defined(VGO_darwin)
780 STRCMP(VG_Z_LIBC_SONAME, strcmp)
781 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
782 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
783 # endif
785 #endif
788 /*---------------------- memchr ----------------------*/
790 #define MEMCHR(soname, fnname) \
791 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
792 (const void *s, int c, SizeT n); \
793 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
794 (const void *s, int c, SizeT n) \
796 SizeT i; \
797 UChar c0 = (UChar)c; \
798 const UChar* p = s; \
799 for (i = 0; i < n; i++) \
800 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
801 return NULL; \
804 #if defined(VGO_linux)
805 MEMCHR(VG_Z_LIBC_SONAME, memchr)
806 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
808 #elif defined(VGO_darwin)
809 # if DARWIN_VERS == DARWIN_10_9
810 MEMCHR(VG_Z_DYLD, memchr)
811 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
812 # endif
813 # if DARWIN_VERS == DARWIN_10_10
814 MEMCHR(VG_Z_DYLD, memchr)
815 /* _platform_memchr$VARIANT$Generic */
816 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
817 # endif
819 #endif
822 /*---------------------- memrchr ----------------------*/
824 #define MEMRCHR(soname, fnname) \
825 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
826 (const void *s, int c, SizeT n); \
827 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
828 (const void *s, int c, SizeT n) \
830 SizeT i; \
831 UChar c0 = (UChar)c; \
832 const UChar* p = s; \
833 for (i = 0; i < n; i++) \
834 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
835 return NULL; \
838 #if defined(VGO_linux)
839 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
841 #elif defined(VGO_darwin)
842 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
843 //MEMRCHR(VG_Z_DYLD, memrchr)
845 #endif
848 /*---------------------- memcpy ----------------------*/
850 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
851 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
852 ( void *dst, const void *src, SizeT len ); \
853 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
854 ( void *dst, const void *src, SizeT len ) \
856 if (do_ol_check && is_overlap(dst, src, len, len)) \
857 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
859 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
860 const Addr WM = WS - 1; /* 7 or 3 */ \
862 if (len > 0) { \
863 if (dst < src || !is_overlap(dst, src, len, len)) { \
865 /* Copying backwards. */ \
866 SizeT n = len; \
867 Addr d = (Addr)dst; \
868 Addr s = (Addr)src; \
870 if (((s^d) & WM) == 0) { \
871 /* s and d have same UWord alignment. */ \
872 /* Pull up to a UWord boundary. */ \
873 while ((s & WM) != 0 && n >= 1) \
874 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
875 /* Copy UWords. */ \
876 while (n >= WS) \
877 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
878 if (n == 0) \
879 return dst; \
881 if (((s|d) & 1) == 0) { \
882 /* Both are 16-aligned; copy what we can thusly. */ \
883 while (n >= 2) \
884 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
886 /* Copy leftovers, or everything if misaligned. */ \
887 while (n >= 1) \
888 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
890 } else if (dst > src) { \
892 SizeT n = len; \
893 Addr d = ((Addr)dst) + n; \
894 Addr s = ((Addr)src) + n; \
896 /* Copying forwards. */ \
897 if (((s^d) & WM) == 0) { \
898 /* s and d have same UWord alignment. */ \
899 /* Back down to a UWord boundary. */ \
900 while ((s & WM) != 0 && n >= 1) \
901 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
902 /* Copy UWords. */ \
903 while (n >= WS) \
904 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
905 if (n == 0) \
906 return dst; \
908 if (((s|d) & 1) == 0) { \
909 /* Both are 16-aligned; copy what we can thusly. */ \
910 while (n >= 2) \
911 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
913 /* Copy leftovers, or everything if misaligned. */ \
914 while (n >= 1) \
915 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
920 return dst; \
923 #define MEMMOVE(soname, fnname) \
924 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
926 #define MEMCPY(soname, fnname) \
927 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
929 #if defined(VGO_linux)
930 /* For older memcpy we have to use memmove-like semantics and skip
931 the overlap check; sigh; see #275284. */
932 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
933 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
934 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
935 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
936 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
937 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
938 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
939 /* icc9 blats these around all over the place. Not only in the main
940 executable but various .so's. They are highly tuned and read
941 memory beyond the source boundary (although work correctly and
942 never go across page boundaries), so give errors when run
943 natively, at least for misaligned source arg. Just intercepting
944 in the exe only until we understand more about the problem. See
945 http://bugs.kde.org/show_bug.cgi?id=139776
947 MEMCPY(NONE, ZuintelZufastZumemcpy)
949 #elif defined(VGO_darwin)
950 # if DARWIN_VERS <= DARWIN_10_6
951 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
952 # endif
953 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
954 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
956 #endif
959 /*---------------------- memcmp ----------------------*/
961 #define MEMCMP(soname, fnname) \
962 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
963 ( const void *s1V, const void *s2V, SizeT n ); \
964 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
965 ( const void *s1V, const void *s2V, SizeT n ) \
967 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
968 const SizeT WM = WS - 1; /* 7 or 3 */ \
969 Addr s1A = (Addr)s1V; \
970 Addr s2A = (Addr)s2V; \
972 if (((s1A | s2A) & WM) == 0) { \
973 /* Both areas are word aligned. Skip over the */ \
974 /* equal prefix as fast as possible. */ \
975 while (n >= WS) { \
976 UWord w1 = *(UWord*)s1A; \
977 UWord w2 = *(UWord*)s2A; \
978 if (w1 != w2) break; \
979 s1A += WS; \
980 s2A += WS; \
981 n -= WS; \
985 const UChar* s1 = (const UChar*) s1A; \
986 const UChar* s2 = (const UChar*) s2A; \
988 while (n != 0) { \
989 UChar a0 = s1[0]; \
990 UChar b0 = s2[0]; \
991 s1 += 1; \
992 s2 += 1; \
993 int res = ((int)a0) - ((int)b0); \
994 if (res != 0) \
995 return res; \
996 n -= 1; \
998 return 0; \
1001 #if defined(VGO_linux)
1002 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1003 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1004 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1005 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1006 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1007 MEMCMP(VG_Z_LD_SO_1, bcmp)
1009 #elif defined(VGO_darwin)
1010 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
1011 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1012 # endif
1014 #endif
1017 /*---------------------- stpcpy ----------------------*/
1019 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1020 DEST. (minor variant of strcpy) */
1021 #define STPCPY(soname, fnname) \
1022 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1023 ( char* dst, const char* src ); \
1024 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1025 ( char* dst, const char* src ) \
1027 const HChar* src_orig = src; \
1028 HChar* dst_orig = dst; \
1030 while (*src) *dst++ = *src++; \
1031 *dst = 0; \
1033 /* This checks for overlap after copying, unavoidable without */ \
1034 /* pre-counting length... should be ok */ \
1035 if (is_overlap(dst_orig, \
1036 src_orig, \
1037 (Addr)dst-(Addr)dst_orig+1, \
1038 (Addr)src-(Addr)src_orig+1)) \
1039 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1041 return dst; \
1044 #if defined(VGO_linux)
1045 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1046 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1047 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1048 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1049 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1050 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1052 #elif defined(VGO_darwin)
1053 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1054 //STPCPY(VG_Z_DYLD, stpcpy)
1056 #endif
1059 /*---------------------- stpncpy ----------------------*/
1061 #define STPNCPY(soname, fnname) \
1062 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1063 ( char* dst, const char* src, SizeT n ); \
1064 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1065 ( char* dst, const char* src, SizeT n ) \
1067 const HChar* src_orig = src; \
1068 HChar* dst_str = dst; \
1069 SizeT m = 0; \
1071 while (m < n && *src) { m++; *dst++ = *src++; } \
1072 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1073 /* but only m+1 bytes of src if terminator was found */ \
1074 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1075 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1076 dst_str = dst; \
1077 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1079 return dst_str; \
1082 #if defined(VGO_linux)
1083 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1084 #endif
1087 /*---------------------- memset ----------------------*/
1089 /* Why are we bothering to intercept this? It seems entirely
1090 pointless. */
1092 #define MEMSET(soname, fnname) \
1093 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1094 (void *s, Int c, SizeT n); \
1095 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1096 (void *s, Int c, SizeT n) \
1098 if (sizeof(void*) == 8) { \
1099 Addr a = (Addr)s; \
1100 ULong c8 = (c & 0xFF); \
1101 c8 = (c8 << 8) | c8; \
1102 c8 = (c8 << 16) | c8; \
1103 c8 = (c8 << 32) | c8; \
1104 while ((a & 7) != 0 && n >= 1) \
1105 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1106 while (n >= 8) \
1107 { *(ULong*)a = c8; a += 8; n -= 8; } \
1108 while (n >= 1) \
1109 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1110 return s; \
1111 } else { \
1112 Addr a = (Addr)s; \
1113 UInt c4 = (c & 0xFF); \
1114 c4 = (c4 << 8) | c4; \
1115 c4 = (c4 << 16) | c4; \
1116 while ((a & 3) != 0 && n >= 1) \
1117 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1118 while (n >= 4) \
1119 { *(UInt*)a = c4; a += 4; n -= 4; } \
1120 while (n >= 1) \
1121 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1122 return s; \
1126 #if defined(VGO_linux)
1127 MEMSET(VG_Z_LIBC_SONAME, memset)
1129 #elif defined(VGO_darwin)
1130 //MEMSET(VG_Z_LIBC_SONAME, memset)
1131 //MEMSET(VG_Z_DYLD, memset)
1132 MEMSET(VG_Z_LIBC_SONAME, memset)
1134 #endif
1137 /*---------------------- memmove ----------------------*/
1139 /* memmove -- use the MEMMOVE defn above. */
1141 #if defined(VGO_linux)
1142 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1143 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1145 #elif defined(VGO_darwin)
1146 # if DARWIN_VERS <= DARWIN_10_6
1147 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1148 # endif
1149 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1150 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1151 # if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
1152 /* _platform_memmove$VARIANT$Ivybridge */
1153 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1154 # endif
1155 #endif
1158 /*---------------------- bcopy ----------------------*/
1160 #define BCOPY(soname, fnname) \
1161 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1162 (const void *srcV, void *dstV, SizeT n); \
1163 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1164 (const void *srcV, void *dstV, SizeT n) \
1166 SizeT i; \
1167 HChar* dst = dstV; \
1168 const HChar* src = srcV; \
1169 if (dst < src) { \
1170 for (i = 0; i < n; i++) \
1171 dst[i] = src[i]; \
1173 else \
1174 if (dst > src) { \
1175 for (i = 0; i < n; i++) \
1176 dst[n-i-1] = src[n-i-1]; \
1180 #if defined(VGO_linux)
1181 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1183 #elif defined(VGO_darwin)
1184 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1185 //BCOPY(VG_Z_DYLD, bcopy)
1187 #endif
1190 /*-------------------- memmove_chk --------------------*/
1192 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1193 There is no specific part of glibc that this is copied from. */
1194 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1195 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1196 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1197 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1198 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1200 SizeT i; \
1201 HChar* dst = dstV; \
1202 const HChar* src = srcV; \
1203 if (destlen < n) \
1204 goto badness; \
1205 if (dst < src) { \
1206 for (i = 0; i < n; i++) \
1207 dst[i] = src[i]; \
1209 else \
1210 if (dst > src) { \
1211 for (i = 0; i < n; i++) \
1212 dst[n-i-1] = src[n-i-1]; \
1214 return dst; \
1215 badness: \
1216 VALGRIND_PRINTF_BACKTRACE( \
1217 "*** memmove_chk: buffer overflow detected ***: " \
1218 "program terminated\n"); \
1219 my_exit(127); \
1220 /*NOTREACHED*/ \
1221 return NULL; \
1224 #if defined(VGO_linux)
1225 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1227 #elif defined(VGO_darwin)
1229 #endif
1232 /*-------------------- strchrnul --------------------*/
1234 /* Find the first occurrence of C in S or the final NUL byte. */
1235 #define GLIBC232_STRCHRNUL(soname, fnname) \
1236 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1237 (const char* s, int c_in); \
1238 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1239 (const char* s, int c_in) \
1241 HChar c = (HChar) c_in; \
1242 const HChar* char_ptr = s; \
1243 while (1) { \
1244 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1245 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1246 char_ptr++; \
1250 #if defined(VGO_linux)
1251 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1253 #elif defined(VGO_darwin)
1255 #endif
1258 /*---------------------- rawmemchr ----------------------*/
1260 /* Find the first occurrence of C in S. */
1261 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1262 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1263 (const void* s, int c_in); \
1264 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1265 (const void* s, int c_in) \
1267 UChar c = (UChar) c_in; \
1268 const UChar* char_ptr = s; \
1269 while (1) { \
1270 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1271 char_ptr++; \
1275 #if defined (VGO_linux)
1276 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1277 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1279 #elif defined(VGO_darwin)
1281 #endif
1284 /*---------------------- strcpy_chk ----------------------*/
1286 /* glibc variant of strcpy that checks the dest is big enough.
1287 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1288 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1289 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1290 (char* dst, const char* src, SizeT len); \
1291 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1292 (char* dst, const char* src, SizeT len) \
1294 HChar* ret = dst; \
1295 if (! len) \
1296 goto badness; \
1297 while ((*dst++ = *src++) != '\0') \
1298 if (--len == 0) \
1299 goto badness; \
1300 return ret; \
1301 badness: \
1302 VALGRIND_PRINTF_BACKTRACE( \
1303 "*** strcpy_chk: buffer overflow detected ***: " \
1304 "program terminated\n"); \
1305 my_exit(127); \
1306 /*NOTREACHED*/ \
1307 return NULL; \
1310 #if defined(VGO_linux)
1311 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1313 #elif defined(VGO_darwin)
1315 #endif
1318 /*---------------------- stpcpy_chk ----------------------*/
1320 /* glibc variant of stpcpy that checks the dest is big enough.
1321 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1322 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1323 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1324 (char* dst, const char* src, SizeT len); \
1325 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1326 (char* dst, const char* src, SizeT len) \
1328 if (! len) \
1329 goto badness; \
1330 while ((*dst++ = *src++) != '\0') \
1331 if (--len == 0) \
1332 goto badness; \
1333 return dst - 1; \
1334 badness: \
1335 VALGRIND_PRINTF_BACKTRACE( \
1336 "*** stpcpy_chk: buffer overflow detected ***: " \
1337 "program terminated\n"); \
1338 my_exit(127); \
1339 /*NOTREACHED*/ \
1340 return NULL; \
1343 #if defined(VGO_linux)
1344 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1346 #elif defined(VGO_darwin)
1348 #endif
1351 /*---------------------- mempcpy ----------------------*/
1353 /* mempcpy */
1354 #define GLIBC25_MEMPCPY(soname, fnname) \
1355 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1356 ( void *dst, const void *src, SizeT len ); \
1357 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1358 ( void *dst, const void *src, SizeT len ) \
1360 SizeT len_saved = len; \
1362 if (len == 0) \
1363 return dst; \
1365 if (is_overlap(dst, src, len, len)) \
1366 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1368 if ( dst > src ) { \
1369 register HChar *d = (char *)dst + len - 1; \
1370 register const HChar *s = (const char *)src + len - 1; \
1371 while ( len-- ) { \
1372 *d-- = *s--; \
1374 } else if ( dst < src ) { \
1375 register HChar *d = dst; \
1376 register const HChar *s = src; \
1377 while ( len-- ) { \
1378 *d++ = *s++; \
1381 return (void*)( ((char*)dst) + len_saved ); \
1384 #if defined(VGO_linux)
1385 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1386 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1387 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1388 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1389 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1391 #elif defined(VGO_darwin)
1392 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1394 #endif
1397 /*-------------------- memcpy_chk --------------------*/
1399 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1400 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1401 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1402 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1403 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1405 register HChar *d; \
1406 register const HChar *s; \
1408 if (dstlen < len) goto badness; \
1410 if (len == 0) \
1411 return dst; \
1413 if (is_overlap(dst, src, len, len)) \
1414 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1416 if ( dst > src ) { \
1417 d = (HChar *)dst + len - 1; \
1418 s = (const HChar *)src + len - 1; \
1419 while ( len-- ) { \
1420 *d-- = *s--; \
1422 } else if ( dst < src ) { \
1423 d = (HChar *)dst; \
1424 s = (const HChar *)src; \
1425 while ( len-- ) { \
1426 *d++ = *s++; \
1429 return dst; \
1430 badness: \
1431 VALGRIND_PRINTF_BACKTRACE( \
1432 "*** memcpy_chk: buffer overflow detected ***: " \
1433 "program terminated\n"); \
1434 my_exit(127); \
1435 /*NOTREACHED*/ \
1436 return NULL; \
1439 #if defined(VGO_linux)
1440 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1442 #elif defined(VGO_darwin)
1444 #endif
1447 /*---------------------- strstr ----------------------*/
1449 #define STRSTR(soname, fnname) \
1450 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1451 (const char* haystack, const char* needle); \
1452 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1453 (const char* haystack, const char* needle) \
1455 const HChar* h = haystack; \
1456 const HChar* n = needle; \
1458 /* find the length of n, not including terminating zero */ \
1459 UWord nlen = 0; \
1460 while (n[nlen]) nlen++; \
1462 /* if n is the empty string, match immediately. */ \
1463 if (nlen == 0) return CONST_CAST(HChar *,h); \
1465 /* assert(nlen >= 1); */ \
1466 HChar n0 = n[0]; \
1468 while (1) { \
1469 const HChar hh = *h; \
1470 if (hh == 0) return NULL; \
1471 if (hh != n0) { h++; continue; } \
1473 UWord i; \
1474 for (i = 0; i < nlen; i++) { \
1475 if (n[i] != h[i]) \
1476 break; \
1478 /* assert(i >= 0 && i <= nlen); */ \
1479 if (i == nlen) \
1480 return CONST_CAST(HChar *,h); \
1482 h++; \
1486 #if defined(VGO_linux)
1487 STRSTR(VG_Z_LIBC_SONAME, strstr)
1488 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1489 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1491 #elif defined(VGO_darwin)
1493 #endif
1496 /*---------------------- strpbrk ----------------------*/
1498 #define STRPBRK(soname, fnname) \
1499 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1500 (const char* sV, const char* acceptV); \
1501 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1502 (const char* sV, const char* acceptV) \
1504 const HChar* s = sV; \
1505 const HChar* accept = acceptV; \
1507 /* find the length of 'accept', not including terminating zero */ \
1508 UWord nacc = 0; \
1509 while (accept[nacc]) nacc++; \
1511 /* if n is the empty string, fail immediately. */ \
1512 if (nacc == 0) return NULL; \
1514 /* assert(nacc >= 1); */ \
1515 while (1) { \
1516 UWord i; \
1517 HChar sc = *s; \
1518 if (sc == 0) \
1519 break; \
1520 for (i = 0; i < nacc; i++) { \
1521 if (sc == accept[i]) \
1522 return CONST_CAST(HChar *,s); \
1524 s++; \
1527 return NULL; \
1530 #if defined(VGO_linux)
1531 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1533 #elif defined(VGO_darwin)
1535 #endif
1538 /*---------------------- strcspn ----------------------*/
1540 #define STRCSPN(soname, fnname) \
1541 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1542 (const char* sV, const char* rejectV); \
1543 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1544 (const char* sV, const char* rejectV) \
1546 const HChar* s = sV; \
1547 const HChar* reject = rejectV; \
1549 /* find the length of 'reject', not including terminating zero */ \
1550 UWord nrej = 0; \
1551 while (reject[nrej]) nrej++; \
1553 UWord len = 0; \
1554 while (1) { \
1555 UWord i; \
1556 HChar sc = *s; \
1557 if (sc == 0) \
1558 break; \
1559 for (i = 0; i < nrej; i++) { \
1560 if (sc == reject[i]) \
1561 break; \
1563 /* assert(i >= 0 && i <= nrej); */ \
1564 if (i < nrej) \
1565 break; \
1566 s++; \
1567 len++; \
1570 return len; \
1573 #if defined(VGO_linux)
1574 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1576 #elif defined(VGO_darwin)
1578 #endif
1581 /*---------------------- strspn ----------------------*/
1583 #define STRSPN(soname, fnname) \
1584 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1585 (const char* sV, const char* acceptV); \
1586 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1587 (const char* sV, const char* acceptV) \
1589 const UChar* s = (const UChar *)sV; \
1590 const UChar* accept = (const UChar *)acceptV; \
1592 /* find the length of 'accept', not including terminating zero */ \
1593 UWord nacc = 0; \
1594 while (accept[nacc]) nacc++; \
1595 if (nacc == 0) return 0; \
1597 UWord len = 0; \
1598 while (1) { \
1599 UWord i; \
1600 HChar sc = *s; \
1601 if (sc == 0) \
1602 break; \
1603 for (i = 0; i < nacc; i++) { \
1604 if (sc == accept[i]) \
1605 break; \
1607 /* assert(i >= 0 && i <= nacc); */ \
1608 if (i == nacc) \
1609 break; \
1610 s++; \
1611 len++; \
1614 return len; \
1617 #if defined(VGO_linux)
1618 STRSPN(VG_Z_LIBC_SONAME, strspn)
1620 #elif defined(VGO_darwin)
1622 #endif
1625 /*---------------------- strcasestr ----------------------*/
1627 #define STRCASESTR(soname, fnname) \
1628 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1629 (const char* haystack, const char* needle); \
1630 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1631 (const char* haystack, const char* needle) \
1633 extern int tolower(int); \
1634 const HChar* h = haystack; \
1635 const HChar* n = needle; \
1637 /* find the length of n, not including terminating zero */ \
1638 UWord nlen = 0; \
1639 while (n[nlen]) nlen++; \
1641 /* if n is the empty string, match immediately. */ \
1642 if (nlen == 0) return CONST_CAST(HChar *,h); \
1644 /* assert(nlen >= 1); */ \
1645 UChar n0 = tolower(n[0]); \
1647 while (1) { \
1648 UChar hh = tolower(*h); \
1649 if (hh == 0) return NULL; \
1650 if (hh != n0) { h++; continue; } \
1652 UWord i; \
1653 for (i = 0; i < nlen; i++) { \
1654 if (tolower(n[i]) != tolower(h[i])) \
1655 break; \
1657 /* assert(i >= 0 && i <= nlen); */ \
1658 if (i == nlen) \
1659 return CONST_CAST(HChar *,h); \
1661 h++; \
1665 #if defined(VGO_linux)
1666 # if !defined(VGPV_arm_linux_android) \
1667 && !defined(VGPV_x86_linux_android) \
1668 && !defined(VGPV_mips32_linux_android) \
1669 && !defined(VGPV_arm64_linux_android)
1670 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1671 # endif
1673 #elif defined(VGO_darwin)
1675 #endif
1678 /*---------------------- wcslen ----------------------*/
1680 // This is a wchar_t equivalent to strlen. Unfortunately
1681 // we don't have wchar_t available here, but it looks like
1682 // a 32 bit int on Linux. I don't know if that is also
1683 // valid on MacOSX.
1685 #define WCSLEN(soname, fnname) \
1686 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1687 ( const UInt* str ); \
1688 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1689 ( const UInt* str ) \
1691 SizeT i = 0; \
1692 while (str[i] != 0) i++; \
1693 return i; \
1696 #if defined(VGO_linux)
1697 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1699 #elif defined(VGO_darwin)
1701 #endif
1703 /*---------------------- wcscmp ----------------------*/
1705 // This is a wchar_t equivalent to strcmp. We don't
1706 // have wchar_t available here, but in the GNU C Library
1707 // wchar_t is always 32 bits wide and wcscmp uses signed
1708 // comparison, not unsigned as in strcmp function.
1710 #define WCSCMP(soname, fnname) \
1711 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1712 ( const Int* s1, const Int* s2 ); \
1713 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1714 ( const Int* s1, const Int* s2 ) \
1716 register Int c1; \
1717 register Int c2; \
1718 while (True) { \
1719 c1 = *s1; \
1720 c2 = *s2; \
1721 if (c1 != c2) break; \
1722 if (c1 == 0) break; \
1723 s1++; s2++; \
1725 if (c1 < c2) return -1; \
1726 if (c1 > c2) return 1; \
1727 return 0; \
1730 #if defined(VGO_linux)
1731 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
1732 #endif
1734 /*---------------------- wcscpy ----------------------*/
1736 // This is a wchar_t equivalent to strcpy. We don't
1737 // have wchar_t available here, but in the GNU C Library
1738 // wchar_t is always 32 bits wide.
1740 #define WCSCPY(soname, fnname) \
1741 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1742 ( Int* dst, const Int* src ); \
1743 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1744 ( Int* dst, const Int* src ) \
1746 const Int* src_orig = src; \
1747 Int* dst_orig = dst; \
1749 while (*src) *dst++ = *src++; \
1750 *dst = 0; \
1752 /* This checks for overlap after copying, unavoidable without */ \
1753 /* pre-counting length... should be ok */ \
1754 if (is_overlap(dst_orig, \
1755 src_orig, \
1756 (Addr)dst-(Addr)dst_orig+1, \
1757 (Addr)src-(Addr)src_orig+1)) \
1758 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1760 return dst_orig; \
1763 #if defined(VGO_linux)
1764 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
1765 #endif
1768 /*---------------------- wcschr ----------------------*/
1770 // This is a wchar_t equivalent to strchr. We don't
1771 // have wchar_t available here, but in the GNU C Library
1772 // wchar_t is always 32 bits wide.
1774 #define WCSCHR(soname, fnname) \
1775 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1776 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1778 const Int* p = s; \
1779 while (True) { \
1780 if (*p == c) return CONST_CAST(Int *,p); \
1781 if (*p == 0) return NULL; \
1782 p++; \
1786 #if defined(VGO_linux)
1787 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
1788 #endif
1789 /*---------------------- wcsrchr ----------------------*/
1791 // This is a wchar_t equivalent to strrchr. We don't
1792 // have wchar_t available here, but in the GNU C Library
1793 // wchar_t is always 32 bits wide.
1795 #define WCSRCHR(soname, fnname) \
1796 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1797 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1799 const Int* p = s; \
1800 const Int* last = NULL; \
1801 while (True) { \
1802 if (*p == c) last = p; \
1803 if (*p == 0) return CONST_CAST(Int *,last); \
1804 p++; \
1808 #if defined(VGO_linux)
1809 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
1810 #endif
1812 /*------------------------------------------------------------*/
1813 /*--- Improve definedness checking of process environment ---*/
1814 /*------------------------------------------------------------*/
1816 #if defined(VGO_linux)
1818 /* If these wind up getting generated via a macro, so that multiple
1819 versions of each function exist (as above), use the _EZU variants
1820 to assign equivalance class tags. */
1822 /*---------------------- putenv ----------------------*/
1824 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1825 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1827 OrigFn fn;
1828 Word result;
1829 const HChar* p = string;
1830 VALGRIND_GET_ORIG_FN(fn);
1831 /* Now by walking over the string we magically produce
1832 traces when hitting undefined memory. */
1833 if (p)
1834 while (*p++)
1835 __asm__ __volatile__("" ::: "memory");
1836 CALL_FN_W_W(result, fn, string);
1837 return result;
1841 /*---------------------- unsetenv ----------------------*/
1843 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
1844 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1846 OrigFn fn;
1847 Word result;
1848 const HChar* p = name;
1849 VALGRIND_GET_ORIG_FN(fn);
1850 /* Now by walking over the string we magically produce
1851 traces when hitting undefined memory. */
1852 if (p)
1853 while (*p++)
1854 __asm__ __volatile__("" ::: "memory");
1855 CALL_FN_W_W(result, fn, name);
1856 return result;
1860 /*---------------------- setenv ----------------------*/
1862 /* setenv */
1863 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1864 (const char* name, const char* value, int overwrite);
1865 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1866 (const char* name, const char* value, int overwrite)
1868 OrigFn fn;
1869 Word result;
1870 const HChar* p;
1871 VALGRIND_GET_ORIG_FN(fn);
1872 /* Now by walking over the string we magically produce
1873 traces when hitting undefined memory. */
1874 if (name)
1875 for (p = name; *p; p++)
1876 __asm__ __volatile__("" ::: "memory");
1877 if (value)
1878 for (p = value; *p; p++)
1879 __asm__ __volatile__("" ::: "memory");
1880 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
1881 CALL_FN_W_WWW(result, fn, name, value, overwrite);
1882 return result;
1885 #endif /* defined(VGO_linux) */
1887 /*--------------------------------------------------------------------*/
1888 /*--- end ---*/
1889 /*--------------------------------------------------------------------*/