2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/
4 /*--- simulated CPU. ---*/
5 /*--- vg_replace_strmem.c ---*/
6 /*--------------------------------------------------------------------*/
9 This file is part of Valgrind.
11 Copyright (C) 2000-2015 Julian Seward
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
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
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
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:
77 20180 MEMCPY if there's a conflict between memcpy and
78 20181 MEMMOVE memmove, prefer memmove
83 2022P unused (was previously MEMMOVE)
85 20240 GLIBC25___MEMMOVE_CHK
86 20250 GLIBC232_STRCHRNUL
87 20260 GLIBC232_RAWMEMCHR
88 20270 GLIBC25___STRCPY_CHK
89 20280 GLIBC25___STPCPY_CHK
91 20300 GLIBC26___MEMCPY_CHK
106 #if defined(VGO_solaris)
108 Detour functions in the libc and the runtime linker. If a function isn't
109 much optimized (and no overlap checking is necessary) then redir the
110 function only in the libc. This way we can keep stacktraces in the tests
116 /* Figure out if [dst .. dst+dstlen-1] overlaps with
117 [src .. src+srclen-1].
118 We assume that the address ranges do not wrap around
119 (which is safe since on Linux addresses >= 0xC0000000
120 are not accessible and the program will segfault in this
121 circumstance, presumably).
124 Bool
is_overlap ( void* dst
, const void* src
, SizeT dstlen
, SizeT srclen
)
126 Addr loS
, hiS
, loD
, hiD
;
128 if (dstlen
== 0 || srclen
== 0)
133 hiS
= loS
+ srclen
- 1;
134 hiD
= loD
+ dstlen
- 1;
136 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
140 else if (loD
< loS
) {
144 /* They start at same place. Since we know neither of them has
145 zero length, they must overlap. */
151 /* Call here to exit if we can't continue. On Android we can't call
152 _exit for some reason, so we have to blunt-instrument it. */
153 __attribute__ ((__noreturn__
))
154 static inline void my_exit ( int x
)
156 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
157 || defined(VGPV_arm64_linux_android)
158 __asm__
__volatile__(".word 0xFFFFFFFF");
160 # elif defined(VGPV_x86_linux_android)
161 __asm__
__volatile__("ud2");
164 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
170 // This is a macro rather than a function because we don't want to have an
171 // extra function in the stack trace.
172 #ifndef RECORD_OVERLAP_ERROR
173 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
175 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
176 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
180 /*---------------------- strrchr ----------------------*/
182 #define STRRCHR(soname, fnname) \
183 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
184 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
186 HChar ch = (HChar)c; \
187 const HChar* p = s; \
188 const HChar* last = NULL; \
190 if (*p == ch) last = p; \
191 if (*p == 0) return CONST_CAST(HChar *,last); \
196 // Apparently rindex() is the same thing as strrchr()
197 #if defined(VGO_linux)
198 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
199 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
200 STRRCHR(VG_Z_LIBC_SONAME
, __GI_strrchr
)
201 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2
)
202 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2_no_bsf
)
203 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse42
)
204 STRRCHR(VG_Z_LD_LINUX_SO_2
, rindex
)
205 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
206 || defined(VGPV_mips32_linux_android)
207 STRRCHR(NONE
, __dl_strrchr
); /* in /system/bin/linker */
210 #elif defined(VGO_darwin)
211 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
212 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
213 //STRRCHR(VG_Z_DYLD, strrchr)
214 //STRRCHR(VG_Z_DYLD, rindex)
215 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
216 # if DARWIN_VERS >= DARWIN_10_9
217 STRRCHR(libsystemZucZddylib
, strrchr
)
220 #elif defined(VGO_solaris)
221 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
222 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
223 STRRCHR(VG_Z_LD_SO_1
, strrchr
)
228 /*---------------------- strchr ----------------------*/
230 #define STRCHR(soname, fnname) \
231 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
232 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
234 HChar ch = (HChar)c ; \
235 const HChar* p = s; \
237 if (*p == ch) return CONST_CAST(HChar *,p); \
238 if (*p == 0) return NULL; \
243 // Apparently index() is the same thing as strchr()
244 #if defined(VGO_linux)
245 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
246 STRCHR(VG_Z_LIBC_SONAME
, __GI_strchr
)
247 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2
)
248 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2_no_bsf
)
249 STRCHR(VG_Z_LIBC_SONAME
, index
)
250 # if !defined(VGP_x86_linux)
251 STRCHR(VG_Z_LD_LINUX_SO_2
, strchr
)
252 STRCHR(VG_Z_LD_LINUX_SO_2
, index
)
253 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, strchr
)
254 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, index
)
257 #elif defined(VGO_darwin)
258 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
259 # if DARWIN_VERS == DARWIN_10_9
260 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
262 # if DARWIN_VERS >= DARWIN_10_10
263 /* _platform_strchr$VARIANT$Generic */
264 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
265 /* _platform_strchr$VARIANT$Haswell */
266 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
269 #elif defined(VGO_solaris)
270 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
271 STRCHR(VG_Z_LIBC_SONAME
, index
)
272 STRCHR(VG_Z_LD_SO_1
, strchr
)
277 /*---------------------- strcat ----------------------*/
279 #define STRCAT(soname, fnname) \
280 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
281 ( char* dst, const char* src ); \
282 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
283 ( char* dst, const char* src ) \
285 const HChar* src_orig = src; \
286 HChar* dst_orig = dst; \
287 while (*dst) dst++; \
288 while (*src) *dst++ = *src++; \
291 /* This is a bit redundant, I think; any overlap and the strcat will */ \
292 /* go forever... or until a seg fault occurs. */ \
293 if (is_overlap(dst_orig, \
295 (Addr)dst-(Addr)dst_orig+1, \
296 (Addr)src-(Addr)src_orig+1)) \
297 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
302 #if defined(VGO_linux)
303 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
304 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
306 #elif defined(VGO_darwin)
307 //STRCAT(VG_Z_LIBC_SONAME, strcat)
309 #elif defined(VGO_solaris)
310 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
311 STRCAT(VG_Z_LD_SO_1
, strcat
)
316 /*---------------------- strncat ----------------------*/
318 #define STRNCAT(soname, fnname) \
319 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
320 ( char* dst, const char* src, SizeT n ); \
321 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
322 ( char* dst, const char* src, SizeT n ) \
324 const HChar* src_orig = src; \
325 HChar* dst_orig = dst; \
328 while (*dst) dst++; \
329 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
330 *dst = 0; /* always add null */ \
332 /* This checks for overlap after copying, unavoidable without */ \
333 /* pre-counting lengths... should be ok */ \
334 if (is_overlap(dst_orig, \
336 (Addr)dst-(Addr)dst_orig+1, \
337 (Addr)src-(Addr)src_orig+1)) \
338 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
343 #if defined(VGO_linux)
344 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
346 #elif defined(VGO_darwin)
347 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
348 //STRNCAT(VG_Z_DYLD, strncat)
350 #elif defined(VGO_solaris)
351 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
356 /*---------------------- strlcat ----------------------*/
358 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
359 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
360 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
361 Truncation occurred if retval >= n.
363 #define STRLCAT(soname, fnname) \
364 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
365 ( char* dst, const char* src, SizeT n ); \
366 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
367 ( char* dst, const char* src, SizeT n ) \
369 const HChar* src_orig = src; \
370 HChar* dst_orig = dst; \
373 while (m < n && *dst) { m++; dst++; } \
375 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
376 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
379 /* No space to copy anything to dst. m == n */ \
381 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
382 while (*src) { m++; src++; } \
383 /* This checks for overlap after copying, unavoidable without */ \
384 /* pre-counting lengths... should be ok */ \
385 if (is_overlap(dst_orig, \
387 (Addr)dst-(Addr)dst_orig+1, \
388 (Addr)src-(Addr)src_orig+1)) \
389 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
394 #if defined(VGO_linux)
396 #elif defined(VGO_darwin)
397 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
398 //STRLCAT(VG_Z_DYLD, strlcat)
399 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
401 #elif defined(VGO_solaris)
402 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
407 /*---------------------- strnlen ----------------------*/
409 #define STRNLEN(soname, fnname) \
410 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
411 ( const char* str, SizeT n ); \
412 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
413 ( const char* str, SizeT n ) \
416 while (i < n && str[i] != 0) i++; \
420 #if defined(VGO_linux)
421 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
422 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
424 #elif defined(VGO_darwin)
425 # if DARWIN_VERS == DARWIN_10_9
426 STRNLEN(libsystemZucZddylib
, strnlen
)
429 #elif defined(VGO_solaris)
430 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
435 /*---------------------- strlen ----------------------*/
437 // Note that this replacement often doesn't get used because gcc inlines
438 // calls to strlen() with its own built-in version. This can be very
439 // confusing if you aren't expecting it. Other small functions in
440 // this file may also be inline by gcc.
442 #define STRLEN(soname, fnname) \
443 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
444 ( const char* str ); \
445 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
446 ( const char* str ) \
449 while (str[i] != 0) i++; \
453 #if defined(VGO_linux)
454 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
455 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
456 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
457 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
458 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
459 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
460 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
461 # if defined(VGPV_arm_linux_android) \
462 || defined(VGPV_x86_linux_android) \
463 || defined(VGPV_mips32_linux_android)
464 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
467 #elif defined(VGO_darwin)
468 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
469 # if DARWIN_VERS >= DARWIN_10_9
470 STRLEN(libsystemZucZddylib
, strlen
)
473 #elif defined(VGO_solaris)
474 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
475 STRLEN(VG_Z_LD_SO_1
, strlen
)
480 /*---------------------- strcpy ----------------------*/
482 #define STRCPY(soname, fnname) \
483 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
484 ( char* dst, const char* src ); \
485 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
486 ( char* dst, const char* src ) \
488 const HChar* src_orig = src; \
489 HChar* dst_orig = dst; \
491 while (*src) *dst++ = *src++; \
494 /* This checks for overlap after copying, unavoidable without */ \
495 /* pre-counting length... should be ok */ \
496 if (is_overlap(dst_orig, \
498 (Addr)dst-(Addr)dst_orig+1, \
499 (Addr)src-(Addr)src_orig+1)) \
500 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
505 #if defined(VGO_linux)
506 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
507 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
509 #elif defined(VGO_darwin)
510 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
511 # if DARWIN_VERS == DARWIN_10_9
512 STRCPY(libsystemZucZddylib
, strcpy
)
515 #elif defined(VGO_solaris)
516 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
517 STRCPY(VG_Z_LD_SO_1
, strcpy
)
522 /*---------------------- strncpy ----------------------*/
524 #define STRNCPY(soname, fnname) \
525 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
526 ( char* dst, const char* src, SizeT n ); \
527 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
528 ( char* dst, const char* src, SizeT n ) \
530 const HChar* src_orig = src; \
531 HChar* dst_orig = dst; \
534 while (m < n && *src) { m++; *dst++ = *src++; } \
535 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
536 /* but only m+1 bytes of src if terminator was found */ \
537 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
538 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
539 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
544 #if defined(VGO_linux)
545 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
546 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
547 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
548 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
550 #elif defined(VGO_darwin)
551 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
552 # if DARWIN_VERS >= DARWIN_10_9
553 STRNCPY(libsystemZucZddylib
, strncpy
)
556 #elif defined(VGO_solaris)
557 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
558 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
563 /*---------------------- strlcpy ----------------------*/
565 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
566 Returns strlen(src). Does not zero-fill the remainder of dst. */
567 #define STRLCPY(soname, fnname) \
568 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
569 ( char* dst, const char* src, SizeT n ); \
570 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
571 ( char* dst, const char* src, SizeT n ) \
573 const HChar* src_orig = src; \
574 HChar* dst_orig = dst; \
577 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
579 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
580 /* m non-nul bytes have now been copied, and m <= n-1. */ \
581 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
582 /* but only m+1 bytes of src if terminator was found */ \
583 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
584 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
585 /* Nul-terminate dst. */ \
586 if (n > 0) *dst = 0; \
587 /* Finish counting strlen(src). */ \
588 while (*src) src++; \
589 return src - src_orig; \
592 #if defined(VGO_linux)
594 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
595 || defined(VGPV_mips32_linux_android)
596 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
597 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
600 #elif defined(VGO_darwin)
601 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
602 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
603 //STRLCPY(VG_Z_DYLD, strlcpy)
604 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
606 #elif defined(VGO_solaris)
607 /* special case for n == 0 which is undocumented but heavily used */
608 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
610 while (*src) src++; \
611 return src - src_orig; \
614 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
619 /*---------------------- strncmp ----------------------*/
621 #define STRNCMP(soname, fnname) \
622 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
623 ( const char* s1, const char* s2, SizeT nmax ); \
624 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
625 ( const char* s1, const char* s2, SizeT nmax ) \
629 if (n >= nmax) return 0; \
630 if (*s1 == 0 && *s2 == 0) return 0; \
631 if (*s1 == 0) return -1; \
632 if (*s2 == 0) return 1; \
634 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
635 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
641 #if defined(VGO_linux)
642 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
643 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
644 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
645 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
647 #elif defined(VGO_darwin)
648 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
649 # if DARWIN_VERS >= DARWIN_10_9
650 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
653 #elif defined(VGO_solaris)
654 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
659 /*---------------------- strcasecmp ----------------------*/
661 #define STRCASECMP(soname, fnname) \
662 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
663 ( const char* s1, const char* s2 ); \
664 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
665 ( const char* s1, const char* s2 ) \
667 extern int tolower(int); \
671 c1 = tolower(*(const UChar *)s1); \
672 c2 = tolower(*(const UChar *)s2); \
673 if (c1 != c2) break; \
674 if (c1 == 0) break; \
677 if ((UChar)c1 < (UChar)c2) return -1; \
678 if ((UChar)c1 > (UChar)c2) return 1; \
682 #if defined(VGO_linux)
683 # if !defined(VGPV_arm_linux_android) \
684 && !defined(VGPV_x86_linux_android) \
685 && !defined(VGPV_mips32_linux_android) \
686 && !defined(VGPV_arm64_linux_android)
687 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
688 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
691 #elif defined(VGO_darwin)
692 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
694 #elif defined(VGO_solaris)
695 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
700 /*---------------------- strncasecmp ----------------------*/
702 #define STRNCASECMP(soname, fnname) \
703 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
704 ( const char* s1, const char* s2, SizeT nmax ); \
705 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
706 ( const char* s1, const char* s2, SizeT nmax ) \
708 extern int tolower(int); \
711 if (n >= nmax) return 0; \
712 if (*s1 == 0 && *s2 == 0) return 0; \
713 if (*s1 == 0) return -1; \
714 if (*s2 == 0) return 1; \
716 if (tolower(*(const UChar *)s1) \
717 < tolower(*(const UChar*)s2)) return -1; \
718 if (tolower(*(const UChar *)s1) \
719 > tolower(*(const UChar *)s2)) return 1; \
725 #if defined(VGO_linux)
726 # if !defined(VGPV_arm_linux_android) \
727 && !defined(VGPV_x86_linux_android) \
728 && !defined(VGPV_mips32_linux_android) \
729 && !defined(VGPV_arm64_linux_android)
730 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
731 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
734 #elif defined(VGO_darwin)
735 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
736 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
738 #elif defined(VGO_solaris)
739 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
744 /*---------------------- strcasecmp_l ----------------------*/
746 #define STRCASECMP_L(soname, fnname) \
747 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
748 ( const char* s1, const char* s2, void* locale ); \
749 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
750 ( const char* s1, const char* s2, void* locale ) \
752 extern int tolower_l(int, void*) __attribute__((weak)); \
756 c1 = tolower_l(*(const UChar *)s1, locale); \
757 c2 = tolower_l(*(const UChar *)s2, locale); \
758 if (c1 != c2) break; \
759 if (c1 == 0) break; \
762 if ((UChar)c1 < (UChar)c2) return -1; \
763 if ((UChar)c1 > (UChar)c2) return 1; \
767 #if defined(VGO_linux)
768 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
769 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
770 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
772 #elif defined(VGO_darwin)
773 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
775 #elif defined(VGO_solaris)
780 /*---------------------- strncasecmp_l ----------------------*/
782 #define STRNCASECMP_L(soname, fnname) \
783 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
784 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
785 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
786 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
788 extern int tolower_l(int, void*) __attribute__((weak)); \
791 if (n >= nmax) return 0; \
792 if (*s1 == 0 && *s2 == 0) return 0; \
793 if (*s1 == 0) return -1; \
794 if (*s2 == 0) return 1; \
796 if (tolower_l(*(const UChar *)s1, locale) \
797 < tolower_l(*(const UChar *)s2, locale)) return -1; \
798 if (tolower_l(*(const UChar *)s1, locale) \
799 > tolower_l(*(const UChar *)s2, locale)) return 1; \
805 #if defined(VGO_linux)
806 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
807 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
808 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
810 #elif defined(VGO_darwin)
811 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
812 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
814 #elif defined(VGO_solaris)
819 /*---------------------- strcmp ----------------------*/
821 #define STRCMP(soname, fnname) \
822 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
823 ( const char* s1, const char* s2 ); \
824 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
825 ( const char* s1, const char* s2 ) \
830 c1 = *(const UChar *)s1; \
831 c2 = *(const UChar *)s2; \
832 if (c1 != c2) break; \
833 if (c1 == 0) break; \
836 if ((UChar)c1 < (UChar)c2) return -1; \
837 if ((UChar)c1 > (UChar)c2) return 1; \
841 #if defined(VGO_linux)
842 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
843 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
844 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
845 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
846 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
847 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
848 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
849 || defined(VGPV_mips32_linux_android)
850 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
853 #elif defined(VGO_darwin)
854 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
855 # if DARWIN_VERS >= DARWIN_10_9
856 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
859 #elif defined(VGO_solaris)
860 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
861 STRCMP(VG_Z_LD_SO_1
, strcmp
)
866 /*---------------------- memchr ----------------------*/
868 #define MEMCHR(soname, fnname) \
869 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
870 (const void *s, int c, SizeT n); \
871 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
872 (const void *s, int c, SizeT n) \
875 UChar c0 = (UChar)c; \
876 const UChar* p = s; \
877 for (i = 0; i < n; i++) \
878 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
882 #if defined(VGO_linux)
883 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
884 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
886 #elif defined(VGO_darwin)
887 # if DARWIN_VERS == DARWIN_10_9
888 MEMCHR(VG_Z_DYLD
, memchr
)
889 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
891 # if DARWIN_VERS >= DARWIN_10_10
892 MEMCHR(VG_Z_DYLD
, memchr
)
893 /* _platform_memchr$VARIANT$Generic */
894 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
895 /* _platform_memchr$VARIANT$Haswell */
896 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
899 #elif defined(VGO_solaris)
900 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
905 /*---------------------- memrchr ----------------------*/
907 #define MEMRCHR(soname, fnname) \
908 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
909 (const void *s, int c, SizeT n); \
910 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
911 (const void *s, int c, SizeT n) \
914 UChar c0 = (UChar)c; \
915 const UChar* p = s; \
916 for (i = 0; i < n; i++) \
917 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
921 #if defined(VGO_linux)
922 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
924 #elif defined(VGO_darwin)
925 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
926 //MEMRCHR(VG_Z_DYLD, memrchr)
928 #elif defined(VGO_solaris)
933 /*---------------------- memcpy ----------------------*/
935 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
936 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
937 ( void *dst, const void *src, SizeT len ); \
938 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
939 ( void *dst, const void *src, SizeT len ) \
941 if (do_ol_check && is_overlap(dst, src, len, len)) \
942 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
944 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
945 const Addr WM = WS - 1; /* 7 or 3 */ \
948 if (dst < src || !is_overlap(dst, src, len, len)) { \
950 /* Copying backwards. */ \
952 Addr d = (Addr)dst; \
953 Addr s = (Addr)src; \
955 if (((s^d) & WM) == 0) { \
956 /* s and d have same UWord alignment. */ \
957 /* Pull up to a UWord boundary. */ \
958 while ((s & WM) != 0 && n >= 1) \
959 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
962 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
966 if (((s|d) & 1) == 0) { \
967 /* Both are 16-aligned; copy what we can thusly. */ \
969 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
971 /* Copy leftovers, or everything if misaligned. */ \
973 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
975 } else if (dst > src) { \
978 Addr d = ((Addr)dst) + n; \
979 Addr s = ((Addr)src) + n; \
981 /* Copying forwards. */ \
982 if (((s^d) & WM) == 0) { \
983 /* s and d have same UWord alignment. */ \
984 /* Back down to a UWord boundary. */ \
985 while ((s & WM) != 0 && n >= 1) \
986 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
989 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
993 if (((s|d) & 1) == 0) { \
994 /* Both are 16-aligned; copy what we can thusly. */ \
996 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
998 /* Copy leftovers, or everything if misaligned. */ \
1000 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1008 #define MEMMOVE(soname, fnname) \
1009 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1011 #define MEMCPY(soname, fnname) \
1012 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1014 #if defined(VGO_linux)
1015 /* For older memcpy we have to use memmove-like semantics and skip
1016 the overlap check; sigh; see #275284. */
1017 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1018 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1019 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1020 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1021 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1022 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1023 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1024 /* icc9 blats these around all over the place. Not only in the main
1025 executable but various .so's. They are highly tuned and read
1026 memory beyond the source boundary (although work correctly and
1027 never go across page boundaries), so give errors when run
1028 natively, at least for misaligned source arg. Just intercepting
1029 in the exe only until we understand more about the problem. See
1030 http://bugs.kde.org/show_bug.cgi?id=139776
1032 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1034 #elif defined(VGO_darwin)
1035 # if DARWIN_VERS <= DARWIN_10_6
1036 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1038 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1039 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1041 #elif defined(VGO_solaris)
1042 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1043 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1048 /*---------------------- memcmp ----------------------*/
1050 #define MEMCMP(soname, fnname) \
1051 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1052 ( const void *s1V, const void *s2V, SizeT n ); \
1053 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1054 ( const void *s1V, const void *s2V, SizeT n ) \
1056 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1057 const SizeT WM = WS - 1; /* 7 or 3 */ \
1058 Addr s1A = (Addr)s1V; \
1059 Addr s2A = (Addr)s2V; \
1061 if (((s1A | s2A) & WM) == 0) { \
1062 /* Both areas are word aligned. Skip over the */ \
1063 /* equal prefix as fast as possible. */ \
1065 UWord w1 = *(UWord*)s1A; \
1066 UWord w2 = *(UWord*)s2A; \
1067 if (w1 != w2) break; \
1074 const UChar* s1 = (const UChar*) s1A; \
1075 const UChar* s2 = (const UChar*) s2A; \
1082 int res = ((int)a0) - ((int)b0); \
1090 #if defined(VGO_linux)
1091 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1092 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1093 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1094 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1095 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1096 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1098 #elif defined(VGO_darwin)
1099 # if DARWIN_VERS >= DARWIN_10_9
1100 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1103 #elif defined(VGO_solaris)
1104 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1105 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1106 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1111 /*---------------------- stpcpy ----------------------*/
1113 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1114 DEST. (minor variant of strcpy) */
1115 #define STPCPY(soname, fnname) \
1116 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1117 ( char* dst, const char* src ); \
1118 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1119 ( char* dst, const char* src ) \
1121 const HChar* src_orig = src; \
1122 HChar* dst_orig = dst; \
1124 while (*src) *dst++ = *src++; \
1127 /* This checks for overlap after copying, unavoidable without */ \
1128 /* pre-counting length... should be ok */ \
1129 if (is_overlap(dst_orig, \
1131 (Addr)dst-(Addr)dst_orig+1, \
1132 (Addr)src-(Addr)src_orig+1)) \
1133 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1138 #if defined(VGO_linux)
1139 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1140 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1141 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1142 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1143 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1144 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1146 #elif defined(VGO_darwin)
1147 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1148 //STPCPY(VG_Z_DYLD, stpcpy)
1150 #elif defined(VGO_solaris)
1151 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1156 /*---------------------- stpncpy ----------------------*/
1158 #define STPNCPY(soname, fnname) \
1159 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1160 ( char* dst, const char* src, SizeT n ); \
1161 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1162 ( char* dst, const char* src, SizeT n ) \
1164 const HChar* src_orig = src; \
1165 HChar* dst_str = dst; \
1168 while (m < n && *src) { m++; *dst++ = *src++; } \
1169 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1170 /* but only m+1 bytes of src if terminator was found */ \
1171 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1172 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1174 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1179 #if defined(VGO_linux)
1180 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1184 /*---------------------- memset ----------------------*/
1186 /* Why are we bothering to intercept this? It seems entirely
1189 #define MEMSET(soname, fnname) \
1190 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1191 (void *s, Int c, SizeT n); \
1192 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1193 (void *s, Int c, SizeT n) \
1195 if (sizeof(void*) == 8) { \
1197 ULong c8 = (c & 0xFF); \
1198 c8 = (c8 << 8) | c8; \
1199 c8 = (c8 << 16) | c8; \
1200 c8 = (c8 << 32) | c8; \
1201 while ((a & 7) != 0 && n >= 1) \
1202 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1204 { *(ULong*)a = c8; a += 8; n -= 8; } \
1206 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1210 UInt c4 = (c & 0xFF); \
1211 c4 = (c4 << 8) | c4; \
1212 c4 = (c4 << 16) | c4; \
1213 while ((a & 3) != 0 && n >= 1) \
1214 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1216 { *(UInt*)a = c4; a += 4; n -= 4; } \
1218 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1223 #if defined(VGO_linux)
1224 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1226 #elif defined(VGO_darwin)
1227 //MEMSET(VG_Z_LIBC_SONAME, memset)
1228 //MEMSET(VG_Z_DYLD, memset)
1229 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1231 #elif defined(VGO_solaris)
1232 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1237 /*---------------------- memmove ----------------------*/
1239 /* memmove -- use the MEMMOVE defn above. */
1241 #if defined(VGO_linux)
1242 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1243 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1244 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1245 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1247 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1249 #elif defined(VGO_darwin)
1250 # if DARWIN_VERS <= DARWIN_10_6
1251 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1253 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1254 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1255 # if DARWIN_VERS >= DARWIN_10_9
1256 /* _platform_memmove$VARIANT$Ivybridge */
1257 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1260 #elif defined(VGO_solaris)
1261 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1262 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1267 /*---------------------- bcopy ----------------------*/
1269 #define BCOPY(soname, fnname) \
1270 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1271 (const void *srcV, void *dstV, SizeT n); \
1272 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1273 (const void *srcV, void *dstV, SizeT n) \
1276 HChar* dst = dstV; \
1277 const HChar* src = srcV; \
1279 for (i = 0; i < n; i++) \
1284 for (i = 0; i < n; i++) \
1285 dst[n-i-1] = src[n-i-1]; \
1289 #if defined(VGO_linux)
1290 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1292 #elif defined(VGO_darwin)
1293 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1294 //BCOPY(VG_Z_DYLD, bcopy)
1296 #elif defined(VGO_darwin)
1297 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1302 /*-------------------- memmove_chk --------------------*/
1304 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1305 There is no specific part of glibc that this is copied from. */
1306 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1307 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1308 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1309 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1310 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1313 HChar* dst = dstV; \
1314 const HChar* src = srcV; \
1318 for (i = 0; i < n; i++) \
1323 for (i = 0; i < n; i++) \
1324 dst[n-i-1] = src[n-i-1]; \
1328 VALGRIND_PRINTF_BACKTRACE( \
1329 "*** memmove_chk: buffer overflow detected ***: " \
1330 "program terminated\n"); \
1336 #if defined(VGO_linux)
1337 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1339 #elif defined(VGO_darwin)
1341 #elif defined(VGO_solaris)
1346 /*-------------------- strchrnul --------------------*/
1348 /* Find the first occurrence of C in S or the final NUL byte. */
1349 #define GLIBC232_STRCHRNUL(soname, fnname) \
1350 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1351 (const char* s, int c_in); \
1352 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1353 (const char* s, int c_in) \
1355 HChar c = (HChar) c_in; \
1356 const HChar* char_ptr = s; \
1358 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1359 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1364 #if defined(VGO_linux)
1365 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1367 #elif defined(VGO_darwin)
1369 #elif defined(VGO_solaris)
1374 /*---------------------- rawmemchr ----------------------*/
1376 /* Find the first occurrence of C in S. */
1377 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1378 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1379 (const void* s, int c_in); \
1380 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1381 (const void* s, int c_in) \
1383 UChar c = (UChar) c_in; \
1384 const UChar* char_ptr = s; \
1386 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1391 #if defined (VGO_linux)
1392 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1393 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1395 #elif defined(VGO_darwin)
1397 #elif defined(VGO_solaris)
1402 /*---------------------- strcpy_chk ----------------------*/
1404 /* glibc variant of strcpy that checks the dest is big enough.
1405 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1406 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1407 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1408 (char* dst, const char* src, SizeT len); \
1409 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1410 (char* dst, const char* src, SizeT len) \
1415 while ((*dst++ = *src++) != '\0') \
1420 VALGRIND_PRINTF_BACKTRACE( \
1421 "*** strcpy_chk: buffer overflow detected ***: " \
1422 "program terminated\n"); \
1428 #if defined(VGO_linux)
1429 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1431 #elif defined(VGO_darwin)
1433 #elif defined(VGO_solaris)
1438 /*---------------------- stpcpy_chk ----------------------*/
1440 /* glibc variant of stpcpy that checks the dest is big enough.
1441 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1442 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1443 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1444 (char* dst, const char* src, SizeT len); \
1445 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1446 (char* dst, const char* src, SizeT len) \
1450 while ((*dst++ = *src++) != '\0') \
1455 VALGRIND_PRINTF_BACKTRACE( \
1456 "*** stpcpy_chk: buffer overflow detected ***: " \
1457 "program terminated\n"); \
1463 #if defined(VGO_linux)
1464 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1466 #elif defined(VGO_darwin)
1468 #elif defined(VGO_solaris)
1473 /*---------------------- mempcpy ----------------------*/
1476 #define GLIBC25_MEMPCPY(soname, fnname) \
1477 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1478 ( void *dst, const void *src, SizeT len ); \
1479 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1480 ( void *dst, const void *src, SizeT len ) \
1482 SizeT len_saved = len; \
1487 if (is_overlap(dst, src, len, len)) \
1488 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1490 if ( dst > src ) { \
1491 register HChar *d = (char *)dst + len - 1; \
1492 register const HChar *s = (const char *)src + len - 1; \
1496 } else if ( dst < src ) { \
1497 register HChar *d = dst; \
1498 register const HChar *s = src; \
1503 return (void*)( ((char*)dst) + len_saved ); \
1506 #if defined(VGO_linux)
1507 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1508 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1509 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1510 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1511 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1513 #elif defined(VGO_darwin)
1514 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1516 #elif defined(VGO_solaris)
1521 /*-------------------- memcpy_chk --------------------*/
1523 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1524 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1525 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1526 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1527 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1529 register HChar *d; \
1530 register const HChar *s; \
1532 if (dstlen < len) goto badness; \
1537 if (is_overlap(dst, src, len, len)) \
1538 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1540 if ( dst > src ) { \
1541 d = (HChar *)dst + len - 1; \
1542 s = (const HChar *)src + len - 1; \
1546 } else if ( dst < src ) { \
1548 s = (const HChar *)src; \
1555 VALGRIND_PRINTF_BACKTRACE( \
1556 "*** memcpy_chk: buffer overflow detected ***: " \
1557 "program terminated\n"); \
1563 #if defined(VGO_linux)
1564 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1566 #elif defined(VGO_darwin)
1568 #elif defined(VGO_solaris)
1573 /*---------------------- strstr ----------------------*/
1575 #define STRSTR(soname, fnname) \
1576 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1577 (const char* haystack, const char* needle); \
1578 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1579 (const char* haystack, const char* needle) \
1581 const HChar* h = haystack; \
1582 const HChar* n = needle; \
1584 /* find the length of n, not including terminating zero */ \
1586 while (n[nlen]) nlen++; \
1588 /* if n is the empty string, match immediately. */ \
1589 if (nlen == 0) return CONST_CAST(HChar *,h); \
1591 /* assert(nlen >= 1); */ \
1595 const HChar hh = *h; \
1596 if (hh == 0) return NULL; \
1597 if (hh != n0) { h++; continue; } \
1600 for (i = 0; i < nlen; i++) { \
1604 /* assert(i >= 0 && i <= nlen); */ \
1606 return CONST_CAST(HChar *,h); \
1612 #if defined(VGO_linux)
1613 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1614 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1615 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1617 #elif defined(VGO_darwin)
1619 #elif defined(VGO_solaris)
1620 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1625 /*---------------------- strpbrk ----------------------*/
1627 #define STRPBRK(soname, fnname) \
1628 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1629 (const char* sV, const char* acceptV); \
1630 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1631 (const char* sV, const char* acceptV) \
1633 const HChar* s = sV; \
1634 const HChar* accept = acceptV; \
1636 /* find the length of 'accept', not including terminating zero */ \
1638 while (accept[nacc]) nacc++; \
1640 /* if n is the empty string, fail immediately. */ \
1641 if (nacc == 0) return NULL; \
1643 /* assert(nacc >= 1); */ \
1649 for (i = 0; i < nacc; i++) { \
1650 if (sc == accept[i]) \
1651 return CONST_CAST(HChar *,s); \
1659 #if defined(VGO_linux)
1660 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1662 #elif defined(VGO_darwin)
1664 #elif defined(VGO_solaris)
1665 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1670 /*---------------------- strcspn ----------------------*/
1672 #define STRCSPN(soname, fnname) \
1673 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1674 (const char* sV, const char* rejectV); \
1675 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1676 (const char* sV, const char* rejectV) \
1678 const HChar* s = sV; \
1679 const HChar* reject = rejectV; \
1681 /* find the length of 'reject', not including terminating zero */ \
1683 while (reject[nrej]) nrej++; \
1691 for (i = 0; i < nrej; i++) { \
1692 if (sc == reject[i]) \
1695 /* assert(i >= 0 && i <= nrej); */ \
1705 #if defined(VGO_linux)
1706 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1708 #elif defined(VGO_darwin)
1710 #elif defined(VGO_solaris)
1711 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1716 /*---------------------- strspn ----------------------*/
1718 #define STRSPN(soname, fnname) \
1719 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1720 (const char* sV, const char* acceptV); \
1721 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1722 (const char* sV, const char* acceptV) \
1724 const UChar* s = (const UChar *)sV; \
1725 const UChar* accept = (const UChar *)acceptV; \
1727 /* find the length of 'accept', not including terminating zero */ \
1729 while (accept[nacc]) nacc++; \
1730 if (nacc == 0) return 0; \
1738 for (i = 0; i < nacc; i++) { \
1739 if (sc == accept[i]) \
1742 /* assert(i >= 0 && i <= nacc); */ \
1752 #if defined(VGO_linux)
1753 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1755 #elif defined(VGO_darwin)
1757 #elif defined(VGO_solaris)
1758 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1763 /*---------------------- strcasestr ----------------------*/
1765 #define STRCASESTR(soname, fnname) \
1766 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1767 (const char* haystack, const char* needle); \
1768 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1769 (const char* haystack, const char* needle) \
1771 extern int tolower(int); \
1772 const HChar* h = haystack; \
1773 const HChar* n = needle; \
1775 /* find the length of n, not including terminating zero */ \
1777 while (n[nlen]) nlen++; \
1779 /* if n is the empty string, match immediately. */ \
1780 if (nlen == 0) return CONST_CAST(HChar *,h); \
1782 /* assert(nlen >= 1); */ \
1783 UChar n0 = tolower(n[0]); \
1786 UChar hh = tolower(*h); \
1787 if (hh == 0) return NULL; \
1788 if (hh != n0) { h++; continue; } \
1791 for (i = 0; i < nlen; i++) { \
1792 if (tolower(n[i]) != tolower(h[i])) \
1795 /* assert(i >= 0 && i <= nlen); */ \
1797 return CONST_CAST(HChar *,h); \
1803 #if defined(VGO_linux)
1804 # if !defined(VGPV_arm_linux_android) \
1805 && !defined(VGPV_x86_linux_android) \
1806 && !defined(VGPV_mips32_linux_android) \
1807 && !defined(VGPV_arm64_linux_android)
1808 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
1811 #elif defined(VGO_darwin)
1813 #elif defined(VGO_solaris)
1814 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
1819 /*---------------------- wcslen ----------------------*/
1821 // This is a wchar_t equivalent to strlen. Unfortunately
1822 // we don't have wchar_t available here, but it looks like
1823 // a 32 bit int on Linux. I don't know if that is also
1826 #define WCSLEN(soname, fnname) \
1827 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1828 ( const UInt* str ); \
1829 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1830 ( const UInt* str ) \
1833 while (str[i] != 0) i++; \
1837 #if defined(VGO_linux)
1838 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
1840 #elif defined(VGO_darwin)
1842 #elif defined(VGO_solaris)
1843 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
1847 /*---------------------- wcscmp ----------------------*/
1849 // This is a wchar_t equivalent to strcmp. We don't
1850 // have wchar_t available here, but in the GNU C Library
1851 // wchar_t is always 32 bits wide and wcscmp uses signed
1852 // comparison, not unsigned as in strcmp function.
1854 #define WCSCMP(soname, fnname) \
1855 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1856 ( const Int* s1, const Int* s2 ); \
1857 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1858 ( const Int* s1, const Int* s2 ) \
1865 if (c1 != c2) break; \
1866 if (c1 == 0) break; \
1869 if (c1 < c2) return -1; \
1870 if (c1 > c2) return 1; \
1874 #if defined(VGO_linux)
1875 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
1878 /*---------------------- wcscpy ----------------------*/
1880 // This is a wchar_t equivalent to strcpy. We don't
1881 // have wchar_t available here, but in the GNU C Library
1882 // wchar_t is always 32 bits wide.
1884 #define WCSCPY(soname, fnname) \
1885 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1886 ( Int* dst, const Int* src ); \
1887 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1888 ( Int* dst, const Int* src ) \
1890 const Int* src_orig = src; \
1891 Int* dst_orig = dst; \
1893 while (*src) *dst++ = *src++; \
1896 /* This checks for overlap after copying, unavoidable without */ \
1897 /* pre-counting length... should be ok */ \
1898 if (is_overlap(dst_orig, \
1900 (Addr)dst-(Addr)dst_orig+1, \
1901 (Addr)src-(Addr)src_orig+1)) \
1902 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1907 #if defined(VGO_linux)
1908 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
1912 /*---------------------- wcschr ----------------------*/
1914 // This is a wchar_t equivalent to strchr. We don't
1915 // have wchar_t available here, but in the GNU C Library
1916 // wchar_t is always 32 bits wide.
1918 #define WCSCHR(soname, fnname) \
1919 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1920 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1924 if (*p == c) return CONST_CAST(Int *,p); \
1925 if (*p == 0) return NULL; \
1930 #if defined(VGO_linux)
1931 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
1933 /*---------------------- wcsrchr ----------------------*/
1935 // This is a wchar_t equivalent to strrchr. We don't
1936 // have wchar_t available here, but in the GNU C Library
1937 // wchar_t is always 32 bits wide.
1939 #define WCSRCHR(soname, fnname) \
1940 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1941 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1944 const Int* last = NULL; \
1946 if (*p == c) last = p; \
1947 if (*p == 0) return CONST_CAST(Int *,last); \
1952 #if defined(VGO_linux)
1953 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
1956 /*------------------------------------------------------------*/
1957 /*--- Improve definedness checking of process environment ---*/
1958 /*------------------------------------------------------------*/
1960 #if defined(VGO_linux)
1962 /* If these wind up getting generated via a macro, so that multiple
1963 versions of each function exist (as above), use the _EZU variants
1964 to assign equivalance class tags. */
1966 /*---------------------- putenv ----------------------*/
1968 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
1969 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
1973 const HChar
* p
= string
;
1974 VALGRIND_GET_ORIG_FN(fn
);
1975 /* Now by walking over the string we magically produce
1976 traces when hitting undefined memory. */
1979 __asm__
__volatile__("" ::: "memory");
1980 CALL_FN_W_W(result
, fn
, string
);
1985 /*---------------------- unsetenv ----------------------*/
1987 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
1988 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
1992 const HChar
* p
= name
;
1993 VALGRIND_GET_ORIG_FN(fn
);
1994 /* Now by walking over the string we magically produce
1995 traces when hitting undefined memory. */
1998 __asm__
__volatile__("" ::: "memory");
1999 CALL_FN_W_W(result
, fn
, name
);
2004 /*---------------------- setenv ----------------------*/
2007 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2008 (const char* name
, const char* value
, int overwrite
);
2009 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2010 (const char* name
, const char* value
, int overwrite
)
2015 VALGRIND_GET_ORIG_FN(fn
);
2016 /* Now by walking over the string we magically produce
2017 traces when hitting undefined memory. */
2019 for (p
= name
; *p
; p
++)
2020 __asm__
__volatile__("" ::: "memory");
2022 for (p
= value
; *p
; p
++)
2023 __asm__
__volatile__("" ::: "memory");
2024 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2025 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2029 #endif /* defined(VGO_linux) */
2031 /*--------------------------------------------------------------------*/
2033 /*--------------------------------------------------------------------*/