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
113 #if defined(VGO_solaris)
115 Detour functions in the libc and the runtime linker. If a function isn't
116 much optimized (and no overlap checking is necessary) then redir the
117 function only in the libc. This way we can keep stacktraces in the tests
123 /* Figure out if [dst .. dst+dstlen-1] overlaps with
124 [src .. src+srclen-1].
125 We assume that the address ranges do not wrap around
126 (which is safe since on Linux addresses >= 0xC0000000
127 are not accessible and the program will segfault in this
128 circumstance, presumably).
131 Bool
is_overlap ( void* dst
, const void* src
, SizeT dstlen
, SizeT srclen
)
133 Addr loS
, hiS
, loD
, hiD
;
135 if (dstlen
== 0 || srclen
== 0)
140 hiS
= loS
+ srclen
- 1;
141 hiD
= loD
+ dstlen
- 1;
143 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
147 else if (loD
< loS
) {
151 /* They start at same place. Since we know neither of them has
152 zero length, they must overlap. */
157 #if defined(VGO_linux)
158 /* Call here to exit if we can't continue. On Android we can't call
159 _exit for some reason, so we have to blunt-instrument it. */
160 __attribute__ ((__noreturn__
))
161 static inline void my_exit ( int x
)
163 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
164 || defined(VGPV_arm64_linux_android)
165 __asm__
__volatile__(".word 0xFFFFFFFF");
167 # elif defined(VGPV_x86_linux_android)
168 __asm__
__volatile__("ud2");
171 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
177 // This is a macro rather than a function because we don't want to have an
178 // extra function in the stack trace.
179 #ifndef RECORD_OVERLAP_ERROR
180 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
183 // Used for tools that record bulk copies: memcpy, strcpy, etc.
185 #define RECORD_COPY(len) do { } while (0)
188 #define FOR_COPY(x) x
191 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
192 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
196 /*---------------------- strrchr ----------------------*/
198 #define STRRCHR(soname, fnname) \
199 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
200 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
202 HChar ch = (HChar)c; \
203 const HChar* p = s; \
204 const HChar* last = NULL; \
206 if (*p == ch) last = p; \
207 if (*p == 0) return CONST_CAST(HChar *,last); \
212 // Apparently rindex() is the same thing as strrchr()
213 #if defined(VGO_linux)
214 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
215 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
216 STRRCHR(VG_Z_LIBC_SONAME
, __GI_strrchr
)
217 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2
)
218 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2_no_bsf
)
219 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse42
)
220 STRRCHR(VG_Z_LD_LINUX_SO_2
, rindex
)
221 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
222 || defined(VGPV_mips32_linux_android)
223 STRRCHR(NONE
, __dl_strrchr
); /* in /system/bin/linker */
226 #elif defined(VGO_freebsd)
227 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
228 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
229 STRRCHR(VG_Z_LD_ELF_SO_1
, strrchr
)
230 STRRCHR(VG_Z_LD_ELF32_SO_1
, strrchr
)
232 #elif defined(VGO_darwin)
233 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
234 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
235 //STRRCHR(VG_Z_DYLD, strrchr)
236 //STRRCHR(VG_Z_DYLD, rindex)
237 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
238 # if DARWIN_VERS >= DARWIN_10_9
239 STRRCHR(libsystemZucZddylib
, strrchr
)
242 #elif defined(VGO_solaris)
243 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
244 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
245 STRRCHR(VG_Z_LD_SO_1
, strrchr
)
250 /*---------------------- strchr ----------------------*/
252 #define STRCHR(soname, fnname) \
253 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
254 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
256 HChar ch = (HChar)c ; \
257 const HChar* p = s; \
259 if (*p == ch) return CONST_CAST(HChar *,p); \
260 if (*p == 0) return NULL; \
265 // Apparently index() is the same thing as strchr()
266 #if defined(VGO_linux)
267 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
268 STRCHR(VG_Z_LIBC_SONAME
, __GI_strchr
)
269 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2
)
270 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2_no_bsf
)
271 STRCHR(VG_Z_LIBC_SONAME
, index
)
272 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
273 STRCHR(VG_Z_LD_LINUX_SO_2
, strchr
)
274 STRCHR(VG_Z_LD_LINUX_SO_2
, index
)
275 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, strchr
)
276 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, index
)
279 #if defined(VGPV_mips32_linux_android)
280 STRCHR(NONE
, __dl_strchr
)
283 #elif defined(VGO_freebsd)
284 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
285 STRCHR(VG_Z_LIBC_SONAME
, index
)
286 STRCHR(VG_Z_LD_ELF_SO_1
, strchr
)
287 STRCHR(VG_Z_LD_ELF32_SO_1
, strchr
)
289 #elif defined(VGO_darwin)
290 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
291 # if DARWIN_VERS == DARWIN_10_9
292 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
294 # if DARWIN_VERS >= DARWIN_10_10
295 /* _platform_strchr$VARIANT$Generic */
296 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
297 /* _platform_strchr$VARIANT$Haswell */
298 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
300 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Base
)
302 #elif defined(VGO_solaris)
303 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
304 STRCHR(VG_Z_LIBC_SONAME
, index
)
305 STRCHR(VG_Z_LD_SO_1
, strchr
)
310 /*---------------------- strcat ----------------------*/
312 #define STRCAT(soname, fnname) \
313 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
314 ( char* dst, const char* src ); \
315 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
316 ( char* dst, const char* src ) \
318 const HChar* src_orig = src; \
319 HChar* dst_orig = dst; \
320 while (*dst) dst++; \
321 while (*src) *dst++ = *src++; \
324 /* This is a bit redundant, I think; any overlap and the strcat will */ \
325 /* go forever... or until a seg fault occurs. */ \
326 if (is_overlap(dst_orig, \
328 (Addr)dst-(Addr)dst_orig+1, \
329 (Addr)src-(Addr)src_orig+1)) \
330 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
335 #if defined(VGO_linux)
336 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
337 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
339 #elif defined(VGO_freebsd)
340 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
341 STRCAT(VG_Z_LD_ELF_SO_1
, strcat
)
342 STRCAT(VG_Z_LD_ELF32_SO_1
, strcat
)
344 #elif defined(VGO_darwin)
345 //STRCAT(VG_Z_LIBC_SONAME, strcat)
347 #elif defined(VGO_solaris)
348 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
349 STRCAT(VG_Z_LD_SO_1
, strcat
)
354 /*---------------------- strncat ----------------------*/
356 #define STRNCAT(soname, fnname) \
357 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
358 ( char* dst, const char* src, SizeT n ); \
359 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
360 ( char* dst, const char* src, SizeT n ) \
362 const HChar* src_orig = src; \
363 HChar* dst_orig = dst; \
366 while (*dst) dst++; \
367 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
368 *dst = 0; /* always add null */ \
370 /* This checks for overlap after copying, unavoidable without */ \
371 /* pre-counting lengths... should be ok */ \
372 if (is_overlap(dst_orig, \
374 (Addr)dst-(Addr)dst_orig+1, \
375 (Addr)src-(Addr)src_orig)) \
376 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
381 #if defined(VGO_linux)
382 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
384 #elif defined(VGO_freebsd)
385 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
387 #elif defined(VGO_darwin)
388 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
389 //STRNCAT(VG_Z_DYLD, strncat)
391 #elif defined(VGO_solaris)
392 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
397 /*---------------------- strlcat ----------------------*/
399 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
400 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
401 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
402 Truncation occurred if retval >= n.
404 #define STRLCAT(soname, fnname) \
405 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
406 ( char* dst, const char* src, SizeT n ); \
407 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
408 ( char* dst, const char* src, SizeT n ) \
410 const HChar* src_orig = src; \
411 HChar* dst_orig = dst; \
414 while (m < n && *dst) { m++; dst++; } \
416 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
417 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
420 /* No space to copy anything to dst. m == n */ \
422 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
423 while (*src) { m++; src++; } \
424 /* This checks for overlap after copying, unavoidable without */ \
425 /* pre-counting lengths... should be ok */ \
426 if (is_overlap(dst_orig, \
428 (Addr)dst-(Addr)dst_orig+1, \
429 (Addr)src-(Addr)src_orig+1)) \
430 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
435 #if defined(VGO_linux)
436 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
438 #elif defined(VGO_freebsd)
439 STRLCAT(VG_Z_LD_ELF_SO_1
, strlcat
)
440 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
441 STRLCAT(VG_Z_LD_ELF32_SO_1
, strlcat
)
443 #elif defined(VGO_darwin)
444 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
445 //STRLCAT(VG_Z_DYLD, strlcat)
446 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
448 #elif defined(VGO_solaris)
449 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
454 /*---------------------- strnlen ----------------------*/
456 #define STRNLEN(soname, fnname) \
457 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
458 ( const char* str, SizeT n ); \
459 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
460 ( const char* str, SizeT n ) \
463 while (i < n && str[i] != 0) i++; \
467 #if defined(VGO_linux)
468 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
469 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
471 #elif defined(VGO_freebsd)
473 STRNLEN(VG_Z_LIBC_SONAME
, srtnlen
)
475 #elif defined(VGO_darwin)
476 # if DARWIN_VERS == DARWIN_10_9
477 STRNLEN(libsystemZucZddylib
, strnlen
)
480 #elif defined(VGO_solaris)
481 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
486 /*---------------------- strlen ----------------------*/
488 // Note that this replacement often doesn't get used because gcc inlines
489 // calls to strlen() with its own built-in version. This can be very
490 // confusing if you aren't expecting it. Other small functions in
491 // this file may also be inline by gcc.
493 #define STRLEN(soname, fnname) \
494 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
495 ( const char* str ); \
496 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
497 ( const char* str ) \
500 while (str[i] != 0) i++; \
504 #if defined(VGO_linux)
505 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
506 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
507 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
508 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
509 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
510 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
511 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
512 # if defined(VGPV_arm_linux_android) \
513 || defined(VGPV_x86_linux_android) \
514 || defined(VGPV_mips32_linux_android)
515 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
518 #elif defined(VGO_freebsd)
519 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
520 STRLEN(VG_Z_LD_ELF_SO_1
, strlen
)
521 STRLEN(VG_Z_LD_ELF32_SO_1
, strlen
)
523 #elif defined(VGO_darwin)
524 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
525 # if DARWIN_VERS >= DARWIN_10_9
526 STRLEN(libsystemZucZddylib
, strlen
)
529 #elif defined(VGO_solaris)
530 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
531 STRLEN(VG_Z_LD_SO_1
, strlen
)
536 /*---------------------- strcpy ----------------------*/
538 #define STRCPY(soname, fnname) \
539 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
540 ( char* dst, const char* src ); \
541 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
542 ( char* dst, const char* src ) \
544 const HChar* src_orig = src; \
545 HChar* dst_orig = dst; \
547 while (*src) *dst++ = *src++; \
550 /* This happens after copying, unavoidable without */ \
551 /* pre-counting length... should be ok */ \
552 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
553 RECORD_COPY(srclen); \
554 if (is_overlap(dst_orig, \
556 (Addr)dst-(Addr)dst_orig+1, \
558 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
563 #if defined(VGO_linux)
564 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
565 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
567 #elif defined(VGO_freebsd)
568 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
569 STRCPY(VG_Z_LD_ELF_SO_1
, strcpy
)
570 STRCPY(VG_Z_LD_ELF32_SO_1
, strcpy
)
572 #elif defined(VGO_darwin)
573 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
574 # if DARWIN_VERS == DARWIN_10_9
575 STRCPY(libsystemZucZddylib
, strcpy
)
578 #elif defined(VGO_solaris)
579 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
580 STRCPY(VG_Z_LD_SO_1
, strcpy
)
585 /*---------------------- strncpy ----------------------*/
587 #define STRNCPY(soname, fnname) \
588 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
589 ( char* dst, const char* src, SizeT n ); \
590 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
591 ( char* dst, const char* src, SizeT n ) \
593 const HChar* src_orig = src; \
594 HChar* dst_orig = dst; \
597 while (m < n && *src) { m++; *dst++ = *src++; } \
598 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
599 /* but only m+1 bytes of src if terminator was found */ \
600 SizeT srclen = (m < n) ? m+1 : n; \
601 RECORD_COPY(srclen); \
602 if (is_overlap(dst_orig, src_orig, n, srclen)) \
603 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
604 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
609 #if defined(VGO_linux)
610 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
611 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
612 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
613 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
615 #elif defined(VGO_freebsd)
616 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
617 STRNCPY(VG_Z_LD_ELF_SO_1
, strncpy
)
618 STRNCPY(VG_Z_LD_ELF32_SO_1
, strncpy
)
620 #elif defined(VGO_darwin)
621 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
622 # if DARWIN_VERS >= DARWIN_10_9
623 STRNCPY(libsystemZucZddylib
, strncpy
)
626 #elif defined(VGO_solaris)
627 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
628 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
633 /*---------------------- strlcpy ----------------------*/
635 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
636 Returns strlen(src). Does not zero-fill the remainder of dst. */
637 #define STRLCPY(soname, fnname) \
638 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
639 ( char* dst, const char* src, SizeT n ); \
640 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
641 ( char* dst, const char* src, SizeT n ) \
643 const HChar* src_orig = src; \
644 HChar* dst_orig = dst; \
647 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
649 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
650 /* m non-nul bytes have now been copied, and m <= n-1. */ \
651 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
652 /* but only m+1 bytes of src if terminator was found */ \
653 SizeT srclen = (m < n) ? m+1 : n; \
654 RECORD_COPY(srclen); \
655 if (is_overlap(dst_orig, src_orig, n, srclen)) \
656 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
657 /* Nul-terminate dst. */ \
658 if (n > 0) *dst = 0; \
659 /* Finish counting strlen(src). */ \
660 while (*src) src++; \
661 return src - src_orig; \
664 #if defined(VGO_linux)
666 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
667 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
669 #elif defined(VGO_freebsd)
670 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
671 STRLCPY(VG_Z_LD_ELF_SO_1
, strlcpy
)
672 STRLCPY(VG_Z_LD_ELF32_SO_1
, strlcpy
)
673 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
675 #elif defined(VGO_darwin)
676 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
677 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
678 //STRLCPY(VG_Z_DYLD, strlcpy)
679 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
681 #elif defined(VGO_solaris)
682 /* special case for n == 0 which is undocumented but heavily used */
683 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
685 while (*src) src++; \
686 return src - src_orig; \
689 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
694 /*---------------------- strncmp ----------------------*/
696 #define STRNCMP(soname, fnname) \
697 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
698 ( const char* s1, const char* s2, SizeT nmax ); \
699 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
700 ( const char* s1, const char* s2, SizeT nmax ) \
704 if (n >= nmax) return 0; \
705 if (*s1 == 0 && *s2 == 0) return 0; \
706 if (*s1 == 0) return -1; \
707 if (*s2 == 0) return 1; \
709 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
710 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
716 #if defined(VGO_linux)
717 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
718 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
719 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
720 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
721 STRNCMP(VG_Z_LD_LINUX_SO_2
, strncmp
)
722 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strncmp
)
724 #elif defined(VGO_freebsd)
725 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
726 STRNCMP(VG_Z_LD_ELF_SO_1
, strncmp
)
727 STRNCMP(VG_Z_LD_ELF32_SO_1
, strncmp
)
729 #elif defined(VGO_darwin)
730 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
731 # if DARWIN_VERS >= DARWIN_10_9
732 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
735 #elif defined(VGO_solaris)
736 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
741 /*---------------------- strcasecmp ----------------------*/
743 #define STRCASECMP(soname, fnname) \
744 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
745 ( const char* s1, const char* s2 ); \
746 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
747 ( const char* s1, const char* s2 ) \
749 extern int tolower(int); \
753 c1 = tolower(*(const UChar *)s1); \
754 c2 = tolower(*(const UChar *)s2); \
755 if (c1 != c2) break; \
756 if (c1 == 0) break; \
759 if ((UChar)c1 < (UChar)c2) return -1; \
760 if ((UChar)c1 > (UChar)c2) return 1; \
764 #if defined(VGO_linux)
765 # if !defined(VGPV_arm_linux_android) \
766 && !defined(VGPV_x86_linux_android) \
767 && !defined(VGPV_mips32_linux_android) \
768 && !defined(VGPV_arm64_linux_android)
769 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
770 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
773 #elif defined(VGO_freebsd)
774 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
775 STRNCMP(VG_Z_LD_ELF_SO_1
, strcasecmp
)
776 STRNCMP(VG_Z_LD_ELF32_SO_1
, strcasecmp
)
778 #elif defined(VGO_darwin)
779 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
781 #elif defined(VGO_solaris)
782 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
787 /*---------------------- strncasecmp ----------------------*/
789 #define STRNCASECMP(soname, fnname) \
790 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
791 ( const char* s1, const char* s2, SizeT nmax ); \
792 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
793 ( const char* s1, const char* s2, SizeT nmax ) \
795 extern int tolower(int); \
798 if (n >= nmax) return 0; \
799 if (*s1 == 0 && *s2 == 0) return 0; \
800 if (*s1 == 0) return -1; \
801 if (*s2 == 0) return 1; \
803 if (tolower(*(const UChar *)s1) \
804 < tolower(*(const UChar*)s2)) return -1; \
805 if (tolower(*(const UChar *)s1) \
806 > tolower(*(const UChar *)s2)) return 1; \
812 #if defined(VGO_linux)
813 # if !defined(VGPV_arm_linux_android) \
814 && !defined(VGPV_x86_linux_android) \
815 && !defined(VGPV_mips32_linux_android) \
816 && !defined(VGPV_arm64_linux_android)
817 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
818 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
821 #elif defined(VGO_freebsd)
822 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
823 STRNCASECMP(VG_Z_LD_ELF_SO_1
, strncasecmp
)
824 STRNCASECMP(VG_Z_LD_ELF32_SO_1
, strncasecmp
)
826 #elif defined(VGO_darwin)
827 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
828 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
830 #elif defined(VGO_solaris)
831 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
836 /*---------------------- strcasecmp_l ----------------------*/
838 #define STRCASECMP_L(soname, fnname) \
839 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
840 ( const char* s1, const char* s2, void* locale ); \
841 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
842 ( const char* s1, const char* s2, void* locale ) \
844 extern int tolower_l(int, void*) __attribute__((weak)); \
848 c1 = tolower_l(*(const UChar *)s1, locale); \
849 c2 = tolower_l(*(const UChar *)s2, locale); \
850 if (c1 != c2) break; \
851 if (c1 == 0) break; \
854 if ((UChar)c1 < (UChar)c2) return -1; \
855 if ((UChar)c1 > (UChar)c2) return 1; \
859 #if defined(VGO_linux)
860 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
861 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
862 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
864 #elif defined(VGO_freebsd)
865 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
867 #elif defined(VGO_darwin)
868 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
870 #elif defined(VGO_solaris)
875 /*---------------------- strncasecmp_l ----------------------*/
877 #define STRNCASECMP_L(soname, fnname) \
878 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
879 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
880 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
881 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
883 extern int tolower_l(int, void*) __attribute__((weak)); \
886 if (n >= nmax) return 0; \
887 if (*s1 == 0 && *s2 == 0) return 0; \
888 if (*s1 == 0) return -1; \
889 if (*s2 == 0) return 1; \
891 if (tolower_l(*(const UChar *)s1, locale) \
892 < tolower_l(*(const UChar *)s2, locale)) return -1; \
893 if (tolower_l(*(const UChar *)s1, locale) \
894 > tolower_l(*(const UChar *)s2, locale)) return 1; \
900 #if defined(VGO_linux)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
902 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
903 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
905 #elif defined(VGO_freebsd)
906 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
908 #elif defined(VGO_darwin)
909 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
910 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
912 #elif defined(VGO_solaris)
917 /*---------------------- strcmp ----------------------*/
919 #define STRCMP(soname, fnname) \
920 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
921 ( const char* s1, const char* s2 ); \
922 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
923 ( const char* s1, const char* s2 ) \
928 c1 = *(const UChar *)s1; \
929 c2 = *(const UChar *)s2; \
930 if (c1 != c2) break; \
931 if (c1 == 0) break; \
934 if ((UChar)c1 < (UChar)c2) return -1; \
935 if ((UChar)c1 > (UChar)c2) return 1; \
939 #if defined(VGO_linux)
940 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
941 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
942 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
943 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
944 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
945 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
946 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
947 || defined(VGPV_mips32_linux_android)
948 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
951 #elif defined(VGO_freebsd)
952 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
953 STRCMP(VG_Z_LD_ELF_SO_1
, strcmp
)
954 STRCMP(VG_Z_LD_ELF32_SO_1
, strcmp
)
956 #elif defined(VGO_darwin)
957 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
958 # if DARWIN_VERS >= DARWIN_10_9
959 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
962 #elif defined(VGO_solaris)
963 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
964 STRCMP(VG_Z_LD_SO_1
, strcmp
)
969 /*---------------------- memchr ----------------------*/
971 #define MEMCHR(soname, fnname) \
972 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
973 (const void *s, int c, SizeT n); \
974 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
975 (const void *s, int c, SizeT n) \
978 UChar c0 = (UChar)c; \
979 const UChar* p = s; \
980 for (i = 0; i < n; i++) \
981 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
985 #if defined(VGO_linux)
986 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
987 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
989 #elif defined(VGO_freebsd)
990 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
992 #elif defined(VGO_darwin)
993 # if DARWIN_VERS == DARWIN_10_9
994 MEMCHR(VG_Z_DYLD
, memchr
)
995 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
997 # if DARWIN_VERS >= DARWIN_10_10
998 MEMCHR(VG_Z_DYLD
, memchr
)
999 /* _platform_memchr$VARIANT$Generic */
1000 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
1001 /* _platform_memchr$VARIANT$Haswell */
1002 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
1004 # if DARWIN_VERS >= DARWIN_10_12
1005 /* _platform_memchr$VARIANT$Base */
1006 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Base
)
1009 #elif defined(VGO_solaris)
1010 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
1015 /*---------------------- memrchr ----------------------*/
1017 #define MEMRCHR(soname, fnname) \
1018 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1019 (const void *s, int c, SizeT n); \
1020 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1021 (const void *s, int c, SizeT n) \
1024 UChar c0 = (UChar)c; \
1025 const UChar* p = s; \
1026 for (i = 0; i < n; i++) \
1027 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1031 #if defined(VGO_linux)
1032 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1034 #elif defined(VGO_freebsd)
1035 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1037 #elif defined(VGO_darwin)
1038 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1039 //MEMRCHR(VG_Z_DYLD, memrchr)
1041 #elif defined(VGO_solaris)
1046 /*---------------------- memcpy ----------------------*/
1048 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1049 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1050 ( void *dst, const void *src, SizeT len ); \
1051 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1052 ( void *dst, const void *src, SizeT len ) \
1055 if (do_ol_check && is_overlap(dst, src, len, len)) \
1056 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1058 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1059 const Addr WM = WS - 1; /* 7 or 3 */ \
1062 if (dst < src || !is_overlap(dst, src, len, len)) { \
1064 /* Copying backwards. */ \
1066 Addr d = (Addr)dst; \
1067 Addr s = (Addr)src; \
1069 if (((s^d) & WM) == 0) { \
1070 /* s and d have same UWord alignment. */ \
1071 /* Pull up to a UWord boundary. */ \
1072 while ((s & WM) != 0 && n >= 1) \
1073 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1074 /* Copy UWords. */ \
1075 while (n >= WS * 4) \
1076 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1077 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1078 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1079 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1081 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1085 if (((s|d) & 1) == 0) { \
1086 /* Both are 16-aligned; copy what we can thusly. */ \
1088 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1090 /* Copy leftovers, or everything if misaligned. */ \
1092 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1094 } else if (dst > src) { \
1097 Addr d = ((Addr)dst) + n; \
1098 Addr s = ((Addr)src) + n; \
1100 /* Copying forwards. */ \
1101 if (((s^d) & WM) == 0) { \
1102 /* s and d have same UWord alignment. */ \
1103 /* Back down to a UWord boundary. */ \
1104 while ((s & WM) != 0 && n >= 1) \
1105 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1106 /* Copy UWords. */ \
1107 while (n >= WS * 4) \
1108 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1109 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1110 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1111 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1113 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1117 if (((s|d) & 1) == 0) { \
1118 /* Both are 16-aligned; copy what we can thusly. */ \
1120 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1122 /* Copy leftovers, or everything if misaligned. */ \
1124 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1132 #define MEMMOVE(soname, fnname) \
1133 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1135 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1136 why we disable the overlap check on x86_64. */
1137 #if defined(VGP_amd64_linux) || defined(VGP_arm64_freebsd)
1138 #define MEMCPY(soname, fnname) \
1139 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 0)
1141 #define MEMCPY(soname, fnname) \
1142 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1145 #if defined(VGO_linux)
1146 /* For older memcpy we have to use memmove-like semantics and skip
1147 the overlap check; sigh; see #275284. */
1148 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1149 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1150 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1151 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1152 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1153 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_avx_unaligned_erms
)
1154 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1155 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1156 /* icc9 blats these around all over the place. Not only in the main
1157 executable but various .so's. They are highly tuned and read
1158 memory beyond the source boundary (although work correctly and
1159 never go across page boundaries), so give errors when run
1160 natively, at least for misaligned source arg. Just intercepting
1161 in the exe only until we understand more about the problem. See
1162 http://bugs.kde.org/show_bug.cgi?id=139776
1164 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1166 #elif defined(VGO_freebsd)
1167 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1168 MEMCPY(VG_Z_LD_ELF_SO_1
, memcpy
)
1169 MEMCPY(VG_Z_LD_ELF32_SO_1
, memcpy
)
1171 #elif defined(VGO_darwin)
1172 # if DARWIN_VERS <= DARWIN_10_6
1173 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1175 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1176 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1178 #elif defined(VGO_solaris)
1179 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1180 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZPZa
)
1181 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1186 /*---------------------- memcmp ----------------------*/
1188 #define MEMCMP(soname, fnname) \
1189 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1190 ( const void *s1V, const void *s2V, SizeT n ); \
1191 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1192 ( const void *s1V, const void *s2V, SizeT n ) \
1194 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1195 const SizeT WM = WS - 1; /* 7 or 3 */ \
1196 Addr s1A = (Addr)s1V; \
1197 Addr s2A = (Addr)s2V; \
1199 if (((s1A | s2A) & WM) == 0) { \
1200 /* Both areas are word aligned. Skip over the */ \
1201 /* equal prefix as fast as possible. */ \
1203 UWord w1 = *(UWord*)s1A; \
1204 UWord w2 = *(UWord*)s2A; \
1205 if (w1 != w2) break; \
1212 const UChar* s1 = (const UChar*) s1A; \
1213 const UChar* s2 = (const UChar*) s2A; \
1220 int res = ((int)a0) - ((int)b0); \
1228 #if defined(VGO_linux)
1229 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1230 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1231 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1232 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1233 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1234 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1236 #elif defined(VGO_freebsd)
1237 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1238 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1239 MEMCMP(VG_Z_LIBC_SONAME
, timingsafe_memcmp
)
1240 MEMCMP(VG_Z_LIBC_SONAME
, timingsafe_bcmp
)
1242 #elif defined(VGO_darwin)
1243 # if DARWIN_VERS >= DARWIN_10_9
1244 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1247 #elif defined(VGO_solaris)
1248 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1249 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1250 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1255 /*---------------------- stpcpy ----------------------*/
1257 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1258 DEST. (minor variant of strcpy) */
1259 #define STPCPY(soname, fnname) \
1260 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1261 ( char* dst, const char* src ); \
1262 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1263 ( char* dst, const char* src ) \
1265 const HChar* src_orig = src; \
1266 HChar* dst_orig = dst; \
1268 while (*src) *dst++ = *src++; \
1271 /* This checks for overlap after copying, unavoidable without */ \
1272 /* pre-counting length... should be ok */ \
1273 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1274 RECORD_COPY(srclen); \
1275 if (is_overlap(dst_orig, \
1277 (Addr)dst-(Addr)dst_orig+1, \
1279 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1284 #if defined(VGO_linux)
1285 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1286 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1287 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1288 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1289 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1290 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1291 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1
,stpcpy
)
1293 #elif defined(VGO_freebsd)
1294 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1295 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1296 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1298 #elif defined(VGO_freebsd)
1299 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1300 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1301 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1303 #elif defined(VGO_darwin)
1304 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1305 //STPCPY(VG_Z_DYLD, stpcpy)
1307 #elif defined(VGO_solaris)
1308 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1313 /*---------------------- stpncpy ----------------------*/
1315 #define STPNCPY(soname, fnname) \
1316 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1317 ( char* dst, const char* src, SizeT n ); \
1318 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1319 ( char* dst, const char* src, SizeT n ) \
1321 const HChar* src_orig = src; \
1322 HChar* dst_str = dst; \
1325 while (m < n && *src) { m++; *dst++ = *src++; } \
1326 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1327 /* but only m+1 bytes of src if terminator was found */ \
1328 SizeT srclen = (m < n) ? m+1 : n; \
1329 RECORD_COPY(srclen); \
1330 if (is_overlap(dst_str, src_orig, n, srclen)) \
1331 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1333 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1338 #if defined(VGO_linux) || defined(VGO_freebsd)
1339 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1343 /*---------------------- memset ----------------------*/
1345 #define MEMSET(soname, fnname) \
1346 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1347 (void *s, Int c, SizeT n); \
1348 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1349 (void *s, Int c, SizeT n) \
1351 if (sizeof(void*) == 8) { \
1353 ULong c8 = (c & 0xFF); \
1354 c8 = (c8 << 8) | c8; \
1355 c8 = (c8 << 16) | c8; \
1356 c8 = (c8 << 32) | c8; \
1357 while ((a & 7) != 0 && n >= 1) \
1358 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1360 { *(ULong*)a = c8; a += 8; n -= 8; \
1361 *(ULong*)a = c8; a += 8; n -= 8; \
1362 *(ULong*)a = c8; a += 8; n -= 8; \
1363 *(ULong*)a = c8; a += 8; n -= 8; } \
1365 { *(ULong*)a = c8; a += 8; n -= 8; } \
1367 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1371 UInt c4 = (c & 0xFF); \
1372 c4 = (c4 << 8) | c4; \
1373 c4 = (c4 << 16) | c4; \
1374 while ((a & 3) != 0 && n >= 1) \
1375 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1377 { *(UInt*)a = c4; a += 4; n -= 4; \
1378 *(UInt*)a = c4; a += 4; n -= 4; \
1379 *(UInt*)a = c4; a += 4; n -= 4; \
1380 *(UInt*)a = c4; a += 4; n -= 4; } \
1382 { *(UInt*)a = c4; a += 4; n -= 4; } \
1384 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1389 #if defined(VGO_linux)
1390 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1392 #elif defined(VGO_freebsd)
1393 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1394 MEMSET(VG_Z_LD_ELF_SO_1
, memset
)
1395 MEMSET(VG_Z_LD_ELF32_SO_1
, memset
)
1397 #elif defined(VGO_darwin)
1398 //MEMSET(VG_Z_LIBC_SONAME, memset)
1399 //MEMSET(VG_Z_DYLD, memset)
1400 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1402 #elif defined(VGO_solaris)
1403 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1404 MEMSET(VG_Z_LIBC_SONAME
, memsetZPZa
)
1409 /*---------------------- memmove ----------------------*/
1411 /* memmove -- use the MEMMOVE defn above. */
1413 #if defined(VGO_linux)
1414 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1415 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1416 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1417 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1419 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1421 #elif defined(VGO_freebsd)
1422 MEMMOVE(VG_Z_LD_ELF_SO_1
, memmove
)
1423 MEMMOVE(VG_Z_LD_ELF32_SO_1
, memmove
)
1424 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1426 #elif defined(VGO_darwin)
1427 # if DARWIN_VERS <= DARWIN_10_6
1428 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1430 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1431 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1432 # if DARWIN_VERS >= DARWIN_10_9
1433 /* _platform_memmove$VARIANT$Ivybridge */
1434 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1437 #elif defined(VGO_solaris)
1438 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1439 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZPZa
)
1440 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1445 /*---------------------- bcopy ----------------------*/
1447 #define BCOPY(soname, fnname) \
1448 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1449 (const void *srcV, void *dstV, SizeT n); \
1450 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1451 (const void *srcV, void *dstV, SizeT n) \
1455 HChar* dst = dstV; \
1456 const HChar* src = srcV; \
1458 for (i = 0; i < n; i++) \
1463 for (i = 0; i < n; i++) \
1464 dst[n-i-1] = src[n-i-1]; \
1468 #if defined(VGO_linux)
1469 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1471 #elif defined(VGO_freebsd)
1472 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1473 BCOPY(VG_Z_LD_ELF_SO_1
, bcopy
)
1474 BCOPY(VG_Z_LD_ELF32_SO_1
, bcopy
)
1476 #elif defined(VGO_darwin)
1477 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1478 //BCOPY(VG_Z_DYLD, bcopy)
1480 #elif defined(VGO_darwin)
1481 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1486 /*-------------------- memmove_chk --------------------*/
1488 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1489 There is no specific part of glibc that this is copied from. */
1490 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1491 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1492 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1493 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1494 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1498 HChar* dst = dstV; \
1499 const HChar* src = srcV; \
1503 for (i = 0; i < n; i++) \
1508 for (i = 0; i < n; i++) \
1509 dst[n-i-1] = src[n-i-1]; \
1513 VALGRIND_PRINTF_BACKTRACE( \
1514 "*** memmove_chk: buffer overflow detected ***: " \
1515 "program terminated\n"); \
1521 #if defined(VGO_linux)
1522 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1524 #elif defined(VGO_darwin)
1526 #elif defined(VGO_solaris)
1531 /*-------------------- strchrnul --------------------*/
1533 /* Find the first occurrence of C in S or the final NUL byte. */
1534 #define GLIBC232_STRCHRNUL(soname, fnname) \
1535 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1536 (const char* s, int c_in); \
1537 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1538 (const char* s, int c_in) \
1540 HChar c = (HChar) c_in; \
1541 const HChar* char_ptr = s; \
1543 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1544 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1549 #if defined(VGO_linux)
1550 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1552 #elif defined(VGO_freebsd)
1553 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1555 #elif defined(VGO_darwin)
1557 #elif defined(VGO_solaris)
1562 /*---------------------- rawmemchr ----------------------*/
1564 /* Find the first occurrence of C in S. */
1565 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1566 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1567 (const void* s, int c_in); \
1568 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1569 (const void* s, int c_in) \
1571 UChar c = (UChar) c_in; \
1572 const UChar* char_ptr = s; \
1574 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1579 #if defined (VGO_linux)
1580 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1581 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1583 #elif defined(VGO_darwin)
1585 #elif defined(VGO_solaris)
1590 /*---------------------- strcpy_chk ----------------------*/
1592 /* glibc variant of strcpy that checks the dest is big enough.
1593 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1594 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1595 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1596 (char* dst, const char* src, SizeT len); \
1597 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1598 (char* dst, const char* src, SizeT len) \
1600 FOR_COPY(const HChar* src_orig = src); \
1604 while ((*dst++ = *src++) != '\0') \
1607 RECORD_COPY((Addr)src-(Addr)src_orig); \
1610 VALGRIND_PRINTF_BACKTRACE( \
1611 "*** strcpy_chk: buffer overflow detected ***: " \
1612 "program terminated\n"); \
1618 #if defined(VGO_linux)
1619 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1621 #elif defined(VGO_darwin)
1623 #elif defined(VGO_solaris)
1628 /*---------------------- stpcpy_chk ----------------------*/
1630 /* glibc variant of stpcpy that checks the dest is big enough.
1631 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1632 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1633 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1634 (char* dst, const char* src, SizeT len); \
1635 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1636 (char* dst, const char* src, SizeT len) \
1638 FOR_COPY(const HChar* src_orig = src); \
1641 while ((*dst++ = *src++) != '\0') \
1644 RECORD_COPY((Addr)src-(Addr)src_orig); \
1647 VALGRIND_PRINTF_BACKTRACE( \
1648 "*** stpcpy_chk: buffer overflow detected ***: " \
1649 "program terminated\n"); \
1655 #if defined(VGO_linux)
1656 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1658 #elif defined(VGO_darwin)
1660 #elif defined(VGO_solaris)
1665 /*---------------------- mempcpy ----------------------*/
1668 #define GLIBC25_MEMPCPY(soname, fnname) \
1669 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1670 ( void *dst, const void *src, SizeT len ); \
1671 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1672 ( void *dst, const void *src, SizeT len ) \
1675 SizeT len_saved = len; \
1680 if (is_overlap(dst, src, len, len)) \
1681 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1683 if ( dst > src ) { \
1684 register HChar *d = (char *)dst + len - 1; \
1685 register const HChar *s = (const char *)src + len - 1; \
1689 } else if ( dst < src ) { \
1690 register HChar *d = dst; \
1691 register const HChar *s = src; \
1696 return (void*)( ((char*)dst) + len_saved ); \
1699 #if defined(VGO_linux)
1700 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1701 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1702 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1703 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1704 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1706 #elif defined(VGO_freebsd)
1707 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1708 #elif defined(VGO_darwin)
1709 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1711 #elif defined(VGO_solaris)
1716 /*-------------------- memcpy_chk --------------------*/
1718 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1719 why we disable the overlap check on x86_64. */
1720 #if defined(VGP_amd64_linux)
1721 #define CHECK_OVERLAP 0
1723 #define CHECK_OVERLAP 1
1726 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1727 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1728 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1729 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1730 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1732 register HChar *d; \
1733 register const HChar *s; \
1739 if (CHECK_OVERLAP && is_overlap(dst, src, len, len)) \
1740 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1741 if ( dst > src ) { \
1742 d = (HChar *)dst + len - 1; \
1743 s = (const HChar *)src + len - 1; \
1747 } else if ( dst < src ) { \
1749 s = (const HChar *)src; \
1756 VALGRIND_PRINTF_BACKTRACE( \
1757 "*** memcpy_chk: buffer overflow detected ***: " \
1758 "program terminated\n"); \
1764 #if defined(VGO_linux)
1765 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1767 #elif defined(VGO_darwin)
1769 #elif defined(VGO_solaris)
1774 /*---------------------- strstr ----------------------*/
1776 #define STRSTR(soname, fnname) \
1777 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1778 (const char* haystack, const char* needle); \
1779 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1780 (const char* haystack, const char* needle) \
1782 const HChar* h = haystack; \
1783 const HChar* n = needle; \
1785 /* find the length of n, not including terminating zero */ \
1787 while (n[nlen]) nlen++; \
1789 /* if n is the empty string, match immediately. */ \
1790 if (nlen == 0) return CONST_CAST(HChar *,h); \
1792 /* assert(nlen >= 1); */ \
1796 const HChar hh = *h; \
1797 if (hh == 0) return NULL; \
1798 if (hh != n0) { h++; continue; } \
1801 for (i = 0; i < nlen; i++) { \
1805 /* assert(i >= 0 && i <= nlen); */ \
1807 return CONST_CAST(HChar *,h); \
1813 #if defined(VGO_linux)
1814 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1815 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1816 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1818 #elif defined(VGO_freebsd)
1819 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1821 #elif defined(VGO_darwin)
1823 #elif defined(VGO_solaris)
1824 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1828 /*---------------------- memmem ----------------------*/
1830 #define MEMMEM(soname, fnname) \
1831 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1832 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1833 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1834 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1836 const HChar* h = haystack; \
1837 const HChar* n = needle; \
1839 /* If the needle is the empty string, match immediately. */ \
1840 if (nlen == 0) return CONST_CAST(void *,h); \
1844 for (; hlen >= nlen; hlen--, h++) { \
1845 if (h[0] != n0) continue; \
1848 for (i = 1; i < nlen; i++) { \
1853 return CONST_CAST(HChar *,h); \
1859 #if defined(VGP_s390x_linux)
1860 MEMMEM(VG_Z_LIBC_SONAME
, memmem
)
1864 /*---------------------- strpbrk ----------------------*/
1866 #define STRPBRK(soname, fnname) \
1867 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1868 (const char* sV, const char* acceptV); \
1869 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1870 (const char* sV, const char* acceptV) \
1872 const HChar* s = sV; \
1873 const HChar* accept = acceptV; \
1875 /* find the length of 'accept', not including terminating zero */ \
1877 while (accept[nacc]) nacc++; \
1879 /* if n is the empty string, fail immediately. */ \
1880 if (nacc == 0) return NULL; \
1882 /* assert(nacc >= 1); */ \
1888 for (i = 0; i < nacc; i++) { \
1889 if (sc == accept[i]) \
1890 return CONST_CAST(HChar *,s); \
1898 #if defined(VGO_linux)
1899 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1901 #elif defined(VGO_freebsd)
1902 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1904 #elif defined(VGO_darwin)
1906 #elif defined(VGO_solaris)
1907 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1912 /*---------------------- strcspn ----------------------*/
1914 #define STRCSPN(soname, fnname) \
1915 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1916 (const char* sV, const char* rejectV); \
1917 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1918 (const char* sV, const char* rejectV) \
1920 const HChar* s = sV; \
1921 const HChar* reject = rejectV; \
1923 /* find the length of 'reject', not including terminating zero */ \
1925 while (reject[nrej]) nrej++; \
1933 for (i = 0; i < nrej; i++) { \
1934 if (sc == reject[i]) \
1937 /* assert(i >= 0 && i <= nrej); */ \
1947 #if defined(VGO_linux)
1948 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1949 STRCSPN(VG_Z_LIBC_SONAME
, __GI_strcspn
)
1951 #elif defined(VGO_freebsd)
1952 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1954 #elif defined(VGO_darwin)
1956 #elif defined(VGO_solaris)
1957 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1962 /*---------------------- strspn ----------------------*/
1964 #define STRSPN(soname, fnname) \
1965 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1966 (const char* sV, const char* acceptV); \
1967 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1968 (const char* sV, const char* acceptV) \
1970 const UChar* s = (const UChar *)sV; \
1971 const UChar* accept = (const UChar *)acceptV; \
1973 /* find the length of 'accept', not including terminating zero */ \
1975 while (accept[nacc]) nacc++; \
1976 if (nacc == 0) return 0; \
1984 for (i = 0; i < nacc; i++) { \
1985 if (sc == accept[i]) \
1988 /* assert(i >= 0 && i <= nacc); */ \
1998 #if defined(VGO_linux)
1999 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2001 #elif defined(VGO_freebsd)
2002 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2004 #elif defined(VGO_darwin)
2006 #elif defined(VGO_solaris)
2007 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2012 /*---------------------- strcasestr ----------------------*/
2014 #define STRCASESTR(soname, fnname) \
2015 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2016 (const char* haystack, const char* needle); \
2017 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2018 (const char* haystack, const char* needle) \
2020 extern int tolower(int); \
2021 const HChar* h = haystack; \
2022 const HChar* n = needle; \
2024 /* find the length of n, not including terminating zero */ \
2026 while (n[nlen]) nlen++; \
2028 /* if n is the empty string, match immediately. */ \
2029 if (nlen == 0) return CONST_CAST(HChar *,h); \
2031 /* assert(nlen >= 1); */ \
2032 UChar n0 = tolower(n[0]); \
2035 UChar hh = tolower(*h); \
2036 if (hh == 0) return NULL; \
2037 if (hh != n0) { h++; continue; } \
2040 for (i = 0; i < nlen; i++) { \
2041 if (tolower(n[i]) != tolower(h[i])) \
2044 /* assert(i >= 0 && i <= nlen); */ \
2046 return CONST_CAST(HChar *,h); \
2052 #if defined(VGO_linux)
2053 # if !defined(VGPV_arm_linux_android) \
2054 && !defined(VGPV_x86_linux_android) \
2055 && !defined(VGPV_mips32_linux_android) \
2056 && !defined(VGPV_arm64_linux_android)
2057 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2060 #elif defined(VGO_freebsd)
2061 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2063 #elif defined(VGO_darwin)
2065 #elif defined(VGO_solaris)
2066 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2071 /*---------------------- wcslen ----------------------*/
2073 // This is a wchar_t equivalent to strlen. Unfortunately
2074 // we don't have wchar_t available here, but it looks like
2075 // a 32 bit int on Linux. I don't know if that is also
2078 #define WCSLEN(soname, fnname) \
2079 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2080 ( const Int* str ); \
2081 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2082 ( const Int* str ) \
2085 while (str[i] != 0) i++; \
2089 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2090 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
2094 /*---------------------- wcsnlen ----------------------*/
2096 #define WCSNLEN(soname, fnname) \
2097 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2098 ( const Int *s, SizeT n ); \
2099 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2100 ( const Int *s, SizeT n ) \
2104 while (i < n && *p != 0) { \
2111 #if defined(VGO_linux) || defined(VGO_freebsd)
2112 WCSNLEN(VG_Z_LIBC_SONAME
, wcsnlen
)
2113 WCSNLEN(VG_Z_LIBC_SONAME
, __GI_wcsnlen
)
2116 /*---------------------- wcscmp ----------------------*/
2118 // This is a wchar_t equivalent to strcmp. We don't
2119 // have wchar_t available here, but in the GNU C Library
2120 // wchar_t is always 32 bits wide and wcscmp uses signed
2121 // comparison, not unsigned as in strcmp function.
2123 #define WCSCMP(soname, fnname) \
2124 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2125 ( const Int* s1, const Int* s2 ); \
2126 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2127 ( const Int* s1, const Int* s2 ) \
2134 if (c1 != c2) break; \
2135 if (c1 == 0) break; \
2138 if (c1 < c2) return -1; \
2139 if (c1 > c2) return 1; \
2143 #if defined(VGO_linux) || defined(VGO_freebsd)
2144 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
2147 /*---------------------- wcsncmp ----------------------*/
2149 // This is a wchar_t equivalent to strncmp. We don't
2150 // have wchar_t available here, but in the GNU C Library
2151 // wchar_t is always 32 bits wide and wcsncmp uses signed
2152 // comparison, not unsigned as in strncmp function.
2154 #define WCSNCMP(soname, fnname) \
2155 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2156 ( const Int* s1, const Int* s2, SizeT nmax ); \
2157 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2158 ( const Int* s1, const Int* s2, SizeT nmax ) \
2162 if (n >= nmax) return 0; \
2163 if (*s1 == 0 && *s2 == 0) return 0; \
2164 if (*s1 == 0) return -1; \
2165 if (*s2 == 0) return 1; \
2167 if (*s1 < *s2) return -1; \
2168 if (*s1 > *s2) return 1; \
2173 #if defined(VGO_linux) || defined(VGO_freebsd)
2174 WCSNCMP(VG_Z_LIBC_SONAME
, wcsncmp
)
2177 /*---------------------- wcscpy ----------------------*/
2179 // This is a wchar_t equivalent to strcpy. We don't
2180 // have wchar_t available here, but in the GNU C Library
2181 // wchar_t is always 32 bits wide.
2183 #define WCSCPY(soname, fnname) \
2184 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2185 ( Int* dst, const Int* src ); \
2186 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2187 ( Int* dst, const Int* src ) \
2189 const Int* src_orig = src; \
2190 Int* dst_orig = dst; \
2192 while (*src) *dst++ = *src++; \
2195 /* This checks for overlap after copying, unavoidable without */ \
2196 /* pre-counting length... should be ok */ \
2197 /* +4 because sizeof(wchar_t) == 4 */ \
2198 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2199 RECORD_COPY(srclen); \
2200 if (is_overlap(dst_orig, \
2202 /* +4 because sizeof(wchar_t) == 4 */ \
2203 (Addr)dst-(Addr)dst_orig+4, \
2205 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2210 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2211 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
2215 /*---------------------- wcschr ----------------------*/
2217 // This is a wchar_t equivalent to strchr. We don't
2218 // have wchar_t available here, but in the GNU C Library
2219 // wchar_t is always 32 bits wide.
2221 #define WCSCHR(soname, fnname) \
2222 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2223 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2227 if (*p == c) return CONST_CAST(Int *,p); \
2228 if (*p == 0) return NULL; \
2233 #if defined(VGO_linux) || defined(VGO_freebsd)
2234 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
2236 /*---------------------- wcsrchr ----------------------*/
2238 // This is a wchar_t equivalent to strrchr. 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 WCSRCHR(soname, fnname) \
2243 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2244 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2247 const Int* last = NULL; \
2249 if (*p == c) last = p; \
2250 if (*p == 0) return CONST_CAST(Int *,last); \
2255 #if defined(VGO_linux) || defined(VGO_freebsd)
2256 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
2259 /*---------------------- wmemchr ----------------------*/
2261 // This is a wchar_t equivalent to memchr. We don't
2262 // have wchar_t available here, but in the GNU C Library
2263 // wchar_t is always 32 bits wide.
2265 #define WMEMCHR(soname, fnname) \
2266 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2267 (const Int *s, Int c, SizeT n); \
2268 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2269 (const Int *s, Int c, SizeT n) \
2273 for (i = 0; i < n; i++) { \
2274 if (*p == c) return CONST_CAST(Int *,p); \
2280 #if defined(VGO_linux)
2281 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2282 WMEMCHR(VG_Z_LIBC_SONAME
, __GI_wmemchr
)
2285 #if defined(VGO_freebsd)
2286 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2289 /*---------------------- wmemcmp ----------------------*/
2291 #define WMEMCMP(soname, fnname) \
2292 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2293 ( const Int *b1, const Int *b2, SizeT n ); \
2294 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2295 ( const Int *b1, const Int *b2, SizeT n ) \
2297 for (SizeT i = 0U; i < n; ++i) { \
2298 if (b1[i] != b2[i]) \
2299 return b1[i] > b2[i] ? 1 : -1; \
2304 #if defined(VGO_linux) || defined(VGO_freebsd)
2305 WMEMCMP(VG_Z_LIBC_SONAME
, wmemcmp
)
2308 /*---------------------- wcsncpy ----------------------*/
2310 // This is a wchar_t equivalent to strncpy. We don't
2311 // have wchar_t available here, but in the GNU C Library
2312 // wchar_t is always 32 bits wide.
2314 #define WCSNCPY(soname, fnname) \
2315 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2316 ( Int* dst, const Int* src, SizeT n ); \
2317 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2318 ( Int* dst, const Int* src, SizeT n ) \
2320 const Int* src_orig = src; \
2321 Int* dst_orig = dst; \
2324 while (m < n && *src) { \
2329 /* This checks for overlap after copying, unavoidable without */ \
2330 /* pre-counting length... should be ok */ \
2331 /* *4 because sizeof(wchar_t) == 4 */ \
2332 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2333 RECORD_COPY(srclen); \
2334 if (is_overlap(dst_orig, \
2338 RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
2347 #if defined(VGO_linux) || defined(VGO_freebsd)
2348 WCSNCPY(VG_Z_LIBC_SONAME
, wcsncpy
)
2351 /*---------------------- memccpy ----------------------*/
2353 /* memccpy, mostly based on GNU libc source */
2354 #define MEMCCPY(soname, fnname) \
2355 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2356 ( void *dst, const void *src, Int c, SizeT len ); \
2357 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2358 ( void *dst, const void *src, Int c, SizeT len ) \
2360 const char *s = src; \
2366 if ((*d++ = *s++) == x) { \
2367 SizeT srclen = len - i; \
2368 RECORD_COPY(srclen); \
2369 if (is_overlap(dst, src, len, srclen)) \
2370 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2376 if (is_overlap(dst, src, len, len)) \
2377 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2382 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_darwin) || defined(VGO_solaris)
2383 MEMCCPY(VG_Z_LIBC_SONAME
, memccpy
)
2386 /*---------------------- wcpncpy ----------------------*/
2388 // This is a wchar_t equivalent to strncpy. We don't
2389 // have wchar_t available here, but in the GNU C Library
2390 // wchar_t is always 32 bits wide.
2392 #define WCPNCPY(soname, fnname) \
2393 Int* VG_REPLACE_FUNCTION_EZU(20500,soname,fnname) \
2394 ( Int* dst, const Int* src, SizeT n ); \
2395 Int* VG_REPLACE_FUNCTION_EZU(20500,soname,fnname) \
2396 ( Int* dst, const Int* src, SizeT n ) \
2398 const Int* src_orig = src; \
2399 Int* dst_orig = dst; \
2402 while (m < n && *src) { \
2407 /* This checks for overlap after copying, unavoidable without */ \
2408 /* pre-counting length... should be ok */ \
2409 /* *4 because sizeof(wchar_t) == 4 */ \
2410 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2411 RECORD_COPY(srclen); \
2412 if (is_overlap(dst_orig, \
2416 RECORD_OVERLAP_ERROR("wcpncpy", dst_orig, src_orig, 0); \
2422 return dst_orig + (src - src_orig); \
2425 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2426 WCPNCPY(VG_Z_LIBC_SONAME
, wcpncpy
)
2430 /*------------------------------------------------------------*/
2431 /*--- Improve definedness checking of process environment ---*/
2432 /*------------------------------------------------------------*/
2434 #if defined(VGO_linux) || defined(VGO_freebsd)
2436 /* If these wind up getting generated via a macro, so that multiple
2437 versions of each function exist (as above), use the _EZU variants
2438 to assign equivalance class tags. */
2440 /*---------------------- putenv ----------------------*/
2442 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
2443 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
2447 const HChar
* p
= string
;
2448 VALGRIND_GET_ORIG_FN(fn
);
2449 /* Now by walking over the string we magically produce
2450 traces when hitting undefined memory. */
2453 __asm__
__volatile__("" ::: "memory");
2454 CALL_FN_W_W(result
, fn
, string
);
2459 /*---------------------- unsetenv ----------------------*/
2461 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
2462 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
2466 const HChar
* p
= name
;
2467 VALGRIND_GET_ORIG_FN(fn
);
2468 /* Now by walking over the string we magically produce
2469 traces when hitting undefined memory. */
2472 __asm__
__volatile__("" ::: "memory");
2473 CALL_FN_W_W(result
, fn
, name
);
2478 /*---------------------- setenv ----------------------*/
2481 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2482 (const char* name
, const char* value
, int overwrite
);
2483 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2484 (const char* name
, const char* value
, int overwrite
)
2489 VALGRIND_GET_ORIG_FN(fn
);
2490 /* Now by walking over the string we magically produce
2491 traces when hitting undefined memory. */
2493 for (p
= name
; *p
; p
++)
2494 __asm__
__volatile__("" ::: "memory");
2496 for (p
= value
; *p
; p
++)
2497 __asm__
__volatile__("" ::: "memory");
2498 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2499 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2503 #endif /* defined(VGO_linux) */
2505 /*--------------------------------------------------------------------*/
2507 /*--------------------------------------------------------------------*/