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-2013 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
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).
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)
124 hiS
= loS
+ srclen
- 1;
125 hiD
= loD
+ dstlen
- 1;
127 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
131 else if (loD
< loS
) {
135 /* They start at same place. Since we know neither of them has
136 zero length, they must overlap. */
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");
151 # elif defined(VGPV_x86_linux_android)
152 __asm__
__volatile__("ud2");
155 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
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)
166 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
167 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
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; \
181 if (*p == ch) last = p; \
182 if (*p == 0) return CONST_CAST(HChar *,last); \
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 */
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
)
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; \
223 if (*p == ch) return CONST_CAST(HChar *,p); \
224 if (*p == 0) return NULL; \
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
)
243 #elif defined(VGO_darwin)
244 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
245 # if DARWIN_VERS == DARWIN_10_9
246 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
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
)
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++; \
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, \
274 (Addr)dst-(Addr)dst_orig+1, \
275 (Addr)src-(Addr)src_orig+1)) \
276 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
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)
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; \
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, \
311 (Addr)dst-(Addr)dst_orig+1, \
312 (Addr)src-(Addr)src_orig+1)) \
313 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
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)
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; \
345 while (m < n && *dst) { m++; dst++; } \
347 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
348 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
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, \
359 (Addr)dst-(Addr)dst_orig+1, \
360 (Addr)src-(Addr)src_orig+1)) \
361 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
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
)
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 ) \
385 while (i < n && str[i] != 0) 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
)
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 ) \
415 while (str[i] != 0) 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 */
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
)
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++; \
455 /* This checks for overlap after copying, unavoidable without */ \
456 /* pre-counting length... should be ok */ \
457 if (is_overlap(dst_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); \
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
)
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; \
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 */ \
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
)
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; \
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
);
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
)
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 ) \
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; \
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
)
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); \
607 c1 = tolower(*(const UChar *)s1); \
608 c2 = tolower(*(const UChar *)s2); \
609 if (c1 != c2) break; \
610 if (c1 == 0) break; \
613 if ((UChar)c1 < (UChar)c2) return -1; \
614 if ((UChar)c1 > (UChar)c2) return 1; \
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
)
627 #elif defined(VGO_darwin)
628 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
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); \
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; \
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
)
667 #elif defined(VGO_darwin)
668 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
669 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
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)); \
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; \
692 if ((UChar)c1 < (UChar)c2) return -1; \
693 if ((UChar)c1 > (UChar)c2) return 1; \
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)
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)); \
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; \
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)
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 ) \
756 c1 = *(const UChar *)s1; \
757 c2 = *(const UChar *)s2; \
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 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 */
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
)
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) \
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]); \
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
)
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
)
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) \
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]); \
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)
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 */ \
863 if (dst < src || !is_overlap(dst, src, len, len)) { \
865 /* Copying backwards. */ \
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; } \
877 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
881 if (((s|d) & 1) == 0) { \
882 /* Both are 16-aligned; copy what we can thusly. */ \
884 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
886 /* Copy leftovers, or everything if misaligned. */ \
888 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
890 } else if (dst > src) { \
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; } \
904 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
908 if (((s|d) & 1) == 0) { \
909 /* Both are 16-aligned; copy what we can thusly. */ \
911 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
913 /* Copy leftovers, or everything if misaligned. */ \
915 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
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
)
953 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
954 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
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. */ \
976 UWord w1 = *(UWord*)s1A; \
977 UWord w2 = *(UWord*)s2A; \
978 if (w1 != w2) break; \
985 const UChar* s1 = (const UChar*) s1A; \
986 const UChar* s2 = (const UChar*) s2A; \
993 int res = ((int)a0) - ((int)b0); \
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
)
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++; \
1033 /* This checks for overlap after copying, unavoidable without */ \
1034 /* pre-counting length... should be ok */ \
1035 if (is_overlap(dst_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); \
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)
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; \
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); \
1077 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1082 #if defined(VGO_linux)
1083 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1087 /*---------------------- memset ----------------------*/
1089 /* Why are we bothering to intercept this? It seems entirely
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) { \
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; } \
1107 { *(ULong*)a = c8; a += 8; n -= 8; } \
1109 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
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; } \
1119 { *(UInt*)a = c4; a += 4; n -= 4; } \
1121 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
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
)
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
)
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
)
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) \
1167 HChar* dst = dstV; \
1168 const HChar* src = srcV; \
1170 for (i = 0; i < n; i++) \
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)
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) \
1201 HChar* dst = dstV; \
1202 const HChar* src = srcV; \
1206 for (i = 0; i < n; i++) \
1211 for (i = 0; i < n; i++) \
1212 dst[n-i-1] = src[n-i-1]; \
1216 VALGRIND_PRINTF_BACKTRACE( \
1217 "*** memmove_chk: buffer overflow detected ***: " \
1218 "program terminated\n"); \
1224 #if defined(VGO_linux)
1225 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1227 #elif defined(VGO_darwin)
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; \
1244 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1245 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1250 #if defined(VGO_linux)
1251 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1253 #elif defined(VGO_darwin)
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; \
1270 if (*char_ptr == c) return CONST_CAST(void *,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)
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) \
1297 while ((*dst++ = *src++) != '\0') \
1302 VALGRIND_PRINTF_BACKTRACE( \
1303 "*** strcpy_chk: buffer overflow detected ***: " \
1304 "program terminated\n"); \
1310 #if defined(VGO_linux)
1311 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1313 #elif defined(VGO_darwin)
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) \
1330 while ((*dst++ = *src++) != '\0') \
1335 VALGRIND_PRINTF_BACKTRACE( \
1336 "*** stpcpy_chk: buffer overflow detected ***: " \
1337 "program terminated\n"); \
1343 #if defined(VGO_linux)
1344 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1346 #elif defined(VGO_darwin)
1351 /*---------------------- 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; \
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; \
1374 } else if ( dst < src ) { \
1375 register HChar *d = dst; \
1376 register const HChar *s = src; \
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)
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; \
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; \
1422 } else if ( dst < src ) { \
1424 s = (const HChar *)src; \
1431 VALGRIND_PRINTF_BACKTRACE( \
1432 "*** memcpy_chk: buffer overflow detected ***: " \
1433 "program terminated\n"); \
1439 #if defined(VGO_linux)
1440 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1442 #elif defined(VGO_darwin)
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 */ \
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); */ \
1469 const HChar hh = *h; \
1470 if (hh == 0) return NULL; \
1471 if (hh != n0) { h++; continue; } \
1474 for (i = 0; i < nlen; i++) { \
1478 /* assert(i >= 0 && i <= nlen); */ \
1480 return CONST_CAST(HChar *,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)
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 */ \
1509 while (accept[nacc]) nacc++; \
1511 /* if n is the empty string, fail immediately. */ \
1512 if (nacc == 0) return NULL; \
1514 /* assert(nacc >= 1); */ \
1520 for (i = 0; i < nacc; i++) { \
1521 if (sc == accept[i]) \
1522 return CONST_CAST(HChar *,s); \
1530 #if defined(VGO_linux)
1531 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1533 #elif defined(VGO_darwin)
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 */ \
1551 while (reject[nrej]) nrej++; \
1559 for (i = 0; i < nrej; i++) { \
1560 if (sc == reject[i]) \
1563 /* assert(i >= 0 && i <= nrej); */ \
1573 #if defined(VGO_linux)
1574 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1576 #elif defined(VGO_darwin)
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 */ \
1594 while (accept[nacc]) nacc++; \
1595 if (nacc == 0) return 0; \
1603 for (i = 0; i < nacc; i++) { \
1604 if (sc == accept[i]) \
1607 /* assert(i >= 0 && i <= nacc); */ \
1617 #if defined(VGO_linux)
1618 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1620 #elif defined(VGO_darwin)
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 */ \
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]); \
1648 UChar hh = tolower(*h); \
1649 if (hh == 0) return NULL; \
1650 if (hh != n0) { h++; continue; } \
1653 for (i = 0; i < nlen; i++) { \
1654 if (tolower(n[i]) != tolower(h[i])) \
1657 /* assert(i >= 0 && i <= nlen); */ \
1659 return CONST_CAST(HChar *,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
)
1673 #elif defined(VGO_darwin)
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
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 ) \
1692 while (str[i] != 0) i++; \
1696 #if defined(VGO_linux)
1697 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
1699 #elif defined(VGO_darwin)
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 ) \
1721 if (c1 != c2) break; \
1722 if (c1 == 0) break; \
1725 if (c1 < c2) return -1; \
1726 if (c1 > c2) return 1; \
1730 #if defined(VGO_linux)
1731 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
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++; \
1752 /* This checks for overlap after copying, unavoidable without */ \
1753 /* pre-counting length... should be ok */ \
1754 if (is_overlap(dst_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); \
1763 #if defined(VGO_linux)
1764 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
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 ) \
1780 if (*p == c) return CONST_CAST(Int *,p); \
1781 if (*p == 0) return NULL; \
1786 #if defined(VGO_linux)
1787 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
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 ) \
1800 const Int* last = NULL; \
1802 if (*p == c) last = p; \
1803 if (*p == 0) return CONST_CAST(Int *,last); \
1808 #if defined(VGO_linux)
1809 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
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
)
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. */
1835 __asm__
__volatile__("" ::: "memory");
1836 CALL_FN_W_W(result
, fn
, string
);
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
)
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. */
1854 __asm__
__volatile__("" ::: "memory");
1855 CALL_FN_W_W(result
, fn
, name
);
1860 /*---------------------- 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
)
1871 VALGRIND_GET_ORIG_FN(fn
);
1872 /* Now by walking over the string we magically produce
1873 traces when hitting undefined memory. */
1875 for (p
= name
; *p
; p
++)
1876 __asm__
__volatile__("" ::: "memory");
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
);
1885 #endif /* defined(VGO_linux) */
1887 /*--------------------------------------------------------------------*/
1889 /*--------------------------------------------------------------------*/