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
109 #if defined(VGO_solaris)
111 Detour functions in the libc and the runtime linker. If a function isn't
112 much optimized (and no overlap checking is necessary) then redir the
113 function only in the libc. This way we can keep stacktraces in the tests
119 /* Figure out if [dst .. dst+dstlen-1] overlaps with
120 [src .. src+srclen-1].
121 We assume that the address ranges do not wrap around
122 (which is safe since on Linux addresses >= 0xC0000000
123 are not accessible and the program will segfault in this
124 circumstance, presumably).
127 Bool
is_overlap ( void* dst
, const void* src
, SizeT dstlen
, SizeT srclen
)
129 Addr loS
, hiS
, loD
, hiD
;
131 if (dstlen
== 0 || srclen
== 0)
136 hiS
= loS
+ srclen
- 1;
137 hiD
= loD
+ dstlen
- 1;
139 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
143 else if (loD
< loS
) {
147 /* They start at same place. Since we know neither of them has
148 zero length, they must overlap. */
154 /* Call here to exit if we can't continue. On Android we can't call
155 _exit for some reason, so we have to blunt-instrument it. */
156 __attribute__ ((__noreturn__
))
157 static inline void my_exit ( int x
)
159 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
160 || defined(VGPV_arm64_linux_android)
161 __asm__
__volatile__(".word 0xFFFFFFFF");
163 # elif defined(VGPV_x86_linux_android)
164 __asm__
__volatile__("ud2");
167 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
173 // This is a macro rather than a function because we don't want to have an
174 // extra function in the stack trace.
175 #ifndef RECORD_OVERLAP_ERROR
176 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
179 // Used for tools that record bulk copies: memcpy, strcpy, etc.
181 #define RECORD_COPY(len) do { } while (0)
184 #define FOR_COPY(x) x
187 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
188 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
192 /*---------------------- strrchr ----------------------*/
194 #define STRRCHR(soname, fnname) \
195 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
196 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
198 HChar ch = (HChar)c; \
199 const HChar* p = s; \
200 const HChar* last = NULL; \
202 if (*p == ch) last = p; \
203 if (*p == 0) return CONST_CAST(HChar *,last); \
208 // Apparently rindex() is the same thing as strrchr()
209 #if defined(VGO_linux)
210 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
211 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
212 STRRCHR(VG_Z_LIBC_SONAME
, __GI_strrchr
)
213 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2
)
214 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2_no_bsf
)
215 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse42
)
216 STRRCHR(VG_Z_LD_LINUX_SO_2
, rindex
)
217 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
218 || defined(VGPV_mips32_linux_android)
219 STRRCHR(NONE
, __dl_strrchr
); /* in /system/bin/linker */
222 #elif defined(VGO_freebsd)
223 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
224 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
225 STRRCHR(VG_Z_LD_ELF_SO_1
, strrchr
)
226 STRRCHR(VG_Z_LD_ELF32_SO_1
, strrchr
)
228 #elif defined(VGO_darwin)
229 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
230 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
231 //STRRCHR(VG_Z_DYLD, strrchr)
232 //STRRCHR(VG_Z_DYLD, rindex)
233 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
234 # if DARWIN_VERS >= DARWIN_10_9
235 STRRCHR(libsystemZucZddylib
, strrchr
)
238 #elif defined(VGO_solaris)
239 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
240 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
241 STRRCHR(VG_Z_LD_SO_1
, strrchr
)
246 /*---------------------- strchr ----------------------*/
248 #define STRCHR(soname, fnname) \
249 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
250 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
252 HChar ch = (HChar)c ; \
253 const HChar* p = s; \
255 if (*p == ch) return CONST_CAST(HChar *,p); \
256 if (*p == 0) return NULL; \
261 // Apparently index() is the same thing as strchr()
262 #if defined(VGO_linux)
263 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
264 STRCHR(VG_Z_LIBC_SONAME
, __GI_strchr
)
265 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2
)
266 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2_no_bsf
)
267 STRCHR(VG_Z_LIBC_SONAME
, index
)
268 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
269 STRCHR(VG_Z_LD_LINUX_SO_2
, strchr
)
270 STRCHR(VG_Z_LD_LINUX_SO_2
, index
)
271 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, strchr
)
272 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, index
)
275 #if defined(VGPV_mips32_linux_android)
276 STRCHR(NONE
, __dl_strchr
)
279 #elif defined(VGO_freebsd)
280 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
281 STRCHR(VG_Z_LIBC_SONAME
, index
)
282 STRCHR(VG_Z_LD_ELF_SO_1
, strchr
)
283 STRCHR(VG_Z_LD_ELF32_SO_1
, strchr
)
285 #elif defined(VGO_darwin)
286 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
287 # if DARWIN_VERS == DARWIN_10_9
288 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
290 # if DARWIN_VERS >= DARWIN_10_10
291 /* _platform_strchr$VARIANT$Generic */
292 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
293 /* _platform_strchr$VARIANT$Haswell */
294 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
296 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Base
)
298 #elif defined(VGO_solaris)
299 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
300 STRCHR(VG_Z_LIBC_SONAME
, index
)
301 STRCHR(VG_Z_LD_SO_1
, strchr
)
306 /*---------------------- strcat ----------------------*/
308 #define STRCAT(soname, fnname) \
309 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
310 ( char* dst, const char* src ); \
311 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
312 ( char* dst, const char* src ) \
314 const HChar* src_orig = src; \
315 HChar* dst_orig = dst; \
316 while (*dst) dst++; \
317 while (*src) *dst++ = *src++; \
320 /* This is a bit redundant, I think; any overlap and the strcat will */ \
321 /* go forever... or until a seg fault occurs. */ \
322 if (is_overlap(dst_orig, \
324 (Addr)dst-(Addr)dst_orig+1, \
325 (Addr)src-(Addr)src_orig+1)) \
326 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
331 #if defined(VGO_linux)
332 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
333 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
335 #elif defined(VGO_freebsd)
336 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
337 STRCAT(VG_Z_LD_ELF_SO_1
, strcat
)
338 STRCAT(VG_Z_LD_ELF32_SO_1
, strcat
)
340 #elif defined(VGO_darwin)
341 //STRCAT(VG_Z_LIBC_SONAME, strcat)
343 #elif defined(VGO_solaris)
344 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
345 STRCAT(VG_Z_LD_SO_1
, strcat
)
350 /*---------------------- strncat ----------------------*/
352 #define STRNCAT(soname, fnname) \
353 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
354 ( char* dst, const char* src, SizeT n ); \
355 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
356 ( char* dst, const char* src, SizeT n ) \
358 const HChar* src_orig = src; \
359 HChar* dst_orig = dst; \
362 while (*dst) dst++; \
363 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
364 *dst = 0; /* always add null */ \
366 /* This checks for overlap after copying, unavoidable without */ \
367 /* pre-counting lengths... should be ok */ \
368 if (is_overlap(dst_orig, \
370 (Addr)dst-(Addr)dst_orig+1, \
371 (Addr)src-(Addr)src_orig+1)) \
372 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
377 #if defined(VGO_linux)
378 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
380 #elif defined(VGO_freebsd)
381 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
383 #elif defined(VGO_darwin)
384 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
385 //STRNCAT(VG_Z_DYLD, strncat)
387 #elif defined(VGO_solaris)
388 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
393 /*---------------------- strlcat ----------------------*/
395 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
396 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
397 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
398 Truncation occurred if retval >= n.
400 #define STRLCAT(soname, fnname) \
401 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
402 ( char* dst, const char* src, SizeT n ); \
403 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
404 ( char* dst, const char* src, SizeT n ) \
406 const HChar* src_orig = src; \
407 HChar* dst_orig = dst; \
410 while (m < n && *dst) { m++; dst++; } \
412 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
413 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
416 /* No space to copy anything to dst. m == n */ \
418 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
419 while (*src) { m++; src++; } \
420 /* This checks for overlap after copying, unavoidable without */ \
421 /* pre-counting lengths... should be ok */ \
422 if (is_overlap(dst_orig, \
424 (Addr)dst-(Addr)dst_orig+1, \
425 (Addr)src-(Addr)src_orig+1)) \
426 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
431 #if defined(VGO_linux)
433 #elif defined(VGO_freebsd)
434 STRLCAT(VG_Z_LD_ELF_SO_1
, strlcat
)
435 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
436 STRLCAT(VG_Z_LD_ELF32_SO_1
, strlcat
)
438 #elif defined(VGO_darwin)
439 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
440 //STRLCAT(VG_Z_DYLD, strlcat)
441 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
443 #elif defined(VGO_solaris)
444 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
449 /*---------------------- strnlen ----------------------*/
451 #define STRNLEN(soname, fnname) \
452 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
453 ( const char* str, SizeT n ); \
454 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
455 ( const char* str, SizeT n ) \
458 while (i < n && str[i] != 0) i++; \
462 #if defined(VGO_linux)
463 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
464 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
466 #elif defined(VGO_freebsd)
468 STRNLEN(VG_Z_LIBC_SONAME
, srtnlen
)
470 #elif defined(VGO_darwin)
471 # if DARWIN_VERS == DARWIN_10_9
472 STRNLEN(libsystemZucZddylib
, strnlen
)
475 #elif defined(VGO_solaris)
476 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
481 /*---------------------- strlen ----------------------*/
483 // Note that this replacement often doesn't get used because gcc inlines
484 // calls to strlen() with its own built-in version. This can be very
485 // confusing if you aren't expecting it. Other small functions in
486 // this file may also be inline by gcc.
488 #define STRLEN(soname, fnname) \
489 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
490 ( const char* str ); \
491 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
492 ( const char* str ) \
495 while (str[i] != 0) i++; \
499 #if defined(VGO_linux)
500 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
501 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
502 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
503 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
504 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
505 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
506 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
507 # if defined(VGPV_arm_linux_android) \
508 || defined(VGPV_x86_linux_android) \
509 || defined(VGPV_mips32_linux_android)
510 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
513 #elif defined(VGO_freebsd)
514 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
515 STRLEN(VG_Z_LD_ELF_SO_1
, strlen
)
516 STRLEN(VG_Z_LD_ELF32_SO_1
, strlen
)
518 #elif defined(VGO_darwin)
519 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
520 # if DARWIN_VERS >= DARWIN_10_9
521 STRLEN(libsystemZucZddylib
, strlen
)
524 #elif defined(VGO_solaris)
525 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
526 STRLEN(VG_Z_LD_SO_1
, strlen
)
531 /*---------------------- strcpy ----------------------*/
533 #define STRCPY(soname, fnname) \
534 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
535 ( char* dst, const char* src ); \
536 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
537 ( char* dst, const char* src ) \
539 const HChar* src_orig = src; \
540 HChar* dst_orig = dst; \
542 while (*src) *dst++ = *src++; \
545 /* This happens after copying, unavoidable without */ \
546 /* pre-counting length... should be ok */ \
547 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
548 RECORD_COPY(srclen); \
549 if (is_overlap(dst_orig, \
551 (Addr)dst-(Addr)dst_orig+1, \
553 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
558 #if defined(VGO_linux)
559 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
560 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
562 #elif defined(VGO_freebsd)
563 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
564 STRCPY(VG_Z_LD_ELF_SO_1
, strcpy
)
565 STRCPY(VG_Z_LD_ELF32_SO_1
, strcpy
)
567 #elif defined(VGO_darwin)
568 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
569 # if DARWIN_VERS == DARWIN_10_9
570 STRCPY(libsystemZucZddylib
, strcpy
)
573 #elif defined(VGO_solaris)
574 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
575 STRCPY(VG_Z_LD_SO_1
, strcpy
)
580 /*---------------------- strncpy ----------------------*/
582 #define STRNCPY(soname, fnname) \
583 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
584 ( char* dst, const char* src, SizeT n ); \
585 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
586 ( char* dst, const char* src, SizeT n ) \
588 const HChar* src_orig = src; \
589 HChar* dst_orig = dst; \
592 while (m < n && *src) { m++; *dst++ = *src++; } \
593 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
594 /* but only m+1 bytes of src if terminator was found */ \
595 SizeT srclen = (m < n) ? m+1 : n; \
596 RECORD_COPY(srclen); \
597 if (is_overlap(dst_orig, src_orig, n, srclen)) \
598 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
599 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
604 #if defined(VGO_linux)
605 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
606 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
607 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
608 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
610 #elif defined(VGO_freebsd)
611 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
612 STRNCPY(VG_Z_LD_ELF_SO_1
, strncpy
)
613 STRNCPY(VG_Z_LD_ELF32_SO_1
, strncpy
)
615 #elif defined(VGO_darwin)
616 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
617 # if DARWIN_VERS >= DARWIN_10_9
618 STRNCPY(libsystemZucZddylib
, strncpy
)
621 #elif defined(VGO_solaris)
622 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
623 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
628 /*---------------------- strlcpy ----------------------*/
630 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
631 Returns strlen(src). Does not zero-fill the remainder of dst. */
632 #define STRLCPY(soname, fnname) \
633 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
634 ( char* dst, const char* src, SizeT n ); \
635 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
636 ( char* dst, const char* src, SizeT n ) \
638 const HChar* src_orig = src; \
639 HChar* dst_orig = dst; \
642 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
644 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
645 /* m non-nul bytes have now been copied, and m <= n-1. */ \
646 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
647 /* but only m+1 bytes of src if terminator was found */ \
648 SizeT srclen = (m < n) ? m+1 : n; \
649 RECORD_COPY(srclen); \
650 if (is_overlap(dst_orig, src_orig, n, srclen)) \
651 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
652 /* Nul-terminate dst. */ \
653 if (n > 0) *dst = 0; \
654 /* Finish counting strlen(src). */ \
655 while (*src) src++; \
656 return src - src_orig; \
659 #if defined(VGO_linux)
661 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
662 || defined(VGPV_mips32_linux_android)
663 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
664 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
667 #elif defined(VGO_freebsd)
668 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
669 STRLCPY(VG_Z_LD_ELF_SO_1
, strlcpy
)
670 STRLCPY(VG_Z_LD_ELF32_SO_1
, strlcpy
)
671 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
673 #elif defined(VGO_darwin)
674 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
675 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
676 //STRLCPY(VG_Z_DYLD, strlcpy)
677 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
679 #elif defined(VGO_solaris)
680 /* special case for n == 0 which is undocumented but heavily used */
681 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
683 while (*src) src++; \
684 return src - src_orig; \
687 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
692 /*---------------------- strncmp ----------------------*/
694 #define STRNCMP(soname, fnname) \
695 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
696 ( const char* s1, const char* s2, SizeT nmax ); \
697 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
698 ( const char* s1, const char* s2, SizeT nmax ) \
702 if (n >= nmax) return 0; \
703 if (*s1 == 0 && *s2 == 0) return 0; \
704 if (*s1 == 0) return -1; \
705 if (*s2 == 0) return 1; \
707 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
708 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
714 #if defined(VGO_linux)
715 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
716 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
717 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
718 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
719 STRNCMP(VG_Z_LD_LINUX_SO_2
, strncmp
)
720 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strncmp
)
722 #elif defined(VGO_freebsd)
723 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
724 STRNCMP(VG_Z_LD_ELF_SO_1
, strncmp
)
725 STRNCMP(VG_Z_LD_ELF32_SO_1
, strncmp
)
727 #elif defined(VGO_darwin)
728 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
729 # if DARWIN_VERS >= DARWIN_10_9
730 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
733 #elif defined(VGO_solaris)
734 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
739 /*---------------------- strcasecmp ----------------------*/
741 #define STRCASECMP(soname, fnname) \
742 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
743 ( const char* s1, const char* s2 ); \
744 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
745 ( const char* s1, const char* s2 ) \
747 extern int tolower(int); \
751 c1 = tolower(*(const UChar *)s1); \
752 c2 = tolower(*(const UChar *)s2); \
753 if (c1 != c2) break; \
754 if (c1 == 0) break; \
757 if ((UChar)c1 < (UChar)c2) return -1; \
758 if ((UChar)c1 > (UChar)c2) return 1; \
762 #if defined(VGO_linux)
763 # if !defined(VGPV_arm_linux_android) \
764 && !defined(VGPV_x86_linux_android) \
765 && !defined(VGPV_mips32_linux_android) \
766 && !defined(VGPV_arm64_linux_android)
767 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
768 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
771 #elif defined(VGO_freebsd)
772 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
773 STRNCMP(VG_Z_LD_ELF_SO_1
, strcasecmp
)
774 STRNCMP(VG_Z_LD_ELF32_SO_1
, strcasecmp
)
776 #elif defined(VGO_darwin)
777 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
779 #elif defined(VGO_solaris)
780 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
785 /*---------------------- strncasecmp ----------------------*/
787 #define STRNCASECMP(soname, fnname) \
788 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
789 ( const char* s1, const char* s2, SizeT nmax ); \
790 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
791 ( const char* s1, const char* s2, SizeT nmax ) \
793 extern int tolower(int); \
796 if (n >= nmax) return 0; \
797 if (*s1 == 0 && *s2 == 0) return 0; \
798 if (*s1 == 0) return -1; \
799 if (*s2 == 0) return 1; \
801 if (tolower(*(const UChar *)s1) \
802 < tolower(*(const UChar*)s2)) return -1; \
803 if (tolower(*(const UChar *)s1) \
804 > tolower(*(const UChar *)s2)) return 1; \
810 #if defined(VGO_linux)
811 # if !defined(VGPV_arm_linux_android) \
812 && !defined(VGPV_x86_linux_android) \
813 && !defined(VGPV_mips32_linux_android) \
814 && !defined(VGPV_arm64_linux_android)
815 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
816 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
819 #elif defined(VGO_freebsd)
820 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
821 STRNCASECMP(VG_Z_LD_ELF_SO_1
, strncasecmp
)
822 STRNCASECMP(VG_Z_LD_ELF32_SO_1
, strncasecmp
)
824 #elif defined(VGO_darwin)
825 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
826 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
828 #elif defined(VGO_solaris)
829 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
834 /*---------------------- strcasecmp_l ----------------------*/
836 #define STRCASECMP_L(soname, fnname) \
837 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
838 ( const char* s1, const char* s2, void* locale ); \
839 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
840 ( const char* s1, const char* s2, void* locale ) \
842 extern int tolower_l(int, void*) __attribute__((weak)); \
846 c1 = tolower_l(*(const UChar *)s1, locale); \
847 c2 = tolower_l(*(const UChar *)s2, locale); \
848 if (c1 != c2) break; \
849 if (c1 == 0) break; \
852 if ((UChar)c1 < (UChar)c2) return -1; \
853 if ((UChar)c1 > (UChar)c2) return 1; \
857 #if defined(VGO_linux)
858 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
859 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
860 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
862 #elif defined(VGO_freebsd)
863 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
865 #elif defined(VGO_darwin)
866 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
868 #elif defined(VGO_solaris)
873 /*---------------------- strncasecmp_l ----------------------*/
875 #define STRNCASECMP_L(soname, fnname) \
876 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
877 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
878 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
879 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
881 extern int tolower_l(int, void*) __attribute__((weak)); \
884 if (n >= nmax) return 0; \
885 if (*s1 == 0 && *s2 == 0) return 0; \
886 if (*s1 == 0) return -1; \
887 if (*s2 == 0) return 1; \
889 if (tolower_l(*(const UChar *)s1, locale) \
890 < tolower_l(*(const UChar *)s2, locale)) return -1; \
891 if (tolower_l(*(const UChar *)s1, locale) \
892 > tolower_l(*(const UChar *)s2, locale)) return 1; \
898 #if defined(VGO_linux)
899 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
900 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
903 #elif defined(VGO_freebsd)
904 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
906 #elif defined(VGO_darwin)
907 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
908 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
910 #elif defined(VGO_solaris)
915 /*---------------------- strcmp ----------------------*/
917 #define STRCMP(soname, fnname) \
918 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
919 ( const char* s1, const char* s2 ); \
920 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
921 ( const char* s1, const char* s2 ) \
926 c1 = *(const UChar *)s1; \
927 c2 = *(const UChar *)s2; \
928 if (c1 != c2) break; \
929 if (c1 == 0) break; \
932 if ((UChar)c1 < (UChar)c2) return -1; \
933 if ((UChar)c1 > (UChar)c2) return 1; \
937 #if defined(VGO_linux)
938 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
939 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
940 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
941 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
942 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
943 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
944 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
945 || defined(VGPV_mips32_linux_android)
946 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
949 #elif defined(VGO_freebsd)
950 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
951 STRCMP(VG_Z_LD_ELF_SO_1
, strcmp
)
952 STRCMP(VG_Z_LD_ELF32_SO_1
, strcmp
)
954 #elif defined(VGO_darwin)
955 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
956 # if DARWIN_VERS >= DARWIN_10_9
957 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
960 #elif defined(VGO_solaris)
961 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
962 STRCMP(VG_Z_LD_SO_1
, strcmp
)
967 /*---------------------- memchr ----------------------*/
969 #define MEMCHR(soname, fnname) \
970 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
971 (const void *s, int c, SizeT n); \
972 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
973 (const void *s, int c, SizeT n) \
976 UChar c0 = (UChar)c; \
977 const UChar* p = s; \
978 for (i = 0; i < n; i++) \
979 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
983 #if defined(VGO_linux)
984 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
985 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
987 #elif defined(VGO_freebsd)
988 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
990 #elif defined(VGO_darwin)
991 # if DARWIN_VERS == DARWIN_10_9
992 MEMCHR(VG_Z_DYLD
, memchr
)
993 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
995 # if DARWIN_VERS >= DARWIN_10_10
996 MEMCHR(VG_Z_DYLD
, memchr
)
997 /* _platform_memchr$VARIANT$Generic */
998 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
999 /* _platform_memchr$VARIANT$Haswell */
1000 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
1003 #elif defined(VGO_solaris)
1004 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
1009 /*---------------------- memrchr ----------------------*/
1011 #define MEMRCHR(soname, fnname) \
1012 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1013 (const void *s, int c, SizeT n); \
1014 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1015 (const void *s, int c, SizeT n) \
1018 UChar c0 = (UChar)c; \
1019 const UChar* p = s; \
1020 for (i = 0; i < n; i++) \
1021 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1025 #if defined(VGO_linux)
1026 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1028 #elif defined(VGO_freebsd)
1029 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1031 #elif defined(VGO_darwin)
1032 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1033 //MEMRCHR(VG_Z_DYLD, memrchr)
1035 #elif defined(VGO_solaris)
1040 /*---------------------- memcpy ----------------------*/
1042 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1043 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1044 ( void *dst, const void *src, SizeT len ); \
1045 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1046 ( void *dst, const void *src, SizeT len ) \
1049 if (do_ol_check && is_overlap(dst, src, len, len)) \
1050 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1052 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1053 const Addr WM = WS - 1; /* 7 or 3 */ \
1056 if (dst < src || !is_overlap(dst, src, len, len)) { \
1058 /* Copying backwards. */ \
1060 Addr d = (Addr)dst; \
1061 Addr s = (Addr)src; \
1063 if (((s^d) & WM) == 0) { \
1064 /* s and d have same UWord alignment. */ \
1065 /* Pull up to a UWord boundary. */ \
1066 while ((s & WM) != 0 && n >= 1) \
1067 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1068 /* Copy UWords. */ \
1069 while (n >= WS * 4) \
1070 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
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; } \
1075 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1079 if (((s|d) & 1) == 0) { \
1080 /* Both are 16-aligned; copy what we can thusly. */ \
1082 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1084 /* Copy leftovers, or everything if misaligned. */ \
1086 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1088 } else if (dst > src) { \
1091 Addr d = ((Addr)dst) + n; \
1092 Addr s = ((Addr)src) + n; \
1094 /* Copying forwards. */ \
1095 if (((s^d) & WM) == 0) { \
1096 /* s and d have same UWord alignment. */ \
1097 /* Back down to a UWord boundary. */ \
1098 while ((s & WM) != 0 && n >= 1) \
1099 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1100 /* Copy UWords. */ \
1101 while (n >= WS * 4) \
1102 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
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; } \
1107 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1111 if (((s|d) & 1) == 0) { \
1112 /* Both are 16-aligned; copy what we can thusly. */ \
1114 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1116 /* Copy leftovers, or everything if misaligned. */ \
1118 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1126 #define MEMMOVE(soname, fnname) \
1127 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1129 #define MEMCPY(soname, fnname) \
1130 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1132 #if defined(VGO_linux)
1133 /* For older memcpy we have to use memmove-like semantics and skip
1134 the overlap check; sigh; see #275284. */
1135 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1136 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1137 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1138 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1139 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1140 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_avx_unaligned_erms
)
1141 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1142 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1143 /* icc9 blats these around all over the place. Not only in the main
1144 executable but various .so's. They are highly tuned and read
1145 memory beyond the source boundary (although work correctly and
1146 never go across page boundaries), so give errors when run
1147 natively, at least for misaligned source arg. Just intercepting
1148 in the exe only until we understand more about the problem. See
1149 http://bugs.kde.org/show_bug.cgi?id=139776
1151 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1153 #elif defined(VGO_freebsd)
1154 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1155 MEMCPY(VG_Z_LD_ELF_SO_1
, memcpy
)
1156 MEMCPY(VG_Z_LD_ELF32_SO_1
, memcpy
)
1158 #elif defined(VGO_darwin)
1159 # if DARWIN_VERS <= DARWIN_10_6
1160 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1162 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1163 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1165 #elif defined(VGO_solaris)
1166 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1167 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZPZa
)
1168 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1173 /*---------------------- memcmp ----------------------*/
1175 #define MEMCMP(soname, fnname) \
1176 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1177 ( const void *s1V, const void *s2V, SizeT n ); \
1178 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1179 ( const void *s1V, const void *s2V, SizeT n ) \
1181 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1182 const SizeT WM = WS - 1; /* 7 or 3 */ \
1183 Addr s1A = (Addr)s1V; \
1184 Addr s2A = (Addr)s2V; \
1186 if (((s1A | s2A) & WM) == 0) { \
1187 /* Both areas are word aligned. Skip over the */ \
1188 /* equal prefix as fast as possible. */ \
1190 UWord w1 = *(UWord*)s1A; \
1191 UWord w2 = *(UWord*)s2A; \
1192 if (w1 != w2) break; \
1199 const UChar* s1 = (const UChar*) s1A; \
1200 const UChar* s2 = (const UChar*) s2A; \
1207 int res = ((int)a0) - ((int)b0); \
1215 #if defined(VGO_linux)
1216 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1217 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1218 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1219 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1220 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1221 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1223 #elif defined(VGO_freebsd)
1224 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1225 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1227 #elif defined(VGO_darwin)
1228 # if DARWIN_VERS >= DARWIN_10_9
1229 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1232 #elif defined(VGO_solaris)
1233 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1234 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1235 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1240 /*---------------------- stpcpy ----------------------*/
1242 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1243 DEST. (minor variant of strcpy) */
1244 #define STPCPY(soname, fnname) \
1245 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1246 ( char* dst, const char* src ); \
1247 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1248 ( char* dst, const char* src ) \
1250 const HChar* src_orig = src; \
1251 HChar* dst_orig = dst; \
1253 while (*src) *dst++ = *src++; \
1256 /* This checks for overlap after copying, unavoidable without */ \
1257 /* pre-counting length... should be ok */ \
1258 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1259 RECORD_COPY(srclen); \
1260 if (is_overlap(dst_orig, \
1262 (Addr)dst-(Addr)dst_orig+1, \
1264 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1269 #if defined(VGO_linux)
1270 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1271 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1272 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1273 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1274 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1275 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1276 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1
,stpcpy
)
1278 #elif defined(VGO_freebsd)
1279 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1280 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1281 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1283 #elif defined(VGO_freebsd)
1284 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1285 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1286 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1288 #elif defined(VGO_darwin)
1289 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1290 //STPCPY(VG_Z_DYLD, stpcpy)
1292 #elif defined(VGO_solaris)
1293 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1298 /*---------------------- stpncpy ----------------------*/
1300 #define STPNCPY(soname, fnname) \
1301 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1302 ( char* dst, const char* src, SizeT n ); \
1303 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1304 ( char* dst, const char* src, SizeT n ) \
1306 const HChar* src_orig = src; \
1307 HChar* dst_str = dst; \
1310 while (m < n && *src) { m++; *dst++ = *src++; } \
1311 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1312 /* but only m+1 bytes of src if terminator was found */ \
1313 SizeT srclen = (m < n) ? m+1 : n; \
1314 RECORD_COPY(srclen); \
1315 if (is_overlap(dst_str, src_orig, n, srclen)) \
1316 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1318 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1323 #if defined(VGO_linux) || defined(VGO_freebsd)
1324 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1328 /*---------------------- memset ----------------------*/
1330 #define MEMSET(soname, fnname) \
1331 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1332 (void *s, Int c, SizeT n); \
1333 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1334 (void *s, Int c, SizeT n) \
1336 if (sizeof(void*) == 8) { \
1338 ULong c8 = (c & 0xFF); \
1339 c8 = (c8 << 8) | c8; \
1340 c8 = (c8 << 16) | c8; \
1341 c8 = (c8 << 32) | c8; \
1342 while ((a & 7) != 0 && n >= 1) \
1343 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1345 { *(ULong*)a = c8; a += 8; n -= 8; \
1346 *(ULong*)a = c8; a += 8; n -= 8; \
1347 *(ULong*)a = c8; a += 8; n -= 8; \
1348 *(ULong*)a = c8; a += 8; n -= 8; } \
1350 { *(ULong*)a = c8; a += 8; n -= 8; } \
1352 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1356 UInt c4 = (c & 0xFF); \
1357 c4 = (c4 << 8) | c4; \
1358 c4 = (c4 << 16) | c4; \
1359 while ((a & 3) != 0 && n >= 1) \
1360 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1362 { *(UInt*)a = c4; a += 4; n -= 4; \
1363 *(UInt*)a = c4; a += 4; n -= 4; \
1364 *(UInt*)a = c4; a += 4; n -= 4; \
1365 *(UInt*)a = c4; a += 4; n -= 4; } \
1367 { *(UInt*)a = c4; a += 4; n -= 4; } \
1369 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1374 #if defined(VGO_linux)
1375 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1377 #elif defined(VGO_freebsd)
1378 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1379 MEMSET(VG_Z_LD_ELF_SO_1
, memset
)
1380 MEMSET(VG_Z_LD_ELF32_SO_1
, memset
)
1382 #elif defined(VGO_darwin)
1383 //MEMSET(VG_Z_LIBC_SONAME, memset)
1384 //MEMSET(VG_Z_DYLD, memset)
1385 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1387 #elif defined(VGO_solaris)
1388 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1389 MEMSET(VG_Z_LIBC_SONAME
, memsetZPZa
)
1394 /*---------------------- memmove ----------------------*/
1396 /* memmove -- use the MEMMOVE defn above. */
1398 #if defined(VGO_linux)
1399 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1400 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1401 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1402 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1404 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1406 #elif defined(VGO_freebsd)
1407 MEMMOVE(VG_Z_LD_ELF_SO_1
, memmove
)
1408 MEMMOVE(VG_Z_LD_ELF32_SO_1
, memmove
)
1409 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1411 #elif defined(VGO_darwin)
1412 # if DARWIN_VERS <= DARWIN_10_6
1413 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1415 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1416 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1417 # if DARWIN_VERS >= DARWIN_10_9
1418 /* _platform_memmove$VARIANT$Ivybridge */
1419 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1422 #elif defined(VGO_solaris)
1423 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1424 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZPZa
)
1425 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1430 /*---------------------- bcopy ----------------------*/
1432 #define BCOPY(soname, fnname) \
1433 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1434 (const void *srcV, void *dstV, SizeT n); \
1435 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1436 (const void *srcV, void *dstV, SizeT n) \
1440 HChar* dst = dstV; \
1441 const HChar* src = srcV; \
1443 for (i = 0; i < n; i++) \
1448 for (i = 0; i < n; i++) \
1449 dst[n-i-1] = src[n-i-1]; \
1453 #if defined(VGO_linux)
1454 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1456 #elif defined(VGO_freebsd)
1457 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1458 BCOPY(VG_Z_LD_ELF_SO_1
, bcopy
)
1459 BCOPY(VG_Z_LD_ELF32_SO_1
, bcopy
)
1461 #elif defined(VGO_darwin)
1462 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1463 //BCOPY(VG_Z_DYLD, bcopy)
1465 #elif defined(VGO_darwin)
1466 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1471 /*-------------------- memmove_chk --------------------*/
1473 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1474 There is no specific part of glibc that this is copied from. */
1475 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1476 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1477 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1478 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1479 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1483 HChar* dst = dstV; \
1484 const HChar* src = srcV; \
1488 for (i = 0; i < n; i++) \
1493 for (i = 0; i < n; i++) \
1494 dst[n-i-1] = src[n-i-1]; \
1498 VALGRIND_PRINTF_BACKTRACE( \
1499 "*** memmove_chk: buffer overflow detected ***: " \
1500 "program terminated\n"); \
1506 #if defined(VGO_linux)
1507 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1509 #elif defined(VGO_darwin)
1511 #elif defined(VGO_solaris)
1516 /*-------------------- strchrnul --------------------*/
1518 /* Find the first occurrence of C in S or the final NUL byte. */
1519 #define GLIBC232_STRCHRNUL(soname, fnname) \
1520 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1521 (const char* s, int c_in); \
1522 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1523 (const char* s, int c_in) \
1525 HChar c = (HChar) c_in; \
1526 const HChar* char_ptr = s; \
1528 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1529 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1534 #if defined(VGO_linux)
1535 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1537 #elif defined(VGO_freebsd)
1538 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1540 #elif defined(VGO_darwin)
1542 #elif defined(VGO_solaris)
1547 /*---------------------- rawmemchr ----------------------*/
1549 /* Find the first occurrence of C in S. */
1550 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1551 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1552 (const void* s, int c_in); \
1553 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1554 (const void* s, int c_in) \
1556 UChar c = (UChar) c_in; \
1557 const UChar* char_ptr = s; \
1559 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1564 #if defined (VGO_linux)
1565 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1566 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1568 #elif defined(VGO_darwin)
1570 #elif defined(VGO_solaris)
1575 /*---------------------- strcpy_chk ----------------------*/
1577 /* glibc variant of strcpy that checks the dest is big enough.
1578 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1579 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1580 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1581 (char* dst, const char* src, SizeT len); \
1582 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1583 (char* dst, const char* src, SizeT len) \
1585 FOR_COPY(const HChar* src_orig = src); \
1589 while ((*dst++ = *src++) != '\0') \
1592 RECORD_COPY((Addr)src-(Addr)src_orig); \
1595 VALGRIND_PRINTF_BACKTRACE( \
1596 "*** strcpy_chk: buffer overflow detected ***: " \
1597 "program terminated\n"); \
1603 #if defined(VGO_linux)
1604 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1606 #elif defined(VGO_darwin)
1608 #elif defined(VGO_solaris)
1613 /*---------------------- stpcpy_chk ----------------------*/
1615 /* glibc variant of stpcpy that checks the dest is big enough.
1616 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1617 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1618 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1619 (char* dst, const char* src, SizeT len); \
1620 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1621 (char* dst, const char* src, SizeT len) \
1623 FOR_COPY(const HChar* src_orig = src); \
1626 while ((*dst++ = *src++) != '\0') \
1629 RECORD_COPY((Addr)src-(Addr)src_orig); \
1632 VALGRIND_PRINTF_BACKTRACE( \
1633 "*** stpcpy_chk: buffer overflow detected ***: " \
1634 "program terminated\n"); \
1640 #if defined(VGO_linux)
1641 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1643 #elif defined(VGO_darwin)
1645 #elif defined(VGO_solaris)
1650 /*---------------------- mempcpy ----------------------*/
1653 #define GLIBC25_MEMPCPY(soname, fnname) \
1654 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1655 ( void *dst, const void *src, SizeT len ); \
1656 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1657 ( void *dst, const void *src, SizeT len ) \
1660 SizeT len_saved = len; \
1665 if (is_overlap(dst, src, len, len)) \
1666 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1668 if ( dst > src ) { \
1669 register HChar *d = (char *)dst + len - 1; \
1670 register const HChar *s = (const char *)src + len - 1; \
1674 } else if ( dst < src ) { \
1675 register HChar *d = dst; \
1676 register const HChar *s = src; \
1681 return (void*)( ((char*)dst) + len_saved ); \
1684 #if defined(VGO_linux)
1685 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1686 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1687 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1688 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1689 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1691 #elif defined(VGO_freebsd)
1692 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1693 #elif defined(VGO_darwin)
1694 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1696 #elif defined(VGO_solaris)
1701 /*-------------------- memcpy_chk --------------------*/
1703 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1704 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1705 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1706 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1707 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1709 register HChar *d; \
1710 register const HChar *s; \
1716 if (is_overlap(dst, src, len, len)) \
1717 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1718 if ( dst > src ) { \
1719 d = (HChar *)dst + len - 1; \
1720 s = (const HChar *)src + len - 1; \
1724 } else if ( dst < src ) { \
1726 s = (const HChar *)src; \
1733 VALGRIND_PRINTF_BACKTRACE( \
1734 "*** memcpy_chk: buffer overflow detected ***: " \
1735 "program terminated\n"); \
1741 #if defined(VGO_linux)
1742 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1744 #elif defined(VGO_darwin)
1746 #elif defined(VGO_solaris)
1751 /*---------------------- strstr ----------------------*/
1753 #define STRSTR(soname, fnname) \
1754 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1755 (const char* haystack, const char* needle); \
1756 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1757 (const char* haystack, const char* needle) \
1759 const HChar* h = haystack; \
1760 const HChar* n = needle; \
1762 /* find the length of n, not including terminating zero */ \
1764 while (n[nlen]) nlen++; \
1766 /* if n is the empty string, match immediately. */ \
1767 if (nlen == 0) return CONST_CAST(HChar *,h); \
1769 /* assert(nlen >= 1); */ \
1773 const HChar hh = *h; \
1774 if (hh == 0) return NULL; \
1775 if (hh != n0) { h++; continue; } \
1778 for (i = 0; i < nlen; i++) { \
1782 /* assert(i >= 0 && i <= nlen); */ \
1784 return CONST_CAST(HChar *,h); \
1790 #if defined(VGO_linux)
1791 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1792 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1793 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1795 #elif defined(VGO_freebsd)
1796 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1798 #elif defined(VGO_darwin)
1800 #elif defined(VGO_solaris)
1801 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1805 /*---------------------- memmem ----------------------*/
1807 #define MEMMEM(soname, fnname) \
1808 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1809 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1810 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1811 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1813 const HChar* h = haystack; \
1814 const HChar* n = needle; \
1816 /* If the needle is the empty string, match immediately. */ \
1817 if (nlen == 0) return CONST_CAST(void *,h); \
1821 for (; hlen >= nlen; hlen--, h++) { \
1822 if (h[0] != n0) continue; \
1825 for (i = 1; i < nlen; i++) { \
1830 return CONST_CAST(HChar *,h); \
1836 #if defined(VGP_s390x_linux)
1837 MEMMEM(VG_Z_LIBC_SONAME
, memmem
)
1841 /*---------------------- strpbrk ----------------------*/
1843 #define STRPBRK(soname, fnname) \
1844 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1845 (const char* sV, const char* acceptV); \
1846 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1847 (const char* sV, const char* acceptV) \
1849 const HChar* s = sV; \
1850 const HChar* accept = acceptV; \
1852 /* find the length of 'accept', not including terminating zero */ \
1854 while (accept[nacc]) nacc++; \
1856 /* if n is the empty string, fail immediately. */ \
1857 if (nacc == 0) return NULL; \
1859 /* assert(nacc >= 1); */ \
1865 for (i = 0; i < nacc; i++) { \
1866 if (sc == accept[i]) \
1867 return CONST_CAST(HChar *,s); \
1875 #if defined(VGO_linux)
1876 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1878 #elif defined(VGO_freebsd)
1879 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1881 #elif defined(VGO_darwin)
1883 #elif defined(VGO_solaris)
1884 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1889 /*---------------------- strcspn ----------------------*/
1891 #define STRCSPN(soname, fnname) \
1892 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1893 (const char* sV, const char* rejectV); \
1894 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1895 (const char* sV, const char* rejectV) \
1897 const HChar* s = sV; \
1898 const HChar* reject = rejectV; \
1900 /* find the length of 'reject', not including terminating zero */ \
1902 while (reject[nrej]) nrej++; \
1910 for (i = 0; i < nrej; i++) { \
1911 if (sc == reject[i]) \
1914 /* assert(i >= 0 && i <= nrej); */ \
1924 #if defined(VGO_linux)
1925 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1926 STRCSPN(VG_Z_LIBC_SONAME
, __GI_strcspn
)
1928 #elif defined(VGO_freebsd)
1929 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1931 #elif defined(VGO_darwin)
1933 #elif defined(VGO_solaris)
1934 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1939 /*---------------------- strspn ----------------------*/
1941 #define STRSPN(soname, fnname) \
1942 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1943 (const char* sV, const char* acceptV); \
1944 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1945 (const char* sV, const char* acceptV) \
1947 const UChar* s = (const UChar *)sV; \
1948 const UChar* accept = (const UChar *)acceptV; \
1950 /* find the length of 'accept', not including terminating zero */ \
1952 while (accept[nacc]) nacc++; \
1953 if (nacc == 0) return 0; \
1961 for (i = 0; i < nacc; i++) { \
1962 if (sc == accept[i]) \
1965 /* assert(i >= 0 && i <= nacc); */ \
1975 #if defined(VGO_linux)
1976 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1978 #elif defined(VGO_freebsd)
1979 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1981 #elif defined(VGO_darwin)
1983 #elif defined(VGO_solaris)
1984 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
1989 /*---------------------- strcasestr ----------------------*/
1991 #define STRCASESTR(soname, fnname) \
1992 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1993 (const char* haystack, const char* needle); \
1994 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1995 (const char* haystack, const char* needle) \
1997 extern int tolower(int); \
1998 const HChar* h = haystack; \
1999 const HChar* n = needle; \
2001 /* find the length of n, not including terminating zero */ \
2003 while (n[nlen]) nlen++; \
2005 /* if n is the empty string, match immediately. */ \
2006 if (nlen == 0) return CONST_CAST(HChar *,h); \
2008 /* assert(nlen >= 1); */ \
2009 UChar n0 = tolower(n[0]); \
2012 UChar hh = tolower(*h); \
2013 if (hh == 0) return NULL; \
2014 if (hh != n0) { h++; continue; } \
2017 for (i = 0; i < nlen; i++) { \
2018 if (tolower(n[i]) != tolower(h[i])) \
2021 /* assert(i >= 0 && i <= nlen); */ \
2023 return CONST_CAST(HChar *,h); \
2029 #if defined(VGO_linux)
2030 # if !defined(VGPV_arm_linux_android) \
2031 && !defined(VGPV_x86_linux_android) \
2032 && !defined(VGPV_mips32_linux_android) \
2033 && !defined(VGPV_arm64_linux_android)
2034 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2037 #elif defined(VGO_freebsd)
2038 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2040 #elif defined(VGO_darwin)
2042 #elif defined(VGO_solaris)
2043 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2048 /*---------------------- wcslen ----------------------*/
2050 // This is a wchar_t equivalent to strlen. Unfortunately
2051 // we don't have wchar_t available here, but it looks like
2052 // a 32 bit int on Linux. I don't know if that is also
2055 #define WCSLEN(soname, fnname) \
2056 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2057 ( const Int* str ); \
2058 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2059 ( const Int* str ) \
2062 while (str[i] != 0) i++; \
2066 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2067 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
2071 /*---------------------- wcsnlen ----------------------*/
2073 #define WCSNLEN(soname, fnname) \
2074 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2075 ( const Int *s, SizeT n ); \
2076 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2077 ( const Int *s, SizeT n ) \
2081 while (i < n && *p != 0) { \
2088 #if defined(VGO_linux) || defined(VGO_freebsd)
2089 WCSNLEN(VG_Z_LIBC_SONAME
, wcsnlen
)
2090 WCSNLEN(VG_Z_LIBC_SONAME
, __GI_wcsnlen
)
2093 /*---------------------- wcscmp ----------------------*/
2095 // This is a wchar_t equivalent to strcmp. We don't
2096 // have wchar_t available here, but in the GNU C Library
2097 // wchar_t is always 32 bits wide and wcscmp uses signed
2098 // comparison, not unsigned as in strcmp function.
2100 #define WCSCMP(soname, fnname) \
2101 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2102 ( const Int* s1, const Int* s2 ); \
2103 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2104 ( const Int* s1, const Int* s2 ) \
2111 if (c1 != c2) break; \
2112 if (c1 == 0) break; \
2115 if (c1 < c2) return -1; \
2116 if (c1 > c2) return 1; \
2120 #if defined(VGO_linux) || defined(VGO_freebsd)
2121 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
2124 /*---------------------- wcsncmp ----------------------*/
2126 // This is a wchar_t equivalent to strncmp. We don't
2127 // have wchar_t available here, but in the GNU C Library
2128 // wchar_t is always 32 bits wide and wcsncmp uses signed
2129 // comparison, not unsigned as in strncmp function.
2131 #define WCSNCMP(soname, fnname) \
2132 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2133 ( const Int* s1, const Int* s2, SizeT nmax ); \
2134 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2135 ( const Int* s1, const Int* s2, SizeT nmax ) \
2139 if (n >= nmax) return 0; \
2140 if (*s1 == 0 && *s2 == 0) return 0; \
2141 if (*s1 == 0) return -1; \
2142 if (*s2 == 0) return 1; \
2144 if (*s1 < *s2) return -1; \
2145 if (*s1 > *s2) return 1; \
2150 #if defined(VGO_linux) || defined(VGO_freebsd)
2151 WCSNCMP(VG_Z_LIBC_SONAME
, wcsncmp
)
2154 /*---------------------- wcscpy ----------------------*/
2156 // This is a wchar_t equivalent to strcpy. We don't
2157 // have wchar_t available here, but in the GNU C Library
2158 // wchar_t is always 32 bits wide.
2160 #define WCSCPY(soname, fnname) \
2161 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2162 ( Int* dst, const Int* src ); \
2163 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2164 ( Int* dst, const Int* src ) \
2166 const Int* src_orig = src; \
2167 Int* dst_orig = dst; \
2169 while (*src) *dst++ = *src++; \
2172 /* This checks for overlap after copying, unavoidable without */ \
2173 /* pre-counting length... should be ok */ \
2174 /* +4 because sizeof(wchar_t) == 4 */ \
2175 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2176 RECORD_COPY(srclen); \
2177 if (is_overlap(dst_orig, \
2179 /* +4 because sizeof(wchar_t) == 4 */ \
2180 (Addr)dst-(Addr)dst_orig+4, \
2182 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2187 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2188 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
2192 /*---------------------- wcschr ----------------------*/
2194 // This is a wchar_t equivalent to strchr. We don't
2195 // have wchar_t available here, but in the GNU C Library
2196 // wchar_t is always 32 bits wide.
2198 #define WCSCHR(soname, fnname) \
2199 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2200 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2204 if (*p == c) return CONST_CAST(Int *,p); \
2205 if (*p == 0) return NULL; \
2210 #if defined(VGO_linux) || defined(VGO_freebsd)
2211 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
2213 /*---------------------- wcsrchr ----------------------*/
2215 // This is a wchar_t equivalent to strrchr. We don't
2216 // have wchar_t available here, but in the GNU C Library
2217 // wchar_t is always 32 bits wide.
2219 #define WCSRCHR(soname, fnname) \
2220 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2221 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2224 const Int* last = NULL; \
2226 if (*p == c) last = p; \
2227 if (*p == 0) return CONST_CAST(Int *,last); \
2232 #if defined(VGO_linux) || defined(VGO_freebsd)
2233 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
2236 /*---------------------- wmemchr ----------------------*/
2238 // This is a wchar_t equivalent to memchr. We don't
2239 // have wchar_t available here, but in the GNU C Library
2240 // wchar_t is always 32 bits wide.
2242 #define WMEMCHR(soname, fnname) \
2243 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2244 (const Int *s, Int c, SizeT n); \
2245 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2246 (const Int *s, Int c, SizeT n) \
2250 for (i = 0; i < n; i++) { \
2251 if (*p == c) return CONST_CAST(Int *,p); \
2257 #if defined(VGO_linux)
2258 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2259 WMEMCHR(VG_Z_LIBC_SONAME
, __GI_wmemchr
)
2262 #if defined(VGO_freebsd)
2263 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2265 /*------------------------------------------------------------*/
2266 /*--- Improve definedness checking of process environment ---*/
2267 /*------------------------------------------------------------*/
2269 #if defined(VGO_linux) || defined(VGO_freebsd)
2271 /* If these wind up getting generated via a macro, so that multiple
2272 versions of each function exist (as above), use the _EZU variants
2273 to assign equivalance class tags. */
2275 /*---------------------- putenv ----------------------*/
2277 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
2278 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
2282 const HChar
* p
= string
;
2283 VALGRIND_GET_ORIG_FN(fn
);
2284 /* Now by walking over the string we magically produce
2285 traces when hitting undefined memory. */
2288 __asm__
__volatile__("" ::: "memory");
2289 CALL_FN_W_W(result
, fn
, string
);
2294 /*---------------------- unsetenv ----------------------*/
2296 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
2297 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
2301 const HChar
* p
= name
;
2302 VALGRIND_GET_ORIG_FN(fn
);
2303 /* Now by walking over the string we magically produce
2304 traces when hitting undefined memory. */
2307 __asm__
__volatile__("" ::: "memory");
2308 CALL_FN_W_W(result
, fn
, name
);
2313 /*---------------------- setenv ----------------------*/
2316 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2317 (const char* name
, const char* value
, int overwrite
);
2318 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2319 (const char* name
, const char* value
, int overwrite
)
2324 VALGRIND_GET_ORIG_FN(fn
);
2325 /* Now by walking over the string we magically produce
2326 traces when hitting undefined memory. */
2328 for (p
= name
; *p
; p
++)
2329 __asm__
__volatile__("" ::: "memory");
2331 for (p
= value
; *p
; p
++)
2332 __asm__
__volatile__("" ::: "memory");
2333 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2334 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2338 #endif /* defined(VGO_linux) */
2340 /*--------------------------------------------------------------------*/
2342 /*--------------------------------------------------------------------*/