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, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #include "pub_tool_basics.h"
31 #include "pub_tool_poolalloc.h"
32 #include "pub_tool_hashtable.h"
33 #include "pub_tool_redir.h"
34 #include "pub_tool_tooliface.h"
35 #include "pub_tool_clreq.h"
37 /* ---------------------------------------------------------------------
38 We have our own versions of these functions for multiple reasons:
39 (a) it allows us to do overlap checking
40 (b) it allows us to do copy tracking
41 (c) some of the normal versions are hyper-optimised, which fools
42 Memcheck and cause spurious value warnings. Our versions are
44 (d) the glibc SSE-variants can read past the end of the input data
45 ranges. This can cause false-positive Memcheck / Helgrind / DRD
48 Note that overenthusiastic use of PLT bypassing by the glibc people also
49 means that we need to patch multiple versions of some of the functions to
50 our own implementations.
52 THEY RUN ON THE SIMD CPU!
53 ------------------------------------------------------------------ */
55 /* Assignment of behavioural equivalence class tags: 2NNNP is intended
56 to be reserved for str/mem intercepts. Current usage:
76 20180 MEMCPY if there's a conflict between memcpy and
77 20181 MEMMOVE memmove, prefer memmove
82 2022P unused (was previously MEMMOVE)
84 20240 GLIBC25___MEMMOVE_CHK
85 20250 GLIBC232_STRCHRNUL
86 20260 GLIBC232_RAWMEMCHR
87 20270 GLIBC25___STRCPY_CHK
88 20280 GLIBC25___STPCPY_CHK
90 20300 GLIBC26___MEMCPY_CHK
110 #if defined(VGO_solaris)
112 Detour functions in the libc and the runtime linker. If a function isn't
113 much optimized (and no overlap checking is necessary) then redir the
114 function only in the libc. This way we can keep stacktraces in the tests
120 /* Figure out if [dst .. dst+dstlen-1] overlaps with
121 [src .. src+srclen-1].
122 We assume that the address ranges do not wrap around
123 (which is safe since on Linux addresses >= 0xC0000000
124 are not accessible and the program will segfault in this
125 circumstance, presumably).
128 Bool
is_overlap ( void* dst
, const void* src
, SizeT dstlen
, SizeT srclen
)
130 Addr loS
, hiS
, loD
, hiD
;
132 if (dstlen
== 0 || srclen
== 0)
137 hiS
= loS
+ srclen
- 1;
138 hiD
= loD
+ dstlen
- 1;
140 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
144 else if (loD
< loS
) {
148 /* They start at same place. Since we know neither of them has
149 zero length, they must overlap. */
155 /* Call here to exit if we can't continue. On Android we can't call
156 _exit for some reason, so we have to blunt-instrument it. */
157 __attribute__ ((__noreturn__
))
158 static inline void my_exit ( int x
)
160 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
161 || defined(VGPV_arm64_linux_android)
162 __asm__
__volatile__(".word 0xFFFFFFFF");
164 # elif defined(VGPV_x86_linux_android)
165 __asm__
__volatile__("ud2");
168 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
174 // This is a macro rather than a function because we don't want to have an
175 // extra function in the stack trace.
176 #ifndef RECORD_OVERLAP_ERROR
177 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
180 // Used for tools that record bulk copies: memcpy, strcpy, etc.
182 #define RECORD_COPY(len) do { } while (0)
185 #define FOR_COPY(x) x
188 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
189 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
193 /*---------------------- strrchr ----------------------*/
195 #define STRRCHR(soname, fnname) \
196 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
197 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
199 HChar ch = (HChar)c; \
200 const HChar* p = s; \
201 const HChar* last = NULL; \
203 if (*p == ch) last = p; \
204 if (*p == 0) return CONST_CAST(HChar *,last); \
209 // Apparently rindex() is the same thing as strrchr()
210 #if defined(VGO_linux)
211 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
212 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
213 STRRCHR(VG_Z_LIBC_SONAME
, __GI_strrchr
)
214 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2
)
215 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2_no_bsf
)
216 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse42
)
217 STRRCHR(VG_Z_LD_LINUX_SO_2
, rindex
)
218 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
219 || defined(VGPV_mips32_linux_android)
220 STRRCHR(NONE
, __dl_strrchr
); /* in /system/bin/linker */
223 #elif defined(VGO_freebsd)
224 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
225 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
226 STRRCHR(VG_Z_LD_ELF_SO_1
, strrchr
)
227 STRRCHR(VG_Z_LD_ELF32_SO_1
, strrchr
)
229 #elif defined(VGO_darwin)
230 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
231 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
232 //STRRCHR(VG_Z_DYLD, strrchr)
233 //STRRCHR(VG_Z_DYLD, rindex)
234 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
235 # if DARWIN_VERS >= DARWIN_10_9
236 STRRCHR(libsystemZucZddylib
, strrchr
)
239 #elif defined(VGO_solaris)
240 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
241 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
242 STRRCHR(VG_Z_LD_SO_1
, strrchr
)
247 /*---------------------- strchr ----------------------*/
249 #define STRCHR(soname, fnname) \
250 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
251 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
253 HChar ch = (HChar)c ; \
254 const HChar* p = s; \
256 if (*p == ch) return CONST_CAST(HChar *,p); \
257 if (*p == 0) return NULL; \
262 // Apparently index() is the same thing as strchr()
263 #if defined(VGO_linux)
264 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
265 STRCHR(VG_Z_LIBC_SONAME
, __GI_strchr
)
266 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2
)
267 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2_no_bsf
)
268 STRCHR(VG_Z_LIBC_SONAME
, index
)
269 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
270 STRCHR(VG_Z_LD_LINUX_SO_2
, strchr
)
271 STRCHR(VG_Z_LD_LINUX_SO_2
, index
)
272 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, strchr
)
273 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, index
)
276 #if defined(VGPV_mips32_linux_android)
277 STRCHR(NONE
, __dl_strchr
)
280 #elif defined(VGO_freebsd)
281 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
282 STRCHR(VG_Z_LIBC_SONAME
, index
)
283 STRCHR(VG_Z_LD_ELF_SO_1
, strchr
)
284 STRCHR(VG_Z_LD_ELF32_SO_1
, strchr
)
286 #elif defined(VGO_darwin)
287 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
288 # if DARWIN_VERS == DARWIN_10_9
289 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
291 # if DARWIN_VERS >= DARWIN_10_10
292 /* _platform_strchr$VARIANT$Generic */
293 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
294 /* _platform_strchr$VARIANT$Haswell */
295 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
297 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Base
)
299 #elif defined(VGO_solaris)
300 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
301 STRCHR(VG_Z_LIBC_SONAME
, index
)
302 STRCHR(VG_Z_LD_SO_1
, strchr
)
307 /*---------------------- strcat ----------------------*/
309 #define STRCAT(soname, fnname) \
310 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
311 ( char* dst, const char* src ); \
312 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
313 ( char* dst, const char* src ) \
315 const HChar* src_orig = src; \
316 HChar* dst_orig = dst; \
317 while (*dst) dst++; \
318 while (*src) *dst++ = *src++; \
321 /* This is a bit redundant, I think; any overlap and the strcat will */ \
322 /* go forever... or until a seg fault occurs. */ \
323 if (is_overlap(dst_orig, \
325 (Addr)dst-(Addr)dst_orig+1, \
326 (Addr)src-(Addr)src_orig+1)) \
327 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
332 #if defined(VGO_linux)
333 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
334 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
336 #elif defined(VGO_freebsd)
337 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
338 STRCAT(VG_Z_LD_ELF_SO_1
, strcat
)
339 STRCAT(VG_Z_LD_ELF32_SO_1
, strcat
)
341 #elif defined(VGO_darwin)
342 //STRCAT(VG_Z_LIBC_SONAME, strcat)
344 #elif defined(VGO_solaris)
345 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
346 STRCAT(VG_Z_LD_SO_1
, strcat
)
351 /*---------------------- strncat ----------------------*/
353 #define STRNCAT(soname, fnname) \
354 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
355 ( char* dst, const char* src, SizeT n ); \
356 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
357 ( char* dst, const char* src, SizeT n ) \
359 const HChar* src_orig = src; \
360 HChar* dst_orig = dst; \
363 while (*dst) dst++; \
364 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
365 *dst = 0; /* always add null */ \
367 /* This checks for overlap after copying, unavoidable without */ \
368 /* pre-counting lengths... should be ok */ \
369 if (is_overlap(dst_orig, \
371 (Addr)dst-(Addr)dst_orig+1, \
372 (Addr)src-(Addr)src_orig+1)) \
373 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
378 #if defined(VGO_linux)
379 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
381 #elif defined(VGO_freebsd)
382 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
384 #elif defined(VGO_darwin)
385 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
386 //STRNCAT(VG_Z_DYLD, strncat)
388 #elif defined(VGO_solaris)
389 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
394 /*---------------------- strlcat ----------------------*/
396 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
397 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
398 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
399 Truncation occurred if retval >= n.
401 #define STRLCAT(soname, fnname) \
402 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
403 ( char* dst, const char* src, SizeT n ); \
404 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
405 ( char* dst, const char* src, SizeT n ) \
407 const HChar* src_orig = src; \
408 HChar* dst_orig = dst; \
411 while (m < n && *dst) { m++; dst++; } \
413 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
414 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
417 /* No space to copy anything to dst. m == n */ \
419 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
420 while (*src) { m++; src++; } \
421 /* This checks for overlap after copying, unavoidable without */ \
422 /* pre-counting lengths... should be ok */ \
423 if (is_overlap(dst_orig, \
425 (Addr)dst-(Addr)dst_orig+1, \
426 (Addr)src-(Addr)src_orig+1)) \
427 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
432 #if defined(VGO_linux)
434 #elif defined(VGO_freebsd)
435 STRLCAT(VG_Z_LD_ELF_SO_1
, strlcat
)
436 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
437 STRLCAT(VG_Z_LD_ELF32_SO_1
, strlcat
)
439 #elif defined(VGO_darwin)
440 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
441 //STRLCAT(VG_Z_DYLD, strlcat)
442 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
444 #elif defined(VGO_solaris)
445 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
450 /*---------------------- strnlen ----------------------*/
452 #define STRNLEN(soname, fnname) \
453 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
454 ( const char* str, SizeT n ); \
455 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
456 ( const char* str, SizeT n ) \
459 while (i < n && str[i] != 0) i++; \
463 #if defined(VGO_linux)
464 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
465 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
467 #elif defined(VGO_freebsd)
469 STRNLEN(VG_Z_LIBC_SONAME
, srtnlen
)
471 #elif defined(VGO_darwin)
472 # if DARWIN_VERS == DARWIN_10_9
473 STRNLEN(libsystemZucZddylib
, strnlen
)
476 #elif defined(VGO_solaris)
477 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
482 /*---------------------- strlen ----------------------*/
484 // Note that this replacement often doesn't get used because gcc inlines
485 // calls to strlen() with its own built-in version. This can be very
486 // confusing if you aren't expecting it. Other small functions in
487 // this file may also be inline by gcc.
489 #define STRLEN(soname, fnname) \
490 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
491 ( const char* str ); \
492 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
493 ( const char* str ) \
496 while (str[i] != 0) i++; \
500 #if defined(VGO_linux)
501 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
502 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
503 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
504 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
505 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
506 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
507 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
508 # if defined(VGPV_arm_linux_android) \
509 || defined(VGPV_x86_linux_android) \
510 || defined(VGPV_mips32_linux_android)
511 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
514 #elif defined(VGO_freebsd)
515 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
516 STRLEN(VG_Z_LD_ELF_SO_1
, strlen
)
517 STRLEN(VG_Z_LD_ELF32_SO_1
, strlen
)
519 #elif defined(VGO_darwin)
520 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
521 # if DARWIN_VERS >= DARWIN_10_9
522 STRLEN(libsystemZucZddylib
, strlen
)
525 #elif defined(VGO_solaris)
526 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
527 STRLEN(VG_Z_LD_SO_1
, strlen
)
532 /*---------------------- strcpy ----------------------*/
534 #define STRCPY(soname, fnname) \
535 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
536 ( char* dst, const char* src ); \
537 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
538 ( char* dst, const char* src ) \
540 const HChar* src_orig = src; \
541 HChar* dst_orig = dst; \
543 while (*src) *dst++ = *src++; \
546 /* This happens after copying, unavoidable without */ \
547 /* pre-counting length... should be ok */ \
548 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
549 RECORD_COPY(srclen); \
550 if (is_overlap(dst_orig, \
552 (Addr)dst-(Addr)dst_orig+1, \
554 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
559 #if defined(VGO_linux)
560 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
561 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
563 #elif defined(VGO_freebsd)
564 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
565 STRCPY(VG_Z_LD_ELF_SO_1
, strcpy
)
566 STRCPY(VG_Z_LD_ELF32_SO_1
, strcpy
)
568 #elif defined(VGO_darwin)
569 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
570 # if DARWIN_VERS == DARWIN_10_9
571 STRCPY(libsystemZucZddylib
, strcpy
)
574 #elif defined(VGO_solaris)
575 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
576 STRCPY(VG_Z_LD_SO_1
, strcpy
)
581 /*---------------------- strncpy ----------------------*/
583 #define STRNCPY(soname, fnname) \
584 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
585 ( char* dst, const char* src, SizeT n ); \
586 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
587 ( char* dst, const char* src, SizeT n ) \
589 const HChar* src_orig = src; \
590 HChar* dst_orig = dst; \
593 while (m < n && *src) { m++; *dst++ = *src++; } \
594 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
595 /* but only m+1 bytes of src if terminator was found */ \
596 SizeT srclen = (m < n) ? m+1 : n; \
597 RECORD_COPY(srclen); \
598 if (is_overlap(dst_orig, src_orig, n, srclen)) \
599 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
600 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
605 #if defined(VGO_linux)
606 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
607 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
608 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
609 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
611 #elif defined(VGO_freebsd)
612 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
613 STRNCPY(VG_Z_LD_ELF_SO_1
, strncpy
)
614 STRNCPY(VG_Z_LD_ELF32_SO_1
, strncpy
)
616 #elif defined(VGO_darwin)
617 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
618 # if DARWIN_VERS >= DARWIN_10_9
619 STRNCPY(libsystemZucZddylib
, strncpy
)
622 #elif defined(VGO_solaris)
623 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
624 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
629 /*---------------------- strlcpy ----------------------*/
631 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
632 Returns strlen(src). Does not zero-fill the remainder of dst. */
633 #define STRLCPY(soname, fnname) \
634 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
635 ( char* dst, const char* src, SizeT n ); \
636 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
637 ( char* dst, const char* src, SizeT n ) \
639 const HChar* src_orig = src; \
640 HChar* dst_orig = dst; \
643 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
645 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
646 /* m non-nul bytes have now been copied, and m <= n-1. */ \
647 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
648 /* but only m+1 bytes of src if terminator was found */ \
649 SizeT srclen = (m < n) ? m+1 : n; \
650 RECORD_COPY(srclen); \
651 if (is_overlap(dst_orig, src_orig, n, srclen)) \
652 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
653 /* Nul-terminate dst. */ \
654 if (n > 0) *dst = 0; \
655 /* Finish counting strlen(src). */ \
656 while (*src) src++; \
657 return src - src_orig; \
660 #if defined(VGO_linux)
662 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
663 || defined(VGPV_mips32_linux_android)
664 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
665 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
668 #elif defined(VGO_freebsd)
669 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
670 STRLCPY(VG_Z_LD_ELF_SO_1
, strlcpy
)
671 STRLCPY(VG_Z_LD_ELF32_SO_1
, strlcpy
)
672 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
674 #elif defined(VGO_darwin)
675 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
676 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
677 //STRLCPY(VG_Z_DYLD, strlcpy)
678 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
680 #elif defined(VGO_solaris)
681 /* special case for n == 0 which is undocumented but heavily used */
682 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
684 while (*src) src++; \
685 return src - src_orig; \
688 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
693 /*---------------------- strncmp ----------------------*/
695 #define STRNCMP(soname, fnname) \
696 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
697 ( const char* s1, const char* s2, SizeT nmax ); \
698 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
699 ( const char* s1, const char* s2, SizeT nmax ) \
703 if (n >= nmax) return 0; \
704 if (*s1 == 0 && *s2 == 0) return 0; \
705 if (*s1 == 0) return -1; \
706 if (*s2 == 0) return 1; \
708 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
709 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
715 #if defined(VGO_linux)
716 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
717 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
718 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
719 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
720 STRNCMP(VG_Z_LD_LINUX_SO_2
, strncmp
)
721 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strncmp
)
723 #elif defined(VGO_freebsd)
724 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
725 STRNCMP(VG_Z_LD_ELF_SO_1
, strncmp
)
726 STRNCMP(VG_Z_LD_ELF32_SO_1
, strncmp
)
728 #elif defined(VGO_darwin)
729 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
730 # if DARWIN_VERS >= DARWIN_10_9
731 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
734 #elif defined(VGO_solaris)
735 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
740 /*---------------------- strcasecmp ----------------------*/
742 #define STRCASECMP(soname, fnname) \
743 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
744 ( const char* s1, const char* s2 ); \
745 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
746 ( const char* s1, const char* s2 ) \
748 extern int tolower(int); \
752 c1 = tolower(*(const UChar *)s1); \
753 c2 = tolower(*(const UChar *)s2); \
754 if (c1 != c2) break; \
755 if (c1 == 0) break; \
758 if ((UChar)c1 < (UChar)c2) return -1; \
759 if ((UChar)c1 > (UChar)c2) return 1; \
763 #if defined(VGO_linux)
764 # if !defined(VGPV_arm_linux_android) \
765 && !defined(VGPV_x86_linux_android) \
766 && !defined(VGPV_mips32_linux_android) \
767 && !defined(VGPV_arm64_linux_android)
768 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
769 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
772 #elif defined(VGO_freebsd)
773 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
774 STRNCMP(VG_Z_LD_ELF_SO_1
, strcasecmp
)
775 STRNCMP(VG_Z_LD_ELF32_SO_1
, strcasecmp
)
777 #elif defined(VGO_darwin)
778 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
780 #elif defined(VGO_solaris)
781 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
786 /*---------------------- strncasecmp ----------------------*/
788 #define STRNCASECMP(soname, fnname) \
789 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
790 ( const char* s1, const char* s2, SizeT nmax ); \
791 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
792 ( const char* s1, const char* s2, SizeT nmax ) \
794 extern int tolower(int); \
797 if (n >= nmax) return 0; \
798 if (*s1 == 0 && *s2 == 0) return 0; \
799 if (*s1 == 0) return -1; \
800 if (*s2 == 0) return 1; \
802 if (tolower(*(const UChar *)s1) \
803 < tolower(*(const UChar*)s2)) return -1; \
804 if (tolower(*(const UChar *)s1) \
805 > tolower(*(const UChar *)s2)) return 1; \
811 #if defined(VGO_linux)
812 # if !defined(VGPV_arm_linux_android) \
813 && !defined(VGPV_x86_linux_android) \
814 && !defined(VGPV_mips32_linux_android) \
815 && !defined(VGPV_arm64_linux_android)
816 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
817 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
820 #elif defined(VGO_freebsd)
821 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
822 STRNCASECMP(VG_Z_LD_ELF_SO_1
, strncasecmp
)
823 STRNCASECMP(VG_Z_LD_ELF32_SO_1
, strncasecmp
)
825 #elif defined(VGO_darwin)
826 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
827 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
829 #elif defined(VGO_solaris)
830 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
835 /*---------------------- strcasecmp_l ----------------------*/
837 #define STRCASECMP_L(soname, fnname) \
838 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
839 ( const char* s1, const char* s2, void* locale ); \
840 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
841 ( const char* s1, const char* s2, void* locale ) \
843 extern int tolower_l(int, void*) __attribute__((weak)); \
847 c1 = tolower_l(*(const UChar *)s1, locale); \
848 c2 = tolower_l(*(const UChar *)s2, locale); \
849 if (c1 != c2) break; \
850 if (c1 == 0) break; \
853 if ((UChar)c1 < (UChar)c2) return -1; \
854 if ((UChar)c1 > (UChar)c2) return 1; \
858 #if defined(VGO_linux)
859 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
860 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
861 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
863 #elif defined(VGO_freebsd)
864 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
866 #elif defined(VGO_darwin)
867 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
869 #elif defined(VGO_solaris)
874 /*---------------------- strncasecmp_l ----------------------*/
876 #define STRNCASECMP_L(soname, fnname) \
877 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
878 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
879 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
880 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
882 extern int tolower_l(int, void*) __attribute__((weak)); \
885 if (n >= nmax) return 0; \
886 if (*s1 == 0 && *s2 == 0) return 0; \
887 if (*s1 == 0) return -1; \
888 if (*s2 == 0) return 1; \
890 if (tolower_l(*(const UChar *)s1, locale) \
891 < tolower_l(*(const UChar *)s2, locale)) return -1; \
892 if (tolower_l(*(const UChar *)s1, locale) \
893 > tolower_l(*(const UChar *)s2, locale)) return 1; \
899 #if defined(VGO_linux)
900 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
902 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
904 #elif defined(VGO_freebsd)
905 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
907 #elif defined(VGO_darwin)
908 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
909 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
911 #elif defined(VGO_solaris)
916 /*---------------------- strcmp ----------------------*/
918 #define STRCMP(soname, fnname) \
919 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
920 ( const char* s1, const char* s2 ); \
921 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
922 ( const char* s1, const char* s2 ) \
927 c1 = *(const UChar *)s1; \
928 c2 = *(const UChar *)s2; \
929 if (c1 != c2) break; \
930 if (c1 == 0) break; \
933 if ((UChar)c1 < (UChar)c2) return -1; \
934 if ((UChar)c1 > (UChar)c2) return 1; \
938 #if defined(VGO_linux)
939 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
940 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
941 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
942 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
943 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
944 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
945 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
946 || defined(VGPV_mips32_linux_android)
947 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
950 #elif defined(VGO_freebsd)
951 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
952 STRCMP(VG_Z_LD_ELF_SO_1
, strcmp
)
953 STRCMP(VG_Z_LD_ELF32_SO_1
, strcmp
)
955 #elif defined(VGO_darwin)
956 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
957 # if DARWIN_VERS >= DARWIN_10_9
958 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
961 #elif defined(VGO_solaris)
962 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
963 STRCMP(VG_Z_LD_SO_1
, strcmp
)
968 /*---------------------- memchr ----------------------*/
970 #define MEMCHR(soname, fnname) \
971 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
972 (const void *s, int c, SizeT n); \
973 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
974 (const void *s, int c, SizeT n) \
977 UChar c0 = (UChar)c; \
978 const UChar* p = s; \
979 for (i = 0; i < n; i++) \
980 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
984 #if defined(VGO_linux)
985 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
986 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
988 #elif defined(VGO_freebsd)
989 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
991 #elif defined(VGO_darwin)
992 # if DARWIN_VERS == DARWIN_10_9
993 MEMCHR(VG_Z_DYLD
, memchr
)
994 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
996 # if DARWIN_VERS >= DARWIN_10_10
997 MEMCHR(VG_Z_DYLD
, memchr
)
998 /* _platform_memchr$VARIANT$Generic */
999 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
1000 /* _platform_memchr$VARIANT$Haswell */
1001 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
1004 #elif defined(VGO_solaris)
1005 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
1010 /*---------------------- memrchr ----------------------*/
1012 #define MEMRCHR(soname, fnname) \
1013 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1014 (const void *s, int c, SizeT n); \
1015 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1016 (const void *s, int c, SizeT n) \
1019 UChar c0 = (UChar)c; \
1020 const UChar* p = s; \
1021 for (i = 0; i < n; i++) \
1022 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1026 #if defined(VGO_linux)
1027 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1029 #elif defined(VGO_freebsd)
1030 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1032 #elif defined(VGO_darwin)
1033 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1034 //MEMRCHR(VG_Z_DYLD, memrchr)
1036 #elif defined(VGO_solaris)
1041 /*---------------------- memcpy ----------------------*/
1043 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1044 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1045 ( void *dst, const void *src, SizeT len ); \
1046 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1047 ( void *dst, const void *src, SizeT len ) \
1050 if (do_ol_check && is_overlap(dst, src, len, len)) \
1051 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1053 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1054 const Addr WM = WS - 1; /* 7 or 3 */ \
1057 if (dst < src || !is_overlap(dst, src, len, len)) { \
1059 /* Copying backwards. */ \
1061 Addr d = (Addr)dst; \
1062 Addr s = (Addr)src; \
1064 if (((s^d) & WM) == 0) { \
1065 /* s and d have same UWord alignment. */ \
1066 /* Pull up to a UWord boundary. */ \
1067 while ((s & WM) != 0 && n >= 1) \
1068 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1069 /* Copy UWords. */ \
1070 while (n >= WS * 4) \
1071 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1072 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1073 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1074 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1076 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1080 if (((s|d) & 1) == 0) { \
1081 /* Both are 16-aligned; copy what we can thusly. */ \
1083 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1085 /* Copy leftovers, or everything if misaligned. */ \
1087 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1089 } else if (dst > src) { \
1092 Addr d = ((Addr)dst) + n; \
1093 Addr s = ((Addr)src) + n; \
1095 /* Copying forwards. */ \
1096 if (((s^d) & WM) == 0) { \
1097 /* s and d have same UWord alignment. */ \
1098 /* Back down to a UWord boundary. */ \
1099 while ((s & WM) != 0 && n >= 1) \
1100 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1101 /* Copy UWords. */ \
1102 while (n >= WS * 4) \
1103 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1104 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1105 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1106 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1108 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1112 if (((s|d) & 1) == 0) { \
1113 /* Both are 16-aligned; copy what we can thusly. */ \
1115 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1117 /* Copy leftovers, or everything if misaligned. */ \
1119 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1127 #define MEMMOVE(soname, fnname) \
1128 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1130 #define MEMCPY(soname, fnname) \
1131 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1133 #if defined(VGO_linux)
1134 /* For older memcpy we have to use memmove-like semantics and skip
1135 the overlap check; sigh; see #275284. */
1136 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1137 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1138 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1139 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1140 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1141 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_avx_unaligned_erms
)
1142 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1143 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1144 /* icc9 blats these around all over the place. Not only in the main
1145 executable but various .so's. They are highly tuned and read
1146 memory beyond the source boundary (although work correctly and
1147 never go across page boundaries), so give errors when run
1148 natively, at least for misaligned source arg. Just intercepting
1149 in the exe only until we understand more about the problem. See
1150 http://bugs.kde.org/show_bug.cgi?id=139776
1152 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1154 #elif defined(VGO_freebsd)
1155 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1156 MEMCPY(VG_Z_LD_ELF_SO_1
, memcpy
)
1157 MEMCPY(VG_Z_LD_ELF32_SO_1
, memcpy
)
1159 #elif defined(VGO_darwin)
1160 # if DARWIN_VERS <= DARWIN_10_6
1161 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1163 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1164 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1166 #elif defined(VGO_solaris)
1167 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1168 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZPZa
)
1169 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1174 /*---------------------- memcmp ----------------------*/
1176 #define MEMCMP(soname, fnname) \
1177 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1178 ( const void *s1V, const void *s2V, SizeT n ); \
1179 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1180 ( const void *s1V, const void *s2V, SizeT n ) \
1182 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1183 const SizeT WM = WS - 1; /* 7 or 3 */ \
1184 Addr s1A = (Addr)s1V; \
1185 Addr s2A = (Addr)s2V; \
1187 if (((s1A | s2A) & WM) == 0) { \
1188 /* Both areas are word aligned. Skip over the */ \
1189 /* equal prefix as fast as possible. */ \
1191 UWord w1 = *(UWord*)s1A; \
1192 UWord w2 = *(UWord*)s2A; \
1193 if (w1 != w2) break; \
1200 const UChar* s1 = (const UChar*) s1A; \
1201 const UChar* s2 = (const UChar*) s2A; \
1208 int res = ((int)a0) - ((int)b0); \
1216 #if defined(VGO_linux)
1217 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1218 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1219 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1220 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1221 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1222 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1224 #elif defined(VGO_freebsd)
1225 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1226 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1228 #elif defined(VGO_darwin)
1229 # if DARWIN_VERS >= DARWIN_10_9
1230 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1233 #elif defined(VGO_solaris)
1234 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1235 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1236 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1241 /*---------------------- stpcpy ----------------------*/
1243 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1244 DEST. (minor variant of strcpy) */
1245 #define STPCPY(soname, fnname) \
1246 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1247 ( char* dst, const char* src ); \
1248 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1249 ( char* dst, const char* src ) \
1251 const HChar* src_orig = src; \
1252 HChar* dst_orig = dst; \
1254 while (*src) *dst++ = *src++; \
1257 /* This checks for overlap after copying, unavoidable without */ \
1258 /* pre-counting length... should be ok */ \
1259 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1260 RECORD_COPY(srclen); \
1261 if (is_overlap(dst_orig, \
1263 (Addr)dst-(Addr)dst_orig+1, \
1265 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1270 #if defined(VGO_linux)
1271 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1272 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1273 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1274 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1275 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1276 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1277 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1
,stpcpy
)
1279 #elif defined(VGO_freebsd)
1280 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1281 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1282 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1284 #elif defined(VGO_freebsd)
1285 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1286 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1287 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1289 #elif defined(VGO_darwin)
1290 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1291 //STPCPY(VG_Z_DYLD, stpcpy)
1293 #elif defined(VGO_solaris)
1294 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1299 /*---------------------- stpncpy ----------------------*/
1301 #define STPNCPY(soname, fnname) \
1302 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1303 ( char* dst, const char* src, SizeT n ); \
1304 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1305 ( char* dst, const char* src, SizeT n ) \
1307 const HChar* src_orig = src; \
1308 HChar* dst_str = dst; \
1311 while (m < n && *src) { m++; *dst++ = *src++; } \
1312 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1313 /* but only m+1 bytes of src if terminator was found */ \
1314 SizeT srclen = (m < n) ? m+1 : n; \
1315 RECORD_COPY(srclen); \
1316 if (is_overlap(dst_str, src_orig, n, srclen)) \
1317 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1319 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1324 #if defined(VGO_linux) || defined(VGO_freebsd)
1325 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1329 /*---------------------- memset ----------------------*/
1331 #define MEMSET(soname, fnname) \
1332 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1333 (void *s, Int c, SizeT n); \
1334 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1335 (void *s, Int c, SizeT n) \
1337 if (sizeof(void*) == 8) { \
1339 ULong c8 = (c & 0xFF); \
1340 c8 = (c8 << 8) | c8; \
1341 c8 = (c8 << 16) | c8; \
1342 c8 = (c8 << 32) | c8; \
1343 while ((a & 7) != 0 && n >= 1) \
1344 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1346 { *(ULong*)a = c8; a += 8; n -= 8; \
1347 *(ULong*)a = c8; a += 8; n -= 8; \
1348 *(ULong*)a = c8; a += 8; n -= 8; \
1349 *(ULong*)a = c8; a += 8; n -= 8; } \
1351 { *(ULong*)a = c8; a += 8; n -= 8; } \
1353 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1357 UInt c4 = (c & 0xFF); \
1358 c4 = (c4 << 8) | c4; \
1359 c4 = (c4 << 16) | c4; \
1360 while ((a & 3) != 0 && n >= 1) \
1361 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1363 { *(UInt*)a = c4; a += 4; n -= 4; \
1364 *(UInt*)a = c4; a += 4; n -= 4; \
1365 *(UInt*)a = c4; a += 4; n -= 4; \
1366 *(UInt*)a = c4; a += 4; n -= 4; } \
1368 { *(UInt*)a = c4; a += 4; n -= 4; } \
1370 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1375 #if defined(VGO_linux)
1376 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1378 #elif defined(VGO_freebsd)
1379 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1380 MEMSET(VG_Z_LD_ELF_SO_1
, memset
)
1381 MEMSET(VG_Z_LD_ELF32_SO_1
, memset
)
1383 #elif defined(VGO_darwin)
1384 //MEMSET(VG_Z_LIBC_SONAME, memset)
1385 //MEMSET(VG_Z_DYLD, memset)
1386 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1388 #elif defined(VGO_solaris)
1389 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1390 MEMSET(VG_Z_LIBC_SONAME
, memsetZPZa
)
1395 /*---------------------- memmove ----------------------*/
1397 /* memmove -- use the MEMMOVE defn above. */
1399 #if defined(VGO_linux)
1400 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1401 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1402 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1403 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1405 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1407 #elif defined(VGO_freebsd)
1408 MEMMOVE(VG_Z_LD_ELF_SO_1
, memmove
)
1409 MEMMOVE(VG_Z_LD_ELF32_SO_1
, memmove
)
1410 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1412 #elif defined(VGO_darwin)
1413 # if DARWIN_VERS <= DARWIN_10_6
1414 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1416 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1417 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1418 # if DARWIN_VERS >= DARWIN_10_9
1419 /* _platform_memmove$VARIANT$Ivybridge */
1420 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1423 #elif defined(VGO_solaris)
1424 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1425 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZPZa
)
1426 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1431 /*---------------------- bcopy ----------------------*/
1433 #define BCOPY(soname, fnname) \
1434 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1435 (const void *srcV, void *dstV, SizeT n); \
1436 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1437 (const void *srcV, void *dstV, SizeT n) \
1441 HChar* dst = dstV; \
1442 const HChar* src = srcV; \
1444 for (i = 0; i < n; i++) \
1449 for (i = 0; i < n; i++) \
1450 dst[n-i-1] = src[n-i-1]; \
1454 #if defined(VGO_linux)
1455 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1457 #elif defined(VGO_freebsd)
1458 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1459 BCOPY(VG_Z_LD_ELF_SO_1
, bcopy
)
1460 BCOPY(VG_Z_LD_ELF32_SO_1
, bcopy
)
1462 #elif defined(VGO_darwin)
1463 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1464 //BCOPY(VG_Z_DYLD, bcopy)
1466 #elif defined(VGO_darwin)
1467 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1472 /*-------------------- memmove_chk --------------------*/
1474 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1475 There is no specific part of glibc that this is copied from. */
1476 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1477 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1478 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1479 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1480 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1484 HChar* dst = dstV; \
1485 const HChar* src = srcV; \
1489 for (i = 0; i < n; i++) \
1494 for (i = 0; i < n; i++) \
1495 dst[n-i-1] = src[n-i-1]; \
1499 VALGRIND_PRINTF_BACKTRACE( \
1500 "*** memmove_chk: buffer overflow detected ***: " \
1501 "program terminated\n"); \
1507 #if defined(VGO_linux)
1508 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1510 #elif defined(VGO_darwin)
1512 #elif defined(VGO_solaris)
1517 /*-------------------- strchrnul --------------------*/
1519 /* Find the first occurrence of C in S or the final NUL byte. */
1520 #define GLIBC232_STRCHRNUL(soname, fnname) \
1521 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1522 (const char* s, int c_in); \
1523 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1524 (const char* s, int c_in) \
1526 HChar c = (HChar) c_in; \
1527 const HChar* char_ptr = s; \
1529 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1530 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1535 #if defined(VGO_linux)
1536 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1538 #elif defined(VGO_freebsd)
1539 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1541 #elif defined(VGO_darwin)
1543 #elif defined(VGO_solaris)
1548 /*---------------------- rawmemchr ----------------------*/
1550 /* Find the first occurrence of C in S. */
1551 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1552 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1553 (const void* s, int c_in); \
1554 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1555 (const void* s, int c_in) \
1557 UChar c = (UChar) c_in; \
1558 const UChar* char_ptr = s; \
1560 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1565 #if defined (VGO_linux)
1566 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1567 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1569 #elif defined(VGO_darwin)
1571 #elif defined(VGO_solaris)
1576 /*---------------------- strcpy_chk ----------------------*/
1578 /* glibc variant of strcpy that checks the dest is big enough.
1579 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1580 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1581 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1582 (char* dst, const char* src, SizeT len); \
1583 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1584 (char* dst, const char* src, SizeT len) \
1586 FOR_COPY(const HChar* src_orig = src); \
1590 while ((*dst++ = *src++) != '\0') \
1593 RECORD_COPY((Addr)src-(Addr)src_orig); \
1596 VALGRIND_PRINTF_BACKTRACE( \
1597 "*** strcpy_chk: buffer overflow detected ***: " \
1598 "program terminated\n"); \
1604 #if defined(VGO_linux)
1605 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1607 #elif defined(VGO_darwin)
1609 #elif defined(VGO_solaris)
1614 /*---------------------- stpcpy_chk ----------------------*/
1616 /* glibc variant of stpcpy that checks the dest is big enough.
1617 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1618 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1619 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1620 (char* dst, const char* src, SizeT len); \
1621 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1622 (char* dst, const char* src, SizeT len) \
1624 FOR_COPY(const HChar* src_orig = src); \
1627 while ((*dst++ = *src++) != '\0') \
1630 RECORD_COPY((Addr)src-(Addr)src_orig); \
1633 VALGRIND_PRINTF_BACKTRACE( \
1634 "*** stpcpy_chk: buffer overflow detected ***: " \
1635 "program terminated\n"); \
1641 #if defined(VGO_linux)
1642 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1644 #elif defined(VGO_darwin)
1646 #elif defined(VGO_solaris)
1651 /*---------------------- mempcpy ----------------------*/
1654 #define GLIBC25_MEMPCPY(soname, fnname) \
1655 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1656 ( void *dst, const void *src, SizeT len ); \
1657 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1658 ( void *dst, const void *src, SizeT len ) \
1661 SizeT len_saved = len; \
1666 if (is_overlap(dst, src, len, len)) \
1667 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1669 if ( dst > src ) { \
1670 register HChar *d = (char *)dst + len - 1; \
1671 register const HChar *s = (const char *)src + len - 1; \
1675 } else if ( dst < src ) { \
1676 register HChar *d = dst; \
1677 register const HChar *s = src; \
1682 return (void*)( ((char*)dst) + len_saved ); \
1685 #if defined(VGO_linux)
1686 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1687 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1688 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1689 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1690 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1692 #elif defined(VGO_freebsd)
1693 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1694 #elif defined(VGO_darwin)
1695 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1697 #elif defined(VGO_solaris)
1702 /*-------------------- memcpy_chk --------------------*/
1704 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1705 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1706 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1707 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1708 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1710 register HChar *d; \
1711 register const HChar *s; \
1717 if (is_overlap(dst, src, len, len)) \
1718 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1719 if ( dst > src ) { \
1720 d = (HChar *)dst + len - 1; \
1721 s = (const HChar *)src + len - 1; \
1725 } else if ( dst < src ) { \
1727 s = (const HChar *)src; \
1734 VALGRIND_PRINTF_BACKTRACE( \
1735 "*** memcpy_chk: buffer overflow detected ***: " \
1736 "program terminated\n"); \
1742 #if defined(VGO_linux)
1743 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1745 #elif defined(VGO_darwin)
1747 #elif defined(VGO_solaris)
1752 /*---------------------- strstr ----------------------*/
1754 #define STRSTR(soname, fnname) \
1755 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1756 (const char* haystack, const char* needle); \
1757 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1758 (const char* haystack, const char* needle) \
1760 const HChar* h = haystack; \
1761 const HChar* n = needle; \
1763 /* find the length of n, not including terminating zero */ \
1765 while (n[nlen]) nlen++; \
1767 /* if n is the empty string, match immediately. */ \
1768 if (nlen == 0) return CONST_CAST(HChar *,h); \
1770 /* assert(nlen >= 1); */ \
1774 const HChar hh = *h; \
1775 if (hh == 0) return NULL; \
1776 if (hh != n0) { h++; continue; } \
1779 for (i = 0; i < nlen; i++) { \
1783 /* assert(i >= 0 && i <= nlen); */ \
1785 return CONST_CAST(HChar *,h); \
1791 #if defined(VGO_linux)
1792 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1793 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1794 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1796 #elif defined(VGO_freebsd)
1797 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1799 #elif defined(VGO_darwin)
1801 #elif defined(VGO_solaris)
1802 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1806 /*---------------------- memmem ----------------------*/
1808 #define MEMMEM(soname, fnname) \
1809 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1810 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1811 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1812 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1814 const HChar* h = haystack; \
1815 const HChar* n = needle; \
1817 /* If the needle is the empty string, match immediately. */ \
1818 if (nlen == 0) return CONST_CAST(void *,h); \
1822 for (; hlen >= nlen; hlen--, h++) { \
1823 if (h[0] != n0) continue; \
1826 for (i = 1; i < nlen; i++) { \
1831 return CONST_CAST(HChar *,h); \
1837 #if defined(VGP_s390x_linux)
1838 MEMMEM(VG_Z_LIBC_SONAME
, memmem
)
1842 /*---------------------- strpbrk ----------------------*/
1844 #define STRPBRK(soname, fnname) \
1845 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1846 (const char* sV, const char* acceptV); \
1847 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1848 (const char* sV, const char* acceptV) \
1850 const HChar* s = sV; \
1851 const HChar* accept = acceptV; \
1853 /* find the length of 'accept', not including terminating zero */ \
1855 while (accept[nacc]) nacc++; \
1857 /* if n is the empty string, fail immediately. */ \
1858 if (nacc == 0) return NULL; \
1860 /* assert(nacc >= 1); */ \
1866 for (i = 0; i < nacc; i++) { \
1867 if (sc == accept[i]) \
1868 return CONST_CAST(HChar *,s); \
1876 #if defined(VGO_linux)
1877 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1879 #elif defined(VGO_freebsd)
1880 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1882 #elif defined(VGO_darwin)
1884 #elif defined(VGO_solaris)
1885 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1890 /*---------------------- strcspn ----------------------*/
1892 #define STRCSPN(soname, fnname) \
1893 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1894 (const char* sV, const char* rejectV); \
1895 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1896 (const char* sV, const char* rejectV) \
1898 const HChar* s = sV; \
1899 const HChar* reject = rejectV; \
1901 /* find the length of 'reject', not including terminating zero */ \
1903 while (reject[nrej]) nrej++; \
1911 for (i = 0; i < nrej; i++) { \
1912 if (sc == reject[i]) \
1915 /* assert(i >= 0 && i <= nrej); */ \
1925 #if defined(VGO_linux)
1926 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1927 STRCSPN(VG_Z_LIBC_SONAME
, __GI_strcspn
)
1929 #elif defined(VGO_freebsd)
1930 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1932 #elif defined(VGO_darwin)
1934 #elif defined(VGO_solaris)
1935 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1940 /*---------------------- strspn ----------------------*/
1942 #define STRSPN(soname, fnname) \
1943 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1944 (const char* sV, const char* acceptV); \
1945 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1946 (const char* sV, const char* acceptV) \
1948 const UChar* s = (const UChar *)sV; \
1949 const UChar* accept = (const UChar *)acceptV; \
1951 /* find the length of 'accept', not including terminating zero */ \
1953 while (accept[nacc]) nacc++; \
1954 if (nacc == 0) return 0; \
1962 for (i = 0; i < nacc; i++) { \
1963 if (sc == accept[i]) \
1966 /* assert(i >= 0 && i <= nacc); */ \
1976 #if defined(VGO_linux)
1977 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1979 #elif defined(VGO_freebsd)
1980 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1982 #elif defined(VGO_darwin)
1984 #elif defined(VGO_solaris)
1985 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1990 /*---------------------- strcasestr ----------------------*/
1992 #define STRCASESTR(soname, fnname) \
1993 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1994 (const char* haystack, const char* needle); \
1995 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1996 (const char* haystack, const char* needle) \
1998 extern int tolower(int); \
1999 const HChar* h = haystack; \
2000 const HChar* n = needle; \
2002 /* find the length of n, not including terminating zero */ \
2004 while (n[nlen]) nlen++; \
2006 /* if n is the empty string, match immediately. */ \
2007 if (nlen == 0) return CONST_CAST(HChar *,h); \
2009 /* assert(nlen >= 1); */ \
2010 UChar n0 = tolower(n[0]); \
2013 UChar hh = tolower(*h); \
2014 if (hh == 0) return NULL; \
2015 if (hh != n0) { h++; continue; } \
2018 for (i = 0; i < nlen; i++) { \
2019 if (tolower(n[i]) != tolower(h[i])) \
2022 /* assert(i >= 0 && i <= nlen); */ \
2024 return CONST_CAST(HChar *,h); \
2030 #if defined(VGO_linux)
2031 # if !defined(VGPV_arm_linux_android) \
2032 && !defined(VGPV_x86_linux_android) \
2033 && !defined(VGPV_mips32_linux_android) \
2034 && !defined(VGPV_arm64_linux_android)
2035 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2038 #elif defined(VGO_freebsd)
2039 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2041 #elif defined(VGO_darwin)
2043 #elif defined(VGO_solaris)
2044 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2049 /*---------------------- wcslen ----------------------*/
2051 // This is a wchar_t equivalent to strlen. Unfortunately
2052 // we don't have wchar_t available here, but it looks like
2053 // a 32 bit int on Linux. I don't know if that is also
2056 #define WCSLEN(soname, fnname) \
2057 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2058 ( const Int* str ); \
2059 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2060 ( const Int* str ) \
2063 while (str[i] != 0) i++; \
2067 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2068 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
2072 /*---------------------- wcsnlen ----------------------*/
2074 #define WCSNLEN(soname, fnname) \
2075 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2076 ( const Int *s, SizeT n ); \
2077 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2078 ( const Int *s, SizeT n ) \
2082 while (i < n && *p != 0) { \
2089 #if defined(VGO_linux) || defined(VGO_freebsd)
2090 WCSNLEN(VG_Z_LIBC_SONAME
, wcsnlen
)
2091 WCSNLEN(VG_Z_LIBC_SONAME
, __GI_wcsnlen
)
2094 /*---------------------- wcscmp ----------------------*/
2096 // This is a wchar_t equivalent to strcmp. We don't
2097 // have wchar_t available here, but in the GNU C Library
2098 // wchar_t is always 32 bits wide and wcscmp uses signed
2099 // comparison, not unsigned as in strcmp function.
2101 #define WCSCMP(soname, fnname) \
2102 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2103 ( const Int* s1, const Int* s2 ); \
2104 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2105 ( const Int* s1, const Int* s2 ) \
2112 if (c1 != c2) break; \
2113 if (c1 == 0) break; \
2116 if (c1 < c2) return -1; \
2117 if (c1 > c2) return 1; \
2121 #if defined(VGO_linux) || defined(VGO_freebsd)
2122 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
2125 /*---------------------- wcsncmp ----------------------*/
2127 // This is a wchar_t equivalent to strncmp. We don't
2128 // have wchar_t available here, but in the GNU C Library
2129 // wchar_t is always 32 bits wide and wcsncmp uses signed
2130 // comparison, not unsigned as in strncmp function.
2132 #define WCSNCMP(soname, fnname) \
2133 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2134 ( const Int* s1, const Int* s2, SizeT nmax ); \
2135 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2136 ( const Int* s1, const Int* s2, SizeT nmax ) \
2140 if (n >= nmax) return 0; \
2141 if (*s1 == 0 && *s2 == 0) return 0; \
2142 if (*s1 == 0) return -1; \
2143 if (*s2 == 0) return 1; \
2145 if (*s1 < *s2) return -1; \
2146 if (*s1 > *s2) return 1; \
2151 #if defined(VGO_linux) || defined(VGO_freebsd)
2152 WCSNCMP(VG_Z_LIBC_SONAME
, wcsncmp
)
2155 /*---------------------- wcscpy ----------------------*/
2157 // This is a wchar_t equivalent to strcpy. We don't
2158 // have wchar_t available here, but in the GNU C Library
2159 // wchar_t is always 32 bits wide.
2161 #define WCSCPY(soname, fnname) \
2162 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2163 ( Int* dst, const Int* src ); \
2164 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2165 ( Int* dst, const Int* src ) \
2167 const Int* src_orig = src; \
2168 Int* dst_orig = dst; \
2170 while (*src) *dst++ = *src++; \
2173 /* This checks for overlap after copying, unavoidable without */ \
2174 /* pre-counting length... should be ok */ \
2175 /* +4 because sizeof(wchar_t) == 4 */ \
2176 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2177 RECORD_COPY(srclen); \
2178 if (is_overlap(dst_orig, \
2180 /* +4 because sizeof(wchar_t) == 4 */ \
2181 (Addr)dst-(Addr)dst_orig+4, \
2183 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2188 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2189 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
2193 /*---------------------- wcschr ----------------------*/
2195 // This is a wchar_t equivalent to strchr. We don't
2196 // have wchar_t available here, but in the GNU C Library
2197 // wchar_t is always 32 bits wide.
2199 #define WCSCHR(soname, fnname) \
2200 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2201 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2205 if (*p == c) return CONST_CAST(Int *,p); \
2206 if (*p == 0) return NULL; \
2211 #if defined(VGO_linux) || defined(VGO_freebsd)
2212 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
2214 /*---------------------- wcsrchr ----------------------*/
2216 // This is a wchar_t equivalent to strrchr. We don't
2217 // have wchar_t available here, but in the GNU C Library
2218 // wchar_t is always 32 bits wide.
2220 #define WCSRCHR(soname, fnname) \
2221 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2222 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2225 const Int* last = NULL; \
2227 if (*p == c) last = p; \
2228 if (*p == 0) return CONST_CAST(Int *,last); \
2233 #if defined(VGO_linux) || defined(VGO_freebsd)
2234 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
2237 /*---------------------- wmemchr ----------------------*/
2239 // This is a wchar_t equivalent to memchr. We don't
2240 // have wchar_t available here, but in the GNU C Library
2241 // wchar_t is always 32 bits wide.
2243 #define WMEMCHR(soname, fnname) \
2244 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2245 (const Int *s, Int c, SizeT n); \
2246 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2247 (const Int *s, Int c, SizeT n) \
2251 for (i = 0; i < n; i++) { \
2252 if (*p == c) return CONST_CAST(Int *,p); \
2258 #if defined(VGO_linux)
2259 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2260 WMEMCHR(VG_Z_LIBC_SONAME
, __GI_wmemchr
)
2263 #if defined(VGO_freebsd)
2264 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2268 #define WMEMCMP(soname, fnname) \
2269 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2270 ( const Int *b1, const Int *b2, SizeT n ); \
2271 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2272 ( const Int *b1, const Int *b2, SizeT n ) \
2274 for (SizeT i = 0U; i < n; ++i) { \
2275 if (b1[i] != b2[i]) \
2276 return b1[i] > b2[i] ? 1 : -1; \
2281 #if defined(VGO_linux)
2282 WMEMCMP(VG_Z_LIBC_SONAME
, wmemcmp
)
2286 /*------------------------------------------------------------*/
2287 /*--- Improve definedness checking of process environment ---*/
2288 /*------------------------------------------------------------*/
2290 #if defined(VGO_linux) || defined(VGO_freebsd)
2292 /* If these wind up getting generated via a macro, so that multiple
2293 versions of each function exist (as above), use the _EZU variants
2294 to assign equivalance class tags. */
2296 /*---------------------- putenv ----------------------*/
2298 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
2299 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
2303 const HChar
* p
= string
;
2304 VALGRIND_GET_ORIG_FN(fn
);
2305 /* Now by walking over the string we magically produce
2306 traces when hitting undefined memory. */
2309 __asm__
__volatile__("" ::: "memory");
2310 CALL_FN_W_W(result
, fn
, string
);
2315 /*---------------------- unsetenv ----------------------*/
2317 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
2318 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
2322 const HChar
* p
= name
;
2323 VALGRIND_GET_ORIG_FN(fn
);
2324 /* Now by walking over the string we magically produce
2325 traces when hitting undefined memory. */
2328 __asm__
__volatile__("" ::: "memory");
2329 CALL_FN_W_W(result
, fn
, name
);
2334 /*---------------------- setenv ----------------------*/
2337 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2338 (const char* name
, const char* value
, int overwrite
);
2339 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2340 (const char* name
, const char* value
, int overwrite
)
2345 VALGRIND_GET_ORIG_FN(fn
);
2346 /* Now by walking over the string we magically produce
2347 traces when hitting undefined memory. */
2349 for (p
= name
; *p
; p
++)
2350 __asm__
__volatile__("" ::: "memory");
2352 for (p
= value
; *p
; p
++)
2353 __asm__
__volatile__("" ::: "memory");
2354 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2355 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2359 #endif /* defined(VGO_linux) */
2361 /*--------------------------------------------------------------------*/
2363 /*--------------------------------------------------------------------*/