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-2017 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) && !defined(VGP_amd64_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 #if defined(VGPV_mips32_linux_android)
258 STRCHR(NONE
, __dl_strchr
)
261 #elif defined(VGO_darwin)
262 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
263 # if DARWIN_VERS == DARWIN_10_9
264 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
266 # if DARWIN_VERS >= DARWIN_10_10
267 /* _platform_strchr$VARIANT$Generic */
268 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
269 /* _platform_strchr$VARIANT$Haswell */
270 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
273 #elif defined(VGO_solaris)
274 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
275 STRCHR(VG_Z_LIBC_SONAME
, index
)
276 STRCHR(VG_Z_LD_SO_1
, strchr
)
281 /*---------------------- strcat ----------------------*/
283 #define STRCAT(soname, fnname) \
284 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
285 ( char* dst, const char* src ); \
286 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
287 ( char* dst, const char* src ) \
289 const HChar* src_orig = src; \
290 HChar* dst_orig = dst; \
291 while (*dst) dst++; \
292 while (*src) *dst++ = *src++; \
295 /* This is a bit redundant, I think; any overlap and the strcat will */ \
296 /* go forever... or until a seg fault occurs. */ \
297 if (is_overlap(dst_orig, \
299 (Addr)dst-(Addr)dst_orig+1, \
300 (Addr)src-(Addr)src_orig+1)) \
301 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
306 #if defined(VGO_linux)
307 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
308 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
310 #elif defined(VGO_darwin)
311 //STRCAT(VG_Z_LIBC_SONAME, strcat)
313 #elif defined(VGO_solaris)
314 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
315 STRCAT(VG_Z_LD_SO_1
, strcat
)
320 /*---------------------- strncat ----------------------*/
322 #define STRNCAT(soname, fnname) \
323 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
324 ( char* dst, const char* src, SizeT n ); \
325 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
326 ( char* dst, const char* src, SizeT n ) \
328 const HChar* src_orig = src; \
329 HChar* dst_orig = dst; \
332 while (*dst) dst++; \
333 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
334 *dst = 0; /* always add null */ \
336 /* This checks for overlap after copying, unavoidable without */ \
337 /* pre-counting lengths... should be ok */ \
338 if (is_overlap(dst_orig, \
340 (Addr)dst-(Addr)dst_orig+1, \
341 (Addr)src-(Addr)src_orig+1)) \
342 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
347 #if defined(VGO_linux)
348 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
350 #elif defined(VGO_darwin)
351 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
352 //STRNCAT(VG_Z_DYLD, strncat)
354 #elif defined(VGO_solaris)
355 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
360 /*---------------------- strlcat ----------------------*/
362 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
363 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
364 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
365 Truncation occurred if retval >= n.
367 #define STRLCAT(soname, fnname) \
368 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
369 ( char* dst, const char* src, SizeT n ); \
370 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
371 ( char* dst, const char* src, SizeT n ) \
373 const HChar* src_orig = src; \
374 HChar* dst_orig = dst; \
377 while (m < n && *dst) { m++; dst++; } \
379 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
380 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
383 /* No space to copy anything to dst. m == n */ \
385 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
386 while (*src) { m++; src++; } \
387 /* This checks for overlap after copying, unavoidable without */ \
388 /* pre-counting lengths... should be ok */ \
389 if (is_overlap(dst_orig, \
391 (Addr)dst-(Addr)dst_orig+1, \
392 (Addr)src-(Addr)src_orig+1)) \
393 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
398 #if defined(VGO_linux)
400 #elif defined(VGO_darwin)
401 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
402 //STRLCAT(VG_Z_DYLD, strlcat)
403 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
405 #elif defined(VGO_solaris)
406 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
411 /*---------------------- strnlen ----------------------*/
413 #define STRNLEN(soname, fnname) \
414 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
415 ( const char* str, SizeT n ); \
416 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
417 ( const char* str, SizeT n ) \
420 while (i < n && str[i] != 0) i++; \
424 #if defined(VGO_linux)
425 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
426 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
428 #elif defined(VGO_darwin)
429 # if DARWIN_VERS == DARWIN_10_9
430 STRNLEN(libsystemZucZddylib
, strnlen
)
433 #elif defined(VGO_solaris)
434 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
439 /*---------------------- strlen ----------------------*/
441 // Note that this replacement often doesn't get used because gcc inlines
442 // calls to strlen() with its own built-in version. This can be very
443 // confusing if you aren't expecting it. Other small functions in
444 // this file may also be inline by gcc.
446 #define STRLEN(soname, fnname) \
447 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
448 ( const char* str ); \
449 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
450 ( const char* str ) \
453 while (str[i] != 0) i++; \
457 #if defined(VGO_linux)
458 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
459 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
460 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
461 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
462 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
463 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
464 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
465 # if defined(VGPV_arm_linux_android) \
466 || defined(VGPV_x86_linux_android) \
467 || defined(VGPV_mips32_linux_android)
468 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
471 #elif defined(VGO_darwin)
472 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
473 # if DARWIN_VERS >= DARWIN_10_9
474 STRLEN(libsystemZucZddylib
, strlen
)
477 #elif defined(VGO_solaris)
478 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
479 STRLEN(VG_Z_LD_SO_1
, strlen
)
484 /*---------------------- strcpy ----------------------*/
486 #define STRCPY(soname, fnname) \
487 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
488 ( char* dst, const char* src ); \
489 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
490 ( char* dst, const char* src ) \
492 const HChar* src_orig = src; \
493 HChar* dst_orig = dst; \
495 while (*src) *dst++ = *src++; \
498 /* This checks for overlap after copying, unavoidable without */ \
499 /* pre-counting length... should be ok */ \
500 if (is_overlap(dst_orig, \
502 (Addr)dst-(Addr)dst_orig+1, \
503 (Addr)src-(Addr)src_orig+1)) \
504 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
509 #if defined(VGO_linux)
510 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
511 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
513 #elif defined(VGO_darwin)
514 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
515 # if DARWIN_VERS == DARWIN_10_9
516 STRCPY(libsystemZucZddylib
, strcpy
)
519 #elif defined(VGO_solaris)
520 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
521 STRCPY(VG_Z_LD_SO_1
, strcpy
)
526 /*---------------------- strncpy ----------------------*/
528 #define STRNCPY(soname, fnname) \
529 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
530 ( char* dst, const char* src, SizeT n ); \
531 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
532 ( char* dst, const char* src, SizeT n ) \
534 const HChar* src_orig = src; \
535 HChar* dst_orig = dst; \
538 while (m < n && *src) { m++; *dst++ = *src++; } \
539 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
540 /* but only m+1 bytes of src if terminator was found */ \
541 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
542 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
543 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
548 #if defined(VGO_linux)
549 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
550 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
551 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
552 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
554 #elif defined(VGO_darwin)
555 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
556 # if DARWIN_VERS >= DARWIN_10_9
557 STRNCPY(libsystemZucZddylib
, strncpy
)
560 #elif defined(VGO_solaris)
561 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
562 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
567 /*---------------------- strlcpy ----------------------*/
569 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
570 Returns strlen(src). Does not zero-fill the remainder of dst. */
571 #define STRLCPY(soname, fnname) \
572 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
573 ( char* dst, const char* src, SizeT n ); \
574 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
575 ( char* dst, const char* src, SizeT n ) \
577 const HChar* src_orig = src; \
578 HChar* dst_orig = dst; \
581 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
583 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
584 /* m non-nul bytes have now been copied, and m <= n-1. */ \
585 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
586 /* but only m+1 bytes of src if terminator was found */ \
587 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
588 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
589 /* Nul-terminate dst. */ \
590 if (n > 0) *dst = 0; \
591 /* Finish counting strlen(src). */ \
592 while (*src) src++; \
593 return src - src_orig; \
596 #if defined(VGO_linux)
598 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
599 || defined(VGPV_mips32_linux_android)
600 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
601 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
604 #elif defined(VGO_darwin)
605 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
606 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
607 //STRLCPY(VG_Z_DYLD, strlcpy)
608 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
610 #elif defined(VGO_solaris)
611 /* special case for n == 0 which is undocumented but heavily used */
612 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
614 while (*src) src++; \
615 return src - src_orig; \
618 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
623 /*---------------------- strncmp ----------------------*/
625 #define STRNCMP(soname, fnname) \
626 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
627 ( const char* s1, const char* s2, SizeT nmax ); \
628 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
629 ( const char* s1, const char* s2, SizeT nmax ) \
633 if (n >= nmax) return 0; \
634 if (*s1 == 0 && *s2 == 0) return 0; \
635 if (*s1 == 0) return -1; \
636 if (*s2 == 0) return 1; \
638 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
639 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
645 #if defined(VGO_linux)
646 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
647 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
648 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
649 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
651 #elif defined(VGO_darwin)
652 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
653 # if DARWIN_VERS >= DARWIN_10_9
654 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
657 #elif defined(VGO_solaris)
658 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
663 /*---------------------- strcasecmp ----------------------*/
665 #define STRCASECMP(soname, fnname) \
666 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
667 ( const char* s1, const char* s2 ); \
668 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
669 ( const char* s1, const char* s2 ) \
671 extern int tolower(int); \
675 c1 = tolower(*(const UChar *)s1); \
676 c2 = tolower(*(const UChar *)s2); \
677 if (c1 != c2) break; \
678 if (c1 == 0) break; \
681 if ((UChar)c1 < (UChar)c2) return -1; \
682 if ((UChar)c1 > (UChar)c2) return 1; \
686 #if defined(VGO_linux)
687 # if !defined(VGPV_arm_linux_android) \
688 && !defined(VGPV_x86_linux_android) \
689 && !defined(VGPV_mips32_linux_android) \
690 && !defined(VGPV_arm64_linux_android)
691 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
692 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
695 #elif defined(VGO_darwin)
696 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
698 #elif defined(VGO_solaris)
699 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
704 /*---------------------- strncasecmp ----------------------*/
706 #define STRNCASECMP(soname, fnname) \
707 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
708 ( const char* s1, const char* s2, SizeT nmax ); \
709 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
710 ( const char* s1, const char* s2, SizeT nmax ) \
712 extern int tolower(int); \
715 if (n >= nmax) return 0; \
716 if (*s1 == 0 && *s2 == 0) return 0; \
717 if (*s1 == 0) return -1; \
718 if (*s2 == 0) return 1; \
720 if (tolower(*(const UChar *)s1) \
721 < tolower(*(const UChar*)s2)) return -1; \
722 if (tolower(*(const UChar *)s1) \
723 > tolower(*(const UChar *)s2)) return 1; \
729 #if defined(VGO_linux)
730 # if !defined(VGPV_arm_linux_android) \
731 && !defined(VGPV_x86_linux_android) \
732 && !defined(VGPV_mips32_linux_android) \
733 && !defined(VGPV_arm64_linux_android)
734 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
735 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
738 #elif defined(VGO_darwin)
739 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
740 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
742 #elif defined(VGO_solaris)
743 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
748 /*---------------------- strcasecmp_l ----------------------*/
750 #define STRCASECMP_L(soname, fnname) \
751 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
752 ( const char* s1, const char* s2, void* locale ); \
753 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
754 ( const char* s1, const char* s2, void* locale ) \
756 extern int tolower_l(int, void*) __attribute__((weak)); \
760 c1 = tolower_l(*(const UChar *)s1, locale); \
761 c2 = tolower_l(*(const UChar *)s2, locale); \
762 if (c1 != c2) break; \
763 if (c1 == 0) break; \
766 if ((UChar)c1 < (UChar)c2) return -1; \
767 if ((UChar)c1 > (UChar)c2) return 1; \
771 #if defined(VGO_linux)
772 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
773 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
774 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
776 #elif defined(VGO_darwin)
777 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
779 #elif defined(VGO_solaris)
784 /*---------------------- strncasecmp_l ----------------------*/
786 #define STRNCASECMP_L(soname, fnname) \
787 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
788 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
789 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
790 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
792 extern int tolower_l(int, void*) __attribute__((weak)); \
795 if (n >= nmax) return 0; \
796 if (*s1 == 0 && *s2 == 0) return 0; \
797 if (*s1 == 0) return -1; \
798 if (*s2 == 0) return 1; \
800 if (tolower_l(*(const UChar *)s1, locale) \
801 < tolower_l(*(const UChar *)s2, locale)) return -1; \
802 if (tolower_l(*(const UChar *)s1, locale) \
803 > tolower_l(*(const UChar *)s2, locale)) return 1; \
809 #if defined(VGO_linux)
810 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
811 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
812 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
814 #elif defined(VGO_darwin)
815 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
816 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
818 #elif defined(VGO_solaris)
823 /*---------------------- strcmp ----------------------*/
825 #define STRCMP(soname, fnname) \
826 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
827 ( const char* s1, const char* s2 ); \
828 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
829 ( const char* s1, const char* s2 ) \
834 c1 = *(const UChar *)s1; \
835 c2 = *(const UChar *)s2; \
836 if (c1 != c2) break; \
837 if (c1 == 0) break; \
840 if ((UChar)c1 < (UChar)c2) return -1; \
841 if ((UChar)c1 > (UChar)c2) return 1; \
845 #if defined(VGO_linux)
846 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
847 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
848 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
849 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
850 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
851 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
852 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
853 || defined(VGPV_mips32_linux_android)
854 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
857 #elif defined(VGO_darwin)
858 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
859 # if DARWIN_VERS >= DARWIN_10_9
860 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
863 #elif defined(VGO_solaris)
864 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
865 STRCMP(VG_Z_LD_SO_1
, strcmp
)
870 /*---------------------- memchr ----------------------*/
872 #define MEMCHR(soname, fnname) \
873 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
874 (const void *s, int c, SizeT n); \
875 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
876 (const void *s, int c, SizeT n) \
879 UChar c0 = (UChar)c; \
880 const UChar* p = s; \
881 for (i = 0; i < n; i++) \
882 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
886 #if defined(VGO_linux)
887 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
888 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
890 #elif defined(VGO_darwin)
891 # if DARWIN_VERS == DARWIN_10_9
892 MEMCHR(VG_Z_DYLD
, memchr
)
893 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
895 # if DARWIN_VERS >= DARWIN_10_10
896 MEMCHR(VG_Z_DYLD
, memchr
)
897 /* _platform_memchr$VARIANT$Generic */
898 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
899 /* _platform_memchr$VARIANT$Haswell */
900 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
903 #elif defined(VGO_solaris)
904 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
909 /*---------------------- memrchr ----------------------*/
911 #define MEMRCHR(soname, fnname) \
912 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
913 (const void *s, int c, SizeT n); \
914 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
915 (const void *s, int c, SizeT n) \
918 UChar c0 = (UChar)c; \
919 const UChar* p = s; \
920 for (i = 0; i < n; i++) \
921 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
925 #if defined(VGO_linux)
926 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
928 #elif defined(VGO_darwin)
929 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
930 //MEMRCHR(VG_Z_DYLD, memrchr)
932 #elif defined(VGO_solaris)
937 /*---------------------- memcpy ----------------------*/
939 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
940 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
941 ( void *dst, const void *src, SizeT len ); \
942 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
943 ( void *dst, const void *src, SizeT len ) \
945 if (do_ol_check && is_overlap(dst, src, len, len)) \
946 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
948 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
949 const Addr WM = WS - 1; /* 7 or 3 */ \
952 if (dst < src || !is_overlap(dst, src, len, len)) { \
954 /* Copying backwards. */ \
956 Addr d = (Addr)dst; \
957 Addr s = (Addr)src; \
959 if (((s^d) & WM) == 0) { \
960 /* s and d have same UWord alignment. */ \
961 /* Pull up to a UWord boundary. */ \
962 while ((s & WM) != 0 && n >= 1) \
963 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
966 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
970 if (((s|d) & 1) == 0) { \
971 /* Both are 16-aligned; copy what we can thusly. */ \
973 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
975 /* Copy leftovers, or everything if misaligned. */ \
977 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
979 } else if (dst > src) { \
982 Addr d = ((Addr)dst) + n; \
983 Addr s = ((Addr)src) + n; \
985 /* Copying forwards. */ \
986 if (((s^d) & WM) == 0) { \
987 /* s and d have same UWord alignment. */ \
988 /* Back down to a UWord boundary. */ \
989 while ((s & WM) != 0 && n >= 1) \
990 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
993 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
997 if (((s|d) & 1) == 0) { \
998 /* Both are 16-aligned; copy what we can thusly. */ \
1000 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1002 /* Copy leftovers, or everything if misaligned. */ \
1004 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1012 #define MEMMOVE(soname, fnname) \
1013 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1015 #define MEMCPY(soname, fnname) \
1016 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1018 #if defined(VGO_linux)
1019 /* For older memcpy we have to use memmove-like semantics and skip
1020 the overlap check; sigh; see #275284. */
1021 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1022 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1023 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1024 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1025 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1026 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1027 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1028 /* icc9 blats these around all over the place. Not only in the main
1029 executable but various .so's. They are highly tuned and read
1030 memory beyond the source boundary (although work correctly and
1031 never go across page boundaries), so give errors when run
1032 natively, at least for misaligned source arg. Just intercepting
1033 in the exe only until we understand more about the problem. See
1034 http://bugs.kde.org/show_bug.cgi?id=139776
1036 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1038 #elif defined(VGO_darwin)
1039 # if DARWIN_VERS <= DARWIN_10_6
1040 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1042 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1043 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1045 #elif defined(VGO_solaris)
1046 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1047 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZPZa
)
1048 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1053 /*---------------------- memcmp ----------------------*/
1055 #define MEMCMP(soname, fnname) \
1056 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1057 ( const void *s1V, const void *s2V, SizeT n ); \
1058 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1059 ( const void *s1V, const void *s2V, SizeT n ) \
1061 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1062 const SizeT WM = WS - 1; /* 7 or 3 */ \
1063 Addr s1A = (Addr)s1V; \
1064 Addr s2A = (Addr)s2V; \
1066 if (((s1A | s2A) & WM) == 0) { \
1067 /* Both areas are word aligned. Skip over the */ \
1068 /* equal prefix as fast as possible. */ \
1070 UWord w1 = *(UWord*)s1A; \
1071 UWord w2 = *(UWord*)s2A; \
1072 if (w1 != w2) break; \
1079 const UChar* s1 = (const UChar*) s1A; \
1080 const UChar* s2 = (const UChar*) s2A; \
1087 int res = ((int)a0) - ((int)b0); \
1095 #if defined(VGO_linux)
1096 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1097 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1098 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1099 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1100 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1101 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1103 #elif defined(VGO_darwin)
1104 # if DARWIN_VERS >= DARWIN_10_9
1105 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1108 #elif defined(VGO_solaris)
1109 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1110 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1111 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1116 /*---------------------- stpcpy ----------------------*/
1118 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1119 DEST. (minor variant of strcpy) */
1120 #define STPCPY(soname, fnname) \
1121 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1122 ( char* dst, const char* src ); \
1123 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1124 ( char* dst, const char* src ) \
1126 const HChar* src_orig = src; \
1127 HChar* dst_orig = dst; \
1129 while (*src) *dst++ = *src++; \
1132 /* This checks for overlap after copying, unavoidable without */ \
1133 /* pre-counting length... should be ok */ \
1134 if (is_overlap(dst_orig, \
1136 (Addr)dst-(Addr)dst_orig+1, \
1137 (Addr)src-(Addr)src_orig+1)) \
1138 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1143 #if defined(VGO_linux)
1144 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1145 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1146 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1147 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1148 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1149 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1151 #elif defined(VGO_darwin)
1152 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1153 //STPCPY(VG_Z_DYLD, stpcpy)
1155 #elif defined(VGO_solaris)
1156 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1161 /*---------------------- stpncpy ----------------------*/
1163 #define STPNCPY(soname, fnname) \
1164 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1165 ( char* dst, const char* src, SizeT n ); \
1166 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1167 ( char* dst, const char* src, SizeT n ) \
1169 const HChar* src_orig = src; \
1170 HChar* dst_str = dst; \
1173 while (m < n && *src) { m++; *dst++ = *src++; } \
1174 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1175 /* but only m+1 bytes of src if terminator was found */ \
1176 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1177 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1179 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1184 #if defined(VGO_linux)
1185 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1189 /*---------------------- memset ----------------------*/
1191 /* Why are we bothering to intercept this? It seems entirely
1194 #define MEMSET(soname, fnname) \
1195 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1196 (void *s, Int c, SizeT n); \
1197 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1198 (void *s, Int c, SizeT n) \
1200 if (sizeof(void*) == 8) { \
1202 ULong c8 = (c & 0xFF); \
1203 c8 = (c8 << 8) | c8; \
1204 c8 = (c8 << 16) | c8; \
1205 c8 = (c8 << 32) | c8; \
1206 while ((a & 7) != 0 && n >= 1) \
1207 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1209 { *(ULong*)a = c8; a += 8; n -= 8; \
1210 *(ULong*)a = c8; a += 8; n -= 8; \
1211 *(ULong*)a = c8; a += 8; n -= 8; \
1212 *(ULong*)a = c8; a += 8; n -= 8; } \
1214 { *(ULong*)a = c8; a += 8; n -= 8; } \
1216 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1220 UInt c4 = (c & 0xFF); \
1221 c4 = (c4 << 8) | c4; \
1222 c4 = (c4 << 16) | c4; \
1223 while ((a & 3) != 0 && n >= 1) \
1224 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1226 { *(UInt*)a = c4; a += 4; n -= 4; \
1227 *(UInt*)a = c4; a += 4; n -= 4; \
1228 *(UInt*)a = c4; a += 4; n -= 4; \
1229 *(UInt*)a = c4; a += 4; n -= 4; } \
1231 { *(UInt*)a = c4; a += 4; n -= 4; } \
1233 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1238 #if defined(VGO_linux)
1239 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1241 #elif defined(VGO_darwin)
1242 //MEMSET(VG_Z_LIBC_SONAME, memset)
1243 //MEMSET(VG_Z_DYLD, memset)
1244 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1246 #elif defined(VGO_solaris)
1247 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1248 MEMSET(VG_Z_LIBC_SONAME
, memsetZPZa
)
1253 /*---------------------- memmove ----------------------*/
1255 /* memmove -- use the MEMMOVE defn above. */
1257 #if defined(VGO_linux)
1258 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1259 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1260 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1261 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1263 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1265 #elif defined(VGO_darwin)
1266 # if DARWIN_VERS <= DARWIN_10_6
1267 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1269 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1270 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1271 # if DARWIN_VERS >= DARWIN_10_9
1272 /* _platform_memmove$VARIANT$Ivybridge */
1273 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1276 #elif defined(VGO_solaris)
1277 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1278 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZPZa
)
1279 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1284 /*---------------------- bcopy ----------------------*/
1286 #define BCOPY(soname, fnname) \
1287 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1288 (const void *srcV, void *dstV, SizeT n); \
1289 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1290 (const void *srcV, void *dstV, SizeT n) \
1293 HChar* dst = dstV; \
1294 const HChar* src = srcV; \
1296 for (i = 0; i < n; i++) \
1301 for (i = 0; i < n; i++) \
1302 dst[n-i-1] = src[n-i-1]; \
1306 #if defined(VGO_linux)
1307 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1309 #elif defined(VGO_darwin)
1310 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1311 //BCOPY(VG_Z_DYLD, bcopy)
1313 #elif defined(VGO_darwin)
1314 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1319 /*-------------------- memmove_chk --------------------*/
1321 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1322 There is no specific part of glibc that this is copied from. */
1323 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1324 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1325 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1326 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1327 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1330 HChar* dst = dstV; \
1331 const HChar* src = srcV; \
1335 for (i = 0; i < n; i++) \
1340 for (i = 0; i < n; i++) \
1341 dst[n-i-1] = src[n-i-1]; \
1345 VALGRIND_PRINTF_BACKTRACE( \
1346 "*** memmove_chk: buffer overflow detected ***: " \
1347 "program terminated\n"); \
1353 #if defined(VGO_linux)
1354 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1356 #elif defined(VGO_darwin)
1358 #elif defined(VGO_solaris)
1363 /*-------------------- strchrnul --------------------*/
1365 /* Find the first occurrence of C in S or the final NUL byte. */
1366 #define GLIBC232_STRCHRNUL(soname, fnname) \
1367 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1368 (const char* s, int c_in); \
1369 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1370 (const char* s, int c_in) \
1372 HChar c = (HChar) c_in; \
1373 const HChar* char_ptr = s; \
1375 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1376 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1381 #if defined(VGO_linux)
1382 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1384 #elif defined(VGO_darwin)
1386 #elif defined(VGO_solaris)
1391 /*---------------------- rawmemchr ----------------------*/
1393 /* Find the first occurrence of C in S. */
1394 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1395 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1396 (const void* s, int c_in); \
1397 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1398 (const void* s, int c_in) \
1400 UChar c = (UChar) c_in; \
1401 const UChar* char_ptr = s; \
1403 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1408 #if defined (VGO_linux)
1409 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1410 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1412 #elif defined(VGO_darwin)
1414 #elif defined(VGO_solaris)
1419 /*---------------------- strcpy_chk ----------------------*/
1421 /* glibc variant of strcpy that checks the dest is big enough.
1422 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1423 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1424 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1425 (char* dst, const char* src, SizeT len); \
1426 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1427 (char* dst, const char* src, SizeT len) \
1432 while ((*dst++ = *src++) != '\0') \
1437 VALGRIND_PRINTF_BACKTRACE( \
1438 "*** strcpy_chk: buffer overflow detected ***: " \
1439 "program terminated\n"); \
1445 #if defined(VGO_linux)
1446 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1448 #elif defined(VGO_darwin)
1450 #elif defined(VGO_solaris)
1455 /*---------------------- stpcpy_chk ----------------------*/
1457 /* glibc variant of stpcpy that checks the dest is big enough.
1458 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1459 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1460 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1461 (char* dst, const char* src, SizeT len); \
1462 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1463 (char* dst, const char* src, SizeT len) \
1467 while ((*dst++ = *src++) != '\0') \
1472 VALGRIND_PRINTF_BACKTRACE( \
1473 "*** stpcpy_chk: buffer overflow detected ***: " \
1474 "program terminated\n"); \
1480 #if defined(VGO_linux)
1481 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1483 #elif defined(VGO_darwin)
1485 #elif defined(VGO_solaris)
1490 /*---------------------- mempcpy ----------------------*/
1493 #define GLIBC25_MEMPCPY(soname, fnname) \
1494 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1495 ( void *dst, const void *src, SizeT len ); \
1496 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1497 ( void *dst, const void *src, SizeT len ) \
1499 SizeT len_saved = len; \
1504 if (is_overlap(dst, src, len, len)) \
1505 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1507 if ( dst > src ) { \
1508 register HChar *d = (char *)dst + len - 1; \
1509 register const HChar *s = (const char *)src + len - 1; \
1513 } else if ( dst < src ) { \
1514 register HChar *d = dst; \
1515 register const HChar *s = src; \
1520 return (void*)( ((char*)dst) + len_saved ); \
1523 #if defined(VGO_linux)
1524 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1525 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1526 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1527 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1528 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1530 #elif defined(VGO_darwin)
1531 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1533 #elif defined(VGO_solaris)
1538 /*-------------------- memcpy_chk --------------------*/
1540 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1541 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1542 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1543 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1544 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1546 register HChar *d; \
1547 register const HChar *s; \
1549 if (dstlen < len) goto badness; \
1554 if (is_overlap(dst, src, len, len)) \
1555 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1557 if ( dst > src ) { \
1558 d = (HChar *)dst + len - 1; \
1559 s = (const HChar *)src + len - 1; \
1563 } else if ( dst < src ) { \
1565 s = (const HChar *)src; \
1572 VALGRIND_PRINTF_BACKTRACE( \
1573 "*** memcpy_chk: buffer overflow detected ***: " \
1574 "program terminated\n"); \
1580 #if defined(VGO_linux)
1581 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1583 #elif defined(VGO_darwin)
1585 #elif defined(VGO_solaris)
1590 /*---------------------- strstr ----------------------*/
1592 #define STRSTR(soname, fnname) \
1593 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1594 (const char* haystack, const char* needle); \
1595 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1596 (const char* haystack, const char* needle) \
1598 const HChar* h = haystack; \
1599 const HChar* n = needle; \
1601 /* find the length of n, not including terminating zero */ \
1603 while (n[nlen]) nlen++; \
1605 /* if n is the empty string, match immediately. */ \
1606 if (nlen == 0) return CONST_CAST(HChar *,h); \
1608 /* assert(nlen >= 1); */ \
1612 const HChar hh = *h; \
1613 if (hh == 0) return NULL; \
1614 if (hh != n0) { h++; continue; } \
1617 for (i = 0; i < nlen; i++) { \
1621 /* assert(i >= 0 && i <= nlen); */ \
1623 return CONST_CAST(HChar *,h); \
1629 #if defined(VGO_linux)
1630 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1631 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1632 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1634 #elif defined(VGO_darwin)
1636 #elif defined(VGO_solaris)
1637 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1642 /*---------------------- strpbrk ----------------------*/
1644 #define STRPBRK(soname, fnname) \
1645 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1646 (const char* sV, const char* acceptV); \
1647 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1648 (const char* sV, const char* acceptV) \
1650 const HChar* s = sV; \
1651 const HChar* accept = acceptV; \
1653 /* find the length of 'accept', not including terminating zero */ \
1655 while (accept[nacc]) nacc++; \
1657 /* if n is the empty string, fail immediately. */ \
1658 if (nacc == 0) return NULL; \
1660 /* assert(nacc >= 1); */ \
1666 for (i = 0; i < nacc; i++) { \
1667 if (sc == accept[i]) \
1668 return CONST_CAST(HChar *,s); \
1676 #if defined(VGO_linux)
1677 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1679 #elif defined(VGO_darwin)
1681 #elif defined(VGO_solaris)
1682 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1687 /*---------------------- strcspn ----------------------*/
1689 #define STRCSPN(soname, fnname) \
1690 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1691 (const char* sV, const char* rejectV); \
1692 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1693 (const char* sV, const char* rejectV) \
1695 const HChar* s = sV; \
1696 const HChar* reject = rejectV; \
1698 /* find the length of 'reject', not including terminating zero */ \
1700 while (reject[nrej]) nrej++; \
1708 for (i = 0; i < nrej; i++) { \
1709 if (sc == reject[i]) \
1712 /* assert(i >= 0 && i <= nrej); */ \
1722 #if defined(VGO_linux)
1723 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1725 #elif defined(VGO_darwin)
1727 #elif defined(VGO_solaris)
1728 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1733 /*---------------------- strspn ----------------------*/
1735 #define STRSPN(soname, fnname) \
1736 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1737 (const char* sV, const char* acceptV); \
1738 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1739 (const char* sV, const char* acceptV) \
1741 const UChar* s = (const UChar *)sV; \
1742 const UChar* accept = (const UChar *)acceptV; \
1744 /* find the length of 'accept', not including terminating zero */ \
1746 while (accept[nacc]) nacc++; \
1747 if (nacc == 0) return 0; \
1755 for (i = 0; i < nacc; i++) { \
1756 if (sc == accept[i]) \
1759 /* assert(i >= 0 && i <= nacc); */ \
1769 #if defined(VGO_linux)
1770 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1772 #elif defined(VGO_darwin)
1774 #elif defined(VGO_solaris)
1775 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1780 /*---------------------- strcasestr ----------------------*/
1782 #define STRCASESTR(soname, fnname) \
1783 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1784 (const char* haystack, const char* needle); \
1785 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1786 (const char* haystack, const char* needle) \
1788 extern int tolower(int); \
1789 const HChar* h = haystack; \
1790 const HChar* n = needle; \
1792 /* find the length of n, not including terminating zero */ \
1794 while (n[nlen]) nlen++; \
1796 /* if n is the empty string, match immediately. */ \
1797 if (nlen == 0) return CONST_CAST(HChar *,h); \
1799 /* assert(nlen >= 1); */ \
1800 UChar n0 = tolower(n[0]); \
1803 UChar hh = tolower(*h); \
1804 if (hh == 0) return NULL; \
1805 if (hh != n0) { h++; continue; } \
1808 for (i = 0; i < nlen; i++) { \
1809 if (tolower(n[i]) != tolower(h[i])) \
1812 /* assert(i >= 0 && i <= nlen); */ \
1814 return CONST_CAST(HChar *,h); \
1820 #if defined(VGO_linux)
1821 # if !defined(VGPV_arm_linux_android) \
1822 && !defined(VGPV_x86_linux_android) \
1823 && !defined(VGPV_mips32_linux_android) \
1824 && !defined(VGPV_arm64_linux_android)
1825 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
1828 #elif defined(VGO_darwin)
1830 #elif defined(VGO_solaris)
1831 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
1836 /*---------------------- wcslen ----------------------*/
1838 // This is a wchar_t equivalent to strlen. Unfortunately
1839 // we don't have wchar_t available here, but it looks like
1840 // a 32 bit int on Linux. I don't know if that is also
1843 #define WCSLEN(soname, fnname) \
1844 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1845 ( const UInt* str ); \
1846 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1847 ( const UInt* str ) \
1850 while (str[i] != 0) i++; \
1854 #if defined(VGO_linux)
1855 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
1857 #elif defined(VGO_darwin)
1859 #elif defined(VGO_solaris)
1860 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
1864 /*---------------------- wcscmp ----------------------*/
1866 // This is a wchar_t equivalent to strcmp. We don't
1867 // have wchar_t available here, but in the GNU C Library
1868 // wchar_t is always 32 bits wide and wcscmp uses signed
1869 // comparison, not unsigned as in strcmp function.
1871 #define WCSCMP(soname, fnname) \
1872 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1873 ( const Int* s1, const Int* s2 ); \
1874 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1875 ( const Int* s1, const Int* s2 ) \
1882 if (c1 != c2) break; \
1883 if (c1 == 0) break; \
1886 if (c1 < c2) return -1; \
1887 if (c1 > c2) return 1; \
1891 #if defined(VGO_linux)
1892 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
1895 /*---------------------- wcscpy ----------------------*/
1897 // This is a wchar_t equivalent to strcpy. We don't
1898 // have wchar_t available here, but in the GNU C Library
1899 // wchar_t is always 32 bits wide.
1901 #define WCSCPY(soname, fnname) \
1902 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1903 ( Int* dst, const Int* src ); \
1904 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1905 ( Int* dst, const Int* src ) \
1907 const Int* src_orig = src; \
1908 Int* dst_orig = dst; \
1910 while (*src) *dst++ = *src++; \
1913 /* This checks for overlap after copying, unavoidable without */ \
1914 /* pre-counting length... should be ok */ \
1915 if (is_overlap(dst_orig, \
1917 (Addr)dst-(Addr)dst_orig+1, \
1918 (Addr)src-(Addr)src_orig+1)) \
1919 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1924 #if defined(VGO_linux)
1925 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
1929 /*---------------------- wcschr ----------------------*/
1931 // This is a wchar_t equivalent to strchr. We don't
1932 // have wchar_t available here, but in the GNU C Library
1933 // wchar_t is always 32 bits wide.
1935 #define WCSCHR(soname, fnname) \
1936 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1937 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1941 if (*p == c) return CONST_CAST(Int *,p); \
1942 if (*p == 0) return NULL; \
1947 #if defined(VGO_linux)
1948 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
1950 /*---------------------- wcsrchr ----------------------*/
1952 // This is a wchar_t equivalent to strrchr. We don't
1953 // have wchar_t available here, but in the GNU C Library
1954 // wchar_t is always 32 bits wide.
1956 #define WCSRCHR(soname, fnname) \
1957 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1958 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1961 const Int* last = NULL; \
1963 if (*p == c) last = p; \
1964 if (*p == 0) return CONST_CAST(Int *,last); \
1969 #if defined(VGO_linux)
1970 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
1973 /*------------------------------------------------------------*/
1974 /*--- Improve definedness checking of process environment ---*/
1975 /*------------------------------------------------------------*/
1977 #if defined(VGO_linux)
1979 /* If these wind up getting generated via a macro, so that multiple
1980 versions of each function exist (as above), use the _EZU variants
1981 to assign equivalance class tags. */
1983 /*---------------------- putenv ----------------------*/
1985 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
1986 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
1990 const HChar
* p
= string
;
1991 VALGRIND_GET_ORIG_FN(fn
);
1992 /* Now by walking over the string we magically produce
1993 traces when hitting undefined memory. */
1996 __asm__
__volatile__("" ::: "memory");
1997 CALL_FN_W_W(result
, fn
, string
);
2002 /*---------------------- unsetenv ----------------------*/
2004 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
2005 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
2009 const HChar
* p
= name
;
2010 VALGRIND_GET_ORIG_FN(fn
);
2011 /* Now by walking over the string we magically produce
2012 traces when hitting undefined memory. */
2015 __asm__
__volatile__("" ::: "memory");
2016 CALL_FN_W_W(result
, fn
, name
);
2021 /*---------------------- setenv ----------------------*/
2024 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2025 (const char* name
, const char* value
, int overwrite
);
2026 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2027 (const char* name
, const char* value
, int overwrite
)
2032 VALGRIND_GET_ORIG_FN(fn
);
2033 /* Now by walking over the string we magically produce
2034 traces when hitting undefined memory. */
2036 for (p
= name
; *p
; p
++)
2037 __asm__
__volatile__("" ::: "memory");
2039 for (p
= value
; *p
; p
++)
2040 __asm__
__volatile__("" ::: "memory");
2041 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2042 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2046 #endif /* defined(VGO_linux) */
2048 /*--------------------------------------------------------------------*/
2050 /*--------------------------------------------------------------------*/