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
112 #if defined(VGO_solaris)
114 Detour functions in the libc and the runtime linker. If a function isn't
115 much optimized (and no overlap checking is necessary) then redir the
116 function only in the libc. This way we can keep stacktraces in the tests
122 /* Figure out if [dst .. dst+dstlen-1] overlaps with
123 [src .. src+srclen-1].
124 We assume that the address ranges do not wrap around
125 (which is safe since on Linux addresses >= 0xC0000000
126 are not accessible and the program will segfault in this
127 circumstance, presumably).
130 Bool
is_overlap ( void* dst
, const void* src
, SizeT dstlen
, SizeT srclen
)
132 Addr loS
, hiS
, loD
, hiD
;
134 if (dstlen
== 0 || srclen
== 0)
139 hiS
= loS
+ srclen
- 1;
140 hiD
= loD
+ dstlen
- 1;
142 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
146 else if (loD
< loS
) {
150 /* They start at same place. Since we know neither of them has
151 zero length, they must overlap. */
156 #if defined(VGO_linux)
157 /* Call here to exit if we can't continue. On Android we can't call
158 _exit for some reason, so we have to blunt-instrument it. */
159 __attribute__ ((__noreturn__
))
160 static inline void my_exit ( int x
)
162 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
163 || defined(VGPV_arm64_linux_android)
164 __asm__
__volatile__(".word 0xFFFFFFFF");
166 # elif defined(VGPV_x86_linux_android)
167 __asm__
__volatile__("ud2");
170 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
176 // This is a macro rather than a function because we don't want to have an
177 // extra function in the stack trace.
178 #ifndef RECORD_OVERLAP_ERROR
179 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
182 // Used for tools that record bulk copies: memcpy, strcpy, etc.
184 #define RECORD_COPY(len) do { } while (0)
187 #define FOR_COPY(x) x
190 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
191 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
195 /*---------------------- strrchr ----------------------*/
197 #define STRRCHR(soname, fnname) \
198 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
199 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
201 HChar ch = (HChar)c; \
202 const HChar* p = s; \
203 const HChar* last = NULL; \
205 if (*p == ch) last = p; \
206 if (*p == 0) return CONST_CAST(HChar *,last); \
211 // Apparently rindex() is the same thing as strrchr()
212 #if defined(VGO_linux)
213 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
214 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
215 STRRCHR(VG_Z_LIBC_SONAME
, __GI_strrchr
)
216 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2
)
217 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse2_no_bsf
)
218 STRRCHR(VG_Z_LIBC_SONAME
, __strrchr_sse42
)
219 STRRCHR(VG_Z_LD_LINUX_SO_2
, rindex
)
220 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
221 || defined(VGPV_mips32_linux_android)
222 STRRCHR(NONE
, __dl_strrchr
); /* in /system/bin/linker */
225 #elif defined(VGO_freebsd)
226 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
227 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
228 STRRCHR(VG_Z_LD_ELF_SO_1
, strrchr
)
229 STRRCHR(VG_Z_LD_ELF32_SO_1
, strrchr
)
231 #elif defined(VGO_darwin)
232 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
233 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
234 //STRRCHR(VG_Z_DYLD, strrchr)
235 //STRRCHR(VG_Z_DYLD, rindex)
236 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
237 # if DARWIN_VERS >= DARWIN_10_9
238 STRRCHR(libsystemZucZddylib
, strrchr
)
241 #elif defined(VGO_solaris)
242 STRRCHR(VG_Z_LIBC_SONAME
, strrchr
)
243 STRRCHR(VG_Z_LIBC_SONAME
, rindex
)
244 STRRCHR(VG_Z_LD_SO_1
, strrchr
)
249 /*---------------------- strchr ----------------------*/
251 #define STRCHR(soname, fnname) \
252 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
253 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
255 HChar ch = (HChar)c ; \
256 const HChar* p = s; \
258 if (*p == ch) return CONST_CAST(HChar *,p); \
259 if (*p == 0) return NULL; \
264 // Apparently index() is the same thing as strchr()
265 #if defined(VGO_linux)
266 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
267 STRCHR(VG_Z_LIBC_SONAME
, __GI_strchr
)
268 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2
)
269 STRCHR(VG_Z_LIBC_SONAME
, __strchr_sse2_no_bsf
)
270 STRCHR(VG_Z_LIBC_SONAME
, index
)
271 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
272 STRCHR(VG_Z_LD_LINUX_SO_2
, strchr
)
273 STRCHR(VG_Z_LD_LINUX_SO_2
, index
)
274 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, strchr
)
275 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2
, index
)
278 #if defined(VGPV_mips32_linux_android)
279 STRCHR(NONE
, __dl_strchr
)
282 #elif defined(VGO_freebsd)
283 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
284 STRCHR(VG_Z_LIBC_SONAME
, index
)
285 STRCHR(VG_Z_LD_ELF_SO_1
, strchr
)
286 STRCHR(VG_Z_LD_ELF32_SO_1
, strchr
)
288 #elif defined(VGO_darwin)
289 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
290 # if DARWIN_VERS == DARWIN_10_9
291 STRCHR(libsystemZuplatformZddylib
, _platform_strchr
)
293 # if DARWIN_VERS >= DARWIN_10_10
294 /* _platform_strchr$VARIANT$Generic */
295 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Generic
)
296 /* _platform_strchr$VARIANT$Haswell */
297 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Haswell
)
299 STRCHR(libsystemZuplatformZddylib
, _platform_strchr$VARIANT$Base
)
301 #elif defined(VGO_solaris)
302 STRCHR(VG_Z_LIBC_SONAME
, strchr
)
303 STRCHR(VG_Z_LIBC_SONAME
, index
)
304 STRCHR(VG_Z_LD_SO_1
, strchr
)
309 /*---------------------- strcat ----------------------*/
311 #define STRCAT(soname, fnname) \
312 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
313 ( char* dst, const char* src ); \
314 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
315 ( char* dst, const char* src ) \
317 const HChar* src_orig = src; \
318 HChar* dst_orig = dst; \
319 while (*dst) dst++; \
320 while (*src) *dst++ = *src++; \
323 /* This is a bit redundant, I think; any overlap and the strcat will */ \
324 /* go forever... or until a seg fault occurs. */ \
325 if (is_overlap(dst_orig, \
327 (Addr)dst-(Addr)dst_orig+1, \
328 (Addr)src-(Addr)src_orig+1)) \
329 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
334 #if defined(VGO_linux)
335 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
336 STRCAT(VG_Z_LIBC_SONAME
, __GI_strcat
)
338 #elif defined(VGO_freebsd)
339 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
340 STRCAT(VG_Z_LD_ELF_SO_1
, strcat
)
341 STRCAT(VG_Z_LD_ELF32_SO_1
, strcat
)
343 #elif defined(VGO_darwin)
344 //STRCAT(VG_Z_LIBC_SONAME, strcat)
346 #elif defined(VGO_solaris)
347 STRCAT(VG_Z_LIBC_SONAME
, strcat
)
348 STRCAT(VG_Z_LD_SO_1
, strcat
)
353 /*---------------------- strncat ----------------------*/
355 #define STRNCAT(soname, fnname) \
356 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
357 ( char* dst, const char* src, SizeT n ); \
358 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
359 ( char* dst, const char* src, SizeT n ) \
361 const HChar* src_orig = src; \
362 HChar* dst_orig = dst; \
365 while (*dst) dst++; \
366 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
367 *dst = 0; /* always add null */ \
369 /* This checks for overlap after copying, unavoidable without */ \
370 /* pre-counting lengths... should be ok */ \
371 if (is_overlap(dst_orig, \
373 (Addr)dst-(Addr)dst_orig+1, \
374 (Addr)src-(Addr)src_orig)) \
375 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
380 #if defined(VGO_linux)
381 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
383 #elif defined(VGO_freebsd)
384 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
386 #elif defined(VGO_darwin)
387 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
388 //STRNCAT(VG_Z_DYLD, strncat)
390 #elif defined(VGO_solaris)
391 STRNCAT(VG_Z_LIBC_SONAME
, strncat
)
396 /*---------------------- strlcat ----------------------*/
398 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
399 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
400 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
401 Truncation occurred if retval >= n.
403 #define STRLCAT(soname, fnname) \
404 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
405 ( char* dst, const char* src, SizeT n ); \
406 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
407 ( char* dst, const char* src, SizeT n ) \
409 const HChar* src_orig = src; \
410 HChar* dst_orig = dst; \
413 while (m < n && *dst) { m++; dst++; } \
415 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
416 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
419 /* No space to copy anything to dst. m == n */ \
421 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
422 while (*src) { m++; src++; } \
423 /* This checks for overlap after copying, unavoidable without */ \
424 /* pre-counting lengths... should be ok */ \
425 if (is_overlap(dst_orig, \
427 (Addr)dst-(Addr)dst_orig+1, \
428 (Addr)src-(Addr)src_orig+1)) \
429 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
434 #if defined(VGO_linux)
435 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
437 #elif defined(VGO_freebsd)
438 STRLCAT(VG_Z_LD_ELF_SO_1
, strlcat
)
439 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
440 STRLCAT(VG_Z_LD_ELF32_SO_1
, strlcat
)
442 #elif defined(VGO_darwin)
443 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
444 //STRLCAT(VG_Z_DYLD, strlcat)
445 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
447 #elif defined(VGO_solaris)
448 STRLCAT(VG_Z_LIBC_SONAME
, strlcat
)
453 /*---------------------- strnlen ----------------------*/
455 #define STRNLEN(soname, fnname) \
456 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
457 ( const char* str, SizeT n ); \
458 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
459 ( const char* str, SizeT n ) \
462 while (i < n && str[i] != 0) i++; \
466 #if defined(VGO_linux)
467 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
468 STRNLEN(VG_Z_LIBC_SONAME
, __GI_strnlen
)
470 #elif defined(VGO_freebsd)
472 STRNLEN(VG_Z_LIBC_SONAME
, srtnlen
)
474 #elif defined(VGO_darwin)
475 # if DARWIN_VERS == DARWIN_10_9
476 STRNLEN(libsystemZucZddylib
, strnlen
)
479 #elif defined(VGO_solaris)
480 STRNLEN(VG_Z_LIBC_SONAME
, strnlen
)
485 /*---------------------- strlen ----------------------*/
487 // Note that this replacement often doesn't get used because gcc inlines
488 // calls to strlen() with its own built-in version. This can be very
489 // confusing if you aren't expecting it. Other small functions in
490 // this file may also be inline by gcc.
492 #define STRLEN(soname, fnname) \
493 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
494 ( const char* str ); \
495 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
496 ( const char* str ) \
499 while (str[i] != 0) i++; \
503 #if defined(VGO_linux)
504 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
505 STRLEN(VG_Z_LIBC_SONAME
, __GI_strlen
)
506 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2
)
507 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse2_no_bsf
)
508 STRLEN(VG_Z_LIBC_SONAME
, __strlen_sse42
)
509 STRLEN(VG_Z_LD_LINUX_SO_2
, strlen
)
510 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2
, strlen
)
511 # if defined(VGPV_arm_linux_android) \
512 || defined(VGPV_x86_linux_android) \
513 || defined(VGPV_mips32_linux_android)
514 STRLEN(NONE
, __dl_strlen
); /* in /system/bin/linker */
517 #elif defined(VGO_freebsd)
518 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
519 STRLEN(VG_Z_LD_ELF_SO_1
, strlen
)
520 STRLEN(VG_Z_LD_ELF32_SO_1
, strlen
)
522 #elif defined(VGO_darwin)
523 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
524 # if DARWIN_VERS >= DARWIN_10_9
525 STRLEN(libsystemZucZddylib
, strlen
)
528 #elif defined(VGO_solaris)
529 STRLEN(VG_Z_LIBC_SONAME
, strlen
)
530 STRLEN(VG_Z_LD_SO_1
, strlen
)
535 /*---------------------- strcpy ----------------------*/
537 #define STRCPY(soname, fnname) \
538 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
539 ( char* dst, const char* src ); \
540 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
541 ( char* dst, const char* src ) \
543 const HChar* src_orig = src; \
544 HChar* dst_orig = dst; \
546 while (*src) *dst++ = *src++; \
549 /* This happens after copying, unavoidable without */ \
550 /* pre-counting length... should be ok */ \
551 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
552 RECORD_COPY(srclen); \
553 if (is_overlap(dst_orig, \
555 (Addr)dst-(Addr)dst_orig+1, \
557 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
562 #if defined(VGO_linux)
563 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
564 STRCPY(VG_Z_LIBC_SONAME
, __GI_strcpy
)
566 #elif defined(VGO_freebsd)
567 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
568 STRCPY(VG_Z_LD_ELF_SO_1
, strcpy
)
569 STRCPY(VG_Z_LD_ELF32_SO_1
, strcpy
)
571 #elif defined(VGO_darwin)
572 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
573 # if DARWIN_VERS == DARWIN_10_9
574 STRCPY(libsystemZucZddylib
, strcpy
)
577 #elif defined(VGO_solaris)
578 STRCPY(VG_Z_LIBC_SONAME
, strcpy
)
579 STRCPY(VG_Z_LD_SO_1
, strcpy
)
584 /*---------------------- strncpy ----------------------*/
586 #define STRNCPY(soname, fnname) \
587 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
588 ( char* dst, const char* src, SizeT n ); \
589 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
590 ( char* dst, const char* src, SizeT n ) \
592 const HChar* src_orig = src; \
593 HChar* dst_orig = dst; \
596 while (m < n && *src) { m++; *dst++ = *src++; } \
597 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
598 /* but only m+1 bytes of src if terminator was found */ \
599 SizeT srclen = (m < n) ? m+1 : n; \
600 RECORD_COPY(srclen); \
601 if (is_overlap(dst_orig, src_orig, n, srclen)) \
602 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
603 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
608 #if defined(VGO_linux)
609 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
610 STRNCPY(VG_Z_LIBC_SONAME
, __GI_strncpy
)
611 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2
)
612 STRNCPY(VG_Z_LIBC_SONAME
, __strncpy_sse2_unaligned
)
614 #elif defined(VGO_freebsd)
615 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
616 STRNCPY(VG_Z_LD_ELF_SO_1
, strncpy
)
617 STRNCPY(VG_Z_LD_ELF32_SO_1
, strncpy
)
619 #elif defined(VGO_darwin)
620 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
621 # if DARWIN_VERS >= DARWIN_10_9
622 STRNCPY(libsystemZucZddylib
, strncpy
)
625 #elif defined(VGO_solaris)
626 STRNCPY(VG_Z_LIBC_SONAME
, strncpy
)
627 STRNCPY(VG_Z_LD_SO_1
, strncpy
)
632 /*---------------------- strlcpy ----------------------*/
634 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
635 Returns strlen(src). Does not zero-fill the remainder of dst. */
636 #define STRLCPY(soname, fnname) \
637 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
638 ( char* dst, const char* src, SizeT n ); \
639 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
640 ( char* dst, const char* src, SizeT n ) \
642 const HChar* src_orig = src; \
643 HChar* dst_orig = dst; \
646 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
648 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
649 /* m non-nul bytes have now been copied, and m <= n-1. */ \
650 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
651 /* but only m+1 bytes of src if terminator was found */ \
652 SizeT srclen = (m < n) ? m+1 : n; \
653 RECORD_COPY(srclen); \
654 if (is_overlap(dst_orig, src_orig, n, srclen)) \
655 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
656 /* Nul-terminate dst. */ \
657 if (n > 0) *dst = 0; \
658 /* Finish counting strlen(src). */ \
659 while (*src) src++; \
660 return src - src_orig; \
663 #if defined(VGO_linux)
665 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
666 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
);
668 #elif defined(VGO_freebsd)
669 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
670 STRLCPY(VG_Z_LD_ELF_SO_1
, strlcpy
)
671 STRLCPY(VG_Z_LD_ELF32_SO_1
, strlcpy
)
672 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
674 #elif defined(VGO_darwin)
675 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
676 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
677 //STRLCPY(VG_Z_DYLD, strlcpy)
678 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
680 #elif defined(VGO_solaris)
681 /* special case for n == 0 which is undocumented but heavily used */
682 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
684 while (*src) src++; \
685 return src - src_orig; \
688 STRLCPY(VG_Z_LIBC_SONAME
, strlcpy
)
693 /*---------------------- strncmp ----------------------*/
695 #define STRNCMP(soname, fnname) \
696 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
697 ( const char* s1, const char* s2, SizeT nmax ); \
698 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
699 ( const char* s1, const char* s2, SizeT nmax ) \
703 if (n >= nmax) return 0; \
704 if (*s1 == 0 && *s2 == 0) return 0; \
705 if (*s1 == 0) return -1; \
706 if (*s2 == 0) return 1; \
708 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
709 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
715 #if defined(VGO_linux)
716 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
717 STRNCMP(VG_Z_LIBC_SONAME
, __GI_strncmp
)
718 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse2
)
719 STRNCMP(VG_Z_LIBC_SONAME
, __strncmp_sse42
)
720 STRNCMP(VG_Z_LD_LINUX_SO_2
, strncmp
)
721 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strncmp
)
723 #elif defined(VGO_freebsd)
724 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
725 STRNCMP(VG_Z_LD_ELF_SO_1
, strncmp
)
726 STRNCMP(VG_Z_LD_ELF32_SO_1
, strncmp
)
728 #elif defined(VGO_darwin)
729 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
730 # if DARWIN_VERS >= DARWIN_10_9
731 STRNCMP(libsystemZuplatformZddylib
, _platform_strncmp
)
734 #elif defined(VGO_solaris)
735 STRNCMP(VG_Z_LIBC_SONAME
, strncmp
)
740 /*---------------------- strcasecmp ----------------------*/
742 #define STRCASECMP(soname, fnname) \
743 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
744 ( const char* s1, const char* s2 ); \
745 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
746 ( const char* s1, const char* s2 ) \
748 extern int tolower(int); \
752 c1 = tolower(*(const UChar *)s1); \
753 c2 = tolower(*(const UChar *)s2); \
754 if (c1 != c2) break; \
755 if (c1 == 0) break; \
758 if ((UChar)c1 < (UChar)c2) return -1; \
759 if ((UChar)c1 > (UChar)c2) return 1; \
763 #if defined(VGO_linux)
764 # if !defined(VGPV_arm_linux_android) \
765 && !defined(VGPV_x86_linux_android) \
766 && !defined(VGPV_mips32_linux_android) \
767 && !defined(VGPV_arm64_linux_android)
768 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
769 STRCASECMP(VG_Z_LIBC_SONAME
, __GI_strcasecmp
)
772 #elif defined(VGO_freebsd)
773 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
774 STRNCMP(VG_Z_LD_ELF_SO_1
, strcasecmp
)
775 STRNCMP(VG_Z_LD_ELF32_SO_1
, strcasecmp
)
777 #elif defined(VGO_darwin)
778 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
780 #elif defined(VGO_solaris)
781 STRCASECMP(VG_Z_LIBC_SONAME
, strcasecmp
)
786 /*---------------------- strncasecmp ----------------------*/
788 #define STRNCASECMP(soname, fnname) \
789 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
790 ( const char* s1, const char* s2, SizeT nmax ); \
791 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
792 ( const char* s1, const char* s2, SizeT nmax ) \
794 extern int tolower(int); \
797 if (n >= nmax) return 0; \
798 if (*s1 == 0 && *s2 == 0) return 0; \
799 if (*s1 == 0) return -1; \
800 if (*s2 == 0) return 1; \
802 if (tolower(*(const UChar *)s1) \
803 < tolower(*(const UChar*)s2)) return -1; \
804 if (tolower(*(const UChar *)s1) \
805 > tolower(*(const UChar *)s2)) return 1; \
811 #if defined(VGO_linux)
812 # if !defined(VGPV_arm_linux_android) \
813 && !defined(VGPV_x86_linux_android) \
814 && !defined(VGPV_mips32_linux_android) \
815 && !defined(VGPV_arm64_linux_android)
816 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
817 STRNCASECMP(VG_Z_LIBC_SONAME
, __GI_strncasecmp
)
820 #elif defined(VGO_freebsd)
821 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
822 STRNCASECMP(VG_Z_LD_ELF_SO_1
, strncasecmp
)
823 STRNCASECMP(VG_Z_LD_ELF32_SO_1
, strncasecmp
)
825 #elif defined(VGO_darwin)
826 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
827 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
829 #elif defined(VGO_solaris)
830 STRNCASECMP(VG_Z_LIBC_SONAME
, strncasecmp
)
835 /*---------------------- strcasecmp_l ----------------------*/
837 #define STRCASECMP_L(soname, fnname) \
838 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
839 ( const char* s1, const char* s2, void* locale ); \
840 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
841 ( const char* s1, const char* s2, void* locale ) \
843 extern int tolower_l(int, void*) __attribute__((weak)); \
847 c1 = tolower_l(*(const UChar *)s1, locale); \
848 c2 = tolower_l(*(const UChar *)s2, locale); \
849 if (c1 != c2) break; \
850 if (c1 == 0) break; \
853 if ((UChar)c1 < (UChar)c2) return -1; \
854 if ((UChar)c1 > (UChar)c2) return 1; \
858 #if defined(VGO_linux)
859 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
860 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strcasecmp_l
)
861 STRCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strcasecmp_l
)
863 #elif defined(VGO_freebsd)
864 STRCASECMP_L(VG_Z_LIBC_SONAME
, strcasecmp_l
)
866 #elif defined(VGO_darwin)
867 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
869 #elif defined(VGO_solaris)
874 /*---------------------- strncasecmp_l ----------------------*/
876 #define STRNCASECMP_L(soname, fnname) \
877 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
878 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
879 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
880 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
882 extern int tolower_l(int, void*) __attribute__((weak)); \
885 if (n >= nmax) return 0; \
886 if (*s1 == 0 && *s2 == 0) return 0; \
887 if (*s1 == 0) return -1; \
888 if (*s2 == 0) return 1; \
890 if (tolower_l(*(const UChar *)s1, locale) \
891 < tolower_l(*(const UChar *)s2, locale)) return -1; \
892 if (tolower_l(*(const UChar *)s1, locale) \
893 > tolower_l(*(const UChar *)s2, locale)) return 1; \
899 #if defined(VGO_linux)
900 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI_strncasecmp_l
)
902 STRNCASECMP_L(VG_Z_LIBC_SONAME
, __GI___strncasecmp_l
)
904 #elif defined(VGO_freebsd)
905 STRNCASECMP_L(VG_Z_LIBC_SONAME
, strncasecmp_l
)
907 #elif defined(VGO_darwin)
908 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
909 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
911 #elif defined(VGO_solaris)
916 /*---------------------- strcmp ----------------------*/
918 #define STRCMP(soname, fnname) \
919 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
920 ( const char* s1, const char* s2 ); \
921 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
922 ( const char* s1, const char* s2 ) \
927 c1 = *(const UChar *)s1; \
928 c2 = *(const UChar *)s2; \
929 if (c1 != c2) break; \
930 if (c1 == 0) break; \
933 if ((UChar)c1 < (UChar)c2) return -1; \
934 if ((UChar)c1 > (UChar)c2) return 1; \
938 #if defined(VGO_linux)
939 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
940 STRCMP(VG_Z_LIBC_SONAME
, __GI_strcmp
)
941 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse2
)
942 STRCMP(VG_Z_LIBC_SONAME
, __strcmp_sse42
)
943 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2
, strcmp
)
944 STRCMP(VG_Z_LD64_SO_1
, strcmp
)
945 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
946 || defined(VGPV_mips32_linux_android)
947 STRCMP(NONE
, __dl_strcmp
); /* in /system/bin/linker */
950 #elif defined(VGO_freebsd)
951 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
952 STRCMP(VG_Z_LD_ELF_SO_1
, strcmp
)
953 STRCMP(VG_Z_LD_ELF32_SO_1
, strcmp
)
955 #elif defined(VGO_darwin)
956 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
957 # if DARWIN_VERS >= DARWIN_10_9
958 STRCMP(libsystemZuplatformZddylib
, _platform_strcmp
)
961 #elif defined(VGO_solaris)
962 STRCMP(VG_Z_LIBC_SONAME
, strcmp
)
963 STRCMP(VG_Z_LD_SO_1
, strcmp
)
968 /*---------------------- memchr ----------------------*/
970 #define MEMCHR(soname, fnname) \
971 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
972 (const void *s, int c, SizeT n); \
973 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
974 (const void *s, int c, SizeT n) \
977 UChar c0 = (UChar)c; \
978 const UChar* p = s; \
979 for (i = 0; i < n; i++) \
980 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
984 #if defined(VGO_linux)
985 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
986 MEMCHR(VG_Z_LIBC_SONAME
, __GI_memchr
)
988 #elif defined(VGO_freebsd)
989 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
991 #elif defined(VGO_darwin)
992 # if DARWIN_VERS == DARWIN_10_9
993 MEMCHR(VG_Z_DYLD
, memchr
)
994 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr
)
996 # if DARWIN_VERS >= DARWIN_10_10
997 MEMCHR(VG_Z_DYLD
, memchr
)
998 /* _platform_memchr$VARIANT$Generic */
999 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Generic
)
1000 /* _platform_memchr$VARIANT$Haswell */
1001 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Haswell
)
1003 # if DARWIN_VERS >= DARWIN_10_12
1004 /* _platform_memchr$VARIANT$Base */
1005 MEMCHR(libsystemZuplatformZddylib
, _platform_memchr$VARIANT$Base
)
1008 #elif defined(VGO_solaris)
1009 MEMCHR(VG_Z_LIBC_SONAME
, memchr
)
1014 /*---------------------- memrchr ----------------------*/
1016 #define MEMRCHR(soname, fnname) \
1017 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1018 (const void *s, int c, SizeT n); \
1019 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1020 (const void *s, int c, SizeT n) \
1023 UChar c0 = (UChar)c; \
1024 const UChar* p = s; \
1025 for (i = 0; i < n; i++) \
1026 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1030 #if defined(VGO_linux)
1031 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1033 #elif defined(VGO_freebsd)
1034 MEMRCHR(VG_Z_LIBC_SONAME
, memrchr
)
1036 #elif defined(VGO_darwin)
1037 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1038 //MEMRCHR(VG_Z_DYLD, memrchr)
1040 #elif defined(VGO_solaris)
1045 /*---------------------- memcpy ----------------------*/
1047 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1048 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1049 ( void *dst, const void *src, SizeT len ); \
1050 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1051 ( void *dst, const void *src, SizeT len ) \
1054 if (do_ol_check && is_overlap(dst, src, len, len)) \
1055 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1057 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1058 const Addr WM = WS - 1; /* 7 or 3 */ \
1061 if (dst < src || !is_overlap(dst, src, len, len)) { \
1063 /* Copying backwards. */ \
1065 Addr d = (Addr)dst; \
1066 Addr s = (Addr)src; \
1068 if (((s^d) & WM) == 0) { \
1069 /* s and d have same UWord alignment. */ \
1070 /* Pull up to a UWord boundary. */ \
1071 while ((s & WM) != 0 && n >= 1) \
1072 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1073 /* Copy UWords. */ \
1074 while (n >= WS * 4) \
1075 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
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; } \
1080 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1084 if (((s|d) & 1) == 0) { \
1085 /* Both are 16-aligned; copy what we can thusly. */ \
1087 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1089 /* Copy leftovers, or everything if misaligned. */ \
1091 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1093 } else if (dst > src) { \
1096 Addr d = ((Addr)dst) + n; \
1097 Addr s = ((Addr)src) + n; \
1099 /* Copying forwards. */ \
1100 if (((s^d) & WM) == 0) { \
1101 /* s and d have same UWord alignment. */ \
1102 /* Back down to a UWord boundary. */ \
1103 while ((s & WM) != 0 && n >= 1) \
1104 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1105 /* Copy UWords. */ \
1106 while (n >= WS * 4) \
1107 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
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; } \
1112 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1116 if (((s|d) & 1) == 0) { \
1117 /* Both are 16-aligned; copy what we can thusly. */ \
1119 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1121 /* Copy leftovers, or everything if misaligned. */ \
1123 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1131 #define MEMMOVE(soname, fnname) \
1132 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1134 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1135 why we disable the overlap check on x86_64. */
1136 #if defined(VGP_amd64_linux)
1137 #define MEMCPY(soname, fnname) \
1138 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 0)
1140 #define MEMCPY(soname, fnname) \
1141 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1144 #if defined(VGO_linux)
1145 /* For older memcpy we have to use memmove-like semantics and skip
1146 the overlap check; sigh; see #275284. */
1147 MEMMOVE(VG_Z_LIBC_SONAME
, memcpyZAGLIBCZu2Zd2Zd5
) /* memcpy@GLIBC_2.2.5 */
1148 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZAZAGLIBCZu2Zd14
) /* memcpy@@GLIBC_2.14 */
1149 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
) /* fallback case */
1150 MEMCPY(VG_Z_LIBC_SONAME
, __GI_memcpy
)
1151 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_sse2
)
1152 MEMCPY(VG_Z_LIBC_SONAME
, __memcpy_avx_unaligned_erms
)
1153 MEMCPY(VG_Z_LD_SO_1
, memcpy
) /* ld.so.1 */
1154 MEMCPY(VG_Z_LD64_SO_1
, memcpy
) /* ld64.so.1 */
1155 /* icc9 blats these around all over the place. Not only in the main
1156 executable but various .so's. They are highly tuned and read
1157 memory beyond the source boundary (although work correctly and
1158 never go across page boundaries), so give errors when run
1159 natively, at least for misaligned source arg. Just intercepting
1160 in the exe only until we understand more about the problem. See
1161 http://bugs.kde.org/show_bug.cgi?id=139776
1163 MEMCPY(NONE
, ZuintelZufastZumemcpy
)
1165 #elif defined(VGO_freebsd)
1166 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1167 MEMCPY(VG_Z_LD_ELF_SO_1
, memcpy
)
1168 MEMCPY(VG_Z_LD_ELF32_SO_1
, memcpy
)
1170 #elif defined(VGO_darwin)
1171 # if DARWIN_VERS <= DARWIN_10_6
1172 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1174 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse3x
) /* memcpy$VARIANT$sse3x */
1175 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZDVARIANTZDsse42
) /* memcpy$VARIANT$sse42 */
1177 #elif defined(VGO_solaris)
1178 MEMCPY(VG_Z_LIBC_SONAME
, memcpy
)
1179 MEMCPY(VG_Z_LIBC_SONAME
, memcpyZPZa
)
1180 MEMCPY(VG_Z_LD_SO_1
, memcpy
)
1185 /*---------------------- memcmp ----------------------*/
1187 #define MEMCMP(soname, fnname) \
1188 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1189 ( const void *s1V, const void *s2V, SizeT n ); \
1190 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1191 ( const void *s1V, const void *s2V, SizeT n ) \
1193 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1194 const SizeT WM = WS - 1; /* 7 or 3 */ \
1195 Addr s1A = (Addr)s1V; \
1196 Addr s2A = (Addr)s2V; \
1198 if (((s1A | s2A) & WM) == 0) { \
1199 /* Both areas are word aligned. Skip over the */ \
1200 /* equal prefix as fast as possible. */ \
1202 UWord w1 = *(UWord*)s1A; \
1203 UWord w2 = *(UWord*)s2A; \
1204 if (w1 != w2) break; \
1211 const UChar* s1 = (const UChar*) s1A; \
1212 const UChar* s2 = (const UChar*) s2A; \
1219 int res = ((int)a0) - ((int)b0); \
1227 #if defined(VGO_linux)
1228 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1229 MEMCMP(VG_Z_LIBC_SONAME
, __GI_memcmp
)
1230 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse2
)
1231 MEMCMP(VG_Z_LIBC_SONAME
, __memcmp_sse4_1
)
1232 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1233 MEMCMP(VG_Z_LD_SO_1
, bcmp
)
1235 #elif defined(VGO_freebsd)
1236 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1237 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1238 MEMCMP(VG_Z_LIBC_SONAME
, timingsafe_memcmp
)
1239 MEMCMP(VG_Z_LIBC_SONAME
, timingsafe_bcmp
)
1241 #elif defined(VGO_darwin)
1242 # if DARWIN_VERS >= DARWIN_10_9
1243 MEMCMP(libsystemZuplatformZddylib
, _platform_memcmp
)
1246 #elif defined(VGO_solaris)
1247 MEMCMP(VG_Z_LIBC_SONAME
, memcmp
)
1248 MEMCMP(VG_Z_LIBC_SONAME
, bcmp
)
1249 MEMCMP(VG_Z_LD_SO_1
, memcmp
)
1254 /*---------------------- stpcpy ----------------------*/
1256 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1257 DEST. (minor variant of strcpy) */
1258 #define STPCPY(soname, fnname) \
1259 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1260 ( char* dst, const char* src ); \
1261 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1262 ( char* dst, const char* src ) \
1264 const HChar* src_orig = src; \
1265 HChar* dst_orig = dst; \
1267 while (*src) *dst++ = *src++; \
1270 /* This checks for overlap after copying, unavoidable without */ \
1271 /* pre-counting length... should be ok */ \
1272 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1273 RECORD_COPY(srclen); \
1274 if (is_overlap(dst_orig, \
1276 (Addr)dst-(Addr)dst_orig+1, \
1278 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1283 #if defined(VGO_linux)
1284 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1285 STPCPY(VG_Z_LIBC_SONAME
, __GI_stpcpy
)
1286 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2
)
1287 STPCPY(VG_Z_LIBC_SONAME
, __stpcpy_sse2_unaligned
)
1288 STPCPY(VG_Z_LD_LINUX_SO_2
, stpcpy
)
1289 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, stpcpy
)
1290 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1
,stpcpy
)
1292 #elif defined(VGO_freebsd)
1293 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1294 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1295 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1297 #elif defined(VGO_freebsd)
1298 STPCPY(VG_Z_LD_ELF_SO_1
, stpcpy
)
1299 STPCPY(VG_Z_LD_ELF32_SO_1
, stpcpy
)
1300 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1302 #elif defined(VGO_darwin)
1303 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1304 //STPCPY(VG_Z_DYLD, stpcpy)
1306 #elif defined(VGO_solaris)
1307 STPCPY(VG_Z_LIBC_SONAME
, stpcpy
)
1312 /*---------------------- stpncpy ----------------------*/
1314 #define STPNCPY(soname, fnname) \
1315 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1316 ( char* dst, const char* src, SizeT n ); \
1317 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1318 ( char* dst, const char* src, SizeT n ) \
1320 const HChar* src_orig = src; \
1321 HChar* dst_str = dst; \
1324 while (m < n && *src) { m++; *dst++ = *src++; } \
1325 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1326 /* but only m+1 bytes of src if terminator was found */ \
1327 SizeT srclen = (m < n) ? m+1 : n; \
1328 RECORD_COPY(srclen); \
1329 if (is_overlap(dst_str, src_orig, n, srclen)) \
1330 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1332 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1337 #if defined(VGO_linux) || defined(VGO_freebsd)
1338 STPNCPY(VG_Z_LIBC_SONAME
, stpncpy
)
1342 /*---------------------- memset ----------------------*/
1344 #define MEMSET(soname, fnname) \
1345 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1346 (void *s, Int c, SizeT n); \
1347 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1348 (void *s, Int c, SizeT n) \
1350 if (sizeof(void*) == 8) { \
1352 ULong c8 = (c & 0xFF); \
1353 c8 = (c8 << 8) | c8; \
1354 c8 = (c8 << 16) | c8; \
1355 c8 = (c8 << 32) | c8; \
1356 while ((a & 7) != 0 && n >= 1) \
1357 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1359 { *(ULong*)a = c8; a += 8; n -= 8; \
1360 *(ULong*)a = c8; a += 8; n -= 8; \
1361 *(ULong*)a = c8; a += 8; n -= 8; \
1362 *(ULong*)a = c8; a += 8; n -= 8; } \
1364 { *(ULong*)a = c8; a += 8; n -= 8; } \
1366 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1370 UInt c4 = (c & 0xFF); \
1371 c4 = (c4 << 8) | c4; \
1372 c4 = (c4 << 16) | c4; \
1373 while ((a & 3) != 0 && n >= 1) \
1374 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1376 { *(UInt*)a = c4; a += 4; n -= 4; \
1377 *(UInt*)a = c4; a += 4; n -= 4; \
1378 *(UInt*)a = c4; a += 4; n -= 4; \
1379 *(UInt*)a = c4; a += 4; n -= 4; } \
1381 { *(UInt*)a = c4; a += 4; n -= 4; } \
1383 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1388 #if defined(VGO_linux)
1389 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1391 #elif defined(VGO_freebsd)
1392 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1393 MEMSET(VG_Z_LD_ELF_SO_1
, memset
)
1394 MEMSET(VG_Z_LD_ELF32_SO_1
, memset
)
1396 #elif defined(VGO_darwin)
1397 //MEMSET(VG_Z_LIBC_SONAME, memset)
1398 //MEMSET(VG_Z_DYLD, memset)
1399 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1401 #elif defined(VGO_solaris)
1402 MEMSET(VG_Z_LIBC_SONAME
, memset
)
1403 MEMSET(VG_Z_LIBC_SONAME
, memsetZPZa
)
1408 /*---------------------- memmove ----------------------*/
1410 /* memmove -- use the MEMMOVE defn above. */
1412 #if defined(VGO_linux)
1413 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1414 MEMMOVE(VG_Z_LIBC_SONAME
, __GI_memmove
)
1415 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1416 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1418 MEMMOVE(VG_Z_LD64_SO_1
, memmove
)
1420 #elif defined(VGO_freebsd)
1421 MEMMOVE(VG_Z_LD_ELF_SO_1
, memmove
)
1422 MEMMOVE(VG_Z_LD_ELF32_SO_1
, memmove
)
1423 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1425 #elif defined(VGO_darwin)
1426 # if DARWIN_VERS <= DARWIN_10_6
1427 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1429 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse3x
) /* memmove$VARIANT$sse3x */
1430 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZDVARIANTZDsse42
) /* memmove$VARIANT$sse42 */
1431 # if DARWIN_VERS >= DARWIN_10_9
1432 /* _platform_memmove$VARIANT$Ivybridge */
1433 MEMMOVE(libsystemZuplatformZddylib
, ZuplatformZumemmoveZDVARIANTZDIvybridge
)
1436 #elif defined(VGO_solaris)
1437 MEMMOVE(VG_Z_LIBC_SONAME
, memmove
)
1438 MEMMOVE(VG_Z_LIBC_SONAME
, memmoveZPZa
)
1439 MEMMOVE(VG_Z_LD_SO_1
, memmove
)
1444 /*---------------------- bcopy ----------------------*/
1446 #define BCOPY(soname, fnname) \
1447 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1448 (const void *srcV, void *dstV, SizeT n); \
1449 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1450 (const void *srcV, void *dstV, SizeT n) \
1454 HChar* dst = dstV; \
1455 const HChar* src = srcV; \
1457 for (i = 0; i < n; i++) \
1462 for (i = 0; i < n; i++) \
1463 dst[n-i-1] = src[n-i-1]; \
1467 #if defined(VGO_linux)
1468 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1470 #elif defined(VGO_freebsd)
1471 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1472 BCOPY(VG_Z_LD_ELF_SO_1
, bcopy
)
1473 BCOPY(VG_Z_LD_ELF32_SO_1
, bcopy
)
1475 #elif defined(VGO_darwin)
1476 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1477 //BCOPY(VG_Z_DYLD, bcopy)
1479 #elif defined(VGO_darwin)
1480 BCOPY(VG_Z_LIBC_SONAME
, bcopy
)
1485 /*-------------------- memmove_chk --------------------*/
1487 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1488 There is no specific part of glibc that this is copied from. */
1489 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1490 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1491 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1492 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1493 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1497 HChar* dst = dstV; \
1498 const HChar* src = srcV; \
1502 for (i = 0; i < n; i++) \
1507 for (i = 0; i < n; i++) \
1508 dst[n-i-1] = src[n-i-1]; \
1512 VALGRIND_PRINTF_BACKTRACE( \
1513 "*** memmove_chk: buffer overflow detected ***: " \
1514 "program terminated\n"); \
1520 #if defined(VGO_linux)
1521 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME
, __memmove_chk
)
1523 #elif defined(VGO_darwin)
1525 #elif defined(VGO_solaris)
1530 /*-------------------- strchrnul --------------------*/
1532 /* Find the first occurrence of C in S or the final NUL byte. */
1533 #define GLIBC232_STRCHRNUL(soname, fnname) \
1534 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1535 (const char* s, int c_in); \
1536 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1537 (const char* s, int c_in) \
1539 HChar c = (HChar) c_in; \
1540 const HChar* char_ptr = s; \
1542 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1543 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1548 #if defined(VGO_linux)
1549 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1551 #elif defined(VGO_freebsd)
1552 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME
, strchrnul
)
1554 #elif defined(VGO_darwin)
1556 #elif defined(VGO_solaris)
1561 /*---------------------- rawmemchr ----------------------*/
1563 /* Find the first occurrence of C in S. */
1564 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1565 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1566 (const void* s, int c_in); \
1567 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1568 (const void* s, int c_in) \
1570 UChar c = (UChar) c_in; \
1571 const UChar* char_ptr = s; \
1573 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1578 #if defined (VGO_linux)
1579 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, rawmemchr
)
1580 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME
, __GI___rawmemchr
)
1582 #elif defined(VGO_darwin)
1584 #elif defined(VGO_solaris)
1589 /*---------------------- strcpy_chk ----------------------*/
1591 /* glibc variant of strcpy that checks the dest is big enough.
1592 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1593 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1594 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1595 (char* dst, const char* src, SizeT len); \
1596 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1597 (char* dst, const char* src, SizeT len) \
1599 FOR_COPY(const HChar* src_orig = src); \
1603 while ((*dst++ = *src++) != '\0') \
1606 RECORD_COPY((Addr)src-(Addr)src_orig); \
1609 VALGRIND_PRINTF_BACKTRACE( \
1610 "*** strcpy_chk: buffer overflow detected ***: " \
1611 "program terminated\n"); \
1617 #if defined(VGO_linux)
1618 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME
, __strcpy_chk
)
1620 #elif defined(VGO_darwin)
1622 #elif defined(VGO_solaris)
1627 /*---------------------- stpcpy_chk ----------------------*/
1629 /* glibc variant of stpcpy that checks the dest is big enough.
1630 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1631 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1632 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1633 (char* dst, const char* src, SizeT len); \
1634 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1635 (char* dst, const char* src, SizeT len) \
1637 FOR_COPY(const HChar* src_orig = src); \
1640 while ((*dst++ = *src++) != '\0') \
1643 RECORD_COPY((Addr)src-(Addr)src_orig); \
1646 VALGRIND_PRINTF_BACKTRACE( \
1647 "*** stpcpy_chk: buffer overflow detected ***: " \
1648 "program terminated\n"); \
1654 #if defined(VGO_linux)
1655 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME
, __stpcpy_chk
)
1657 #elif defined(VGO_darwin)
1659 #elif defined(VGO_solaris)
1664 /*---------------------- mempcpy ----------------------*/
1667 #define GLIBC25_MEMPCPY(soname, fnname) \
1668 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1669 ( void *dst, const void *src, SizeT len ); \
1670 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1671 ( void *dst, const void *src, SizeT len ) \
1674 SizeT len_saved = len; \
1679 if (is_overlap(dst, src, len, len)) \
1680 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1682 if ( dst > src ) { \
1683 register HChar *d = (char *)dst + len - 1; \
1684 register const HChar *s = (const char *)src + len - 1; \
1688 } else if ( dst < src ) { \
1689 register HChar *d = dst; \
1690 register const HChar *s = src; \
1695 return (void*)( ((char*)dst) + len_saved ); \
1698 #if defined(VGO_linux)
1699 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1700 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, __GI_mempcpy
)
1701 GLIBC25_MEMPCPY(VG_Z_LD_SO_1
, mempcpy
) /* ld.so.1 */
1702 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3
, mempcpy
) /* ld-linux.so.3 */
1703 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2
, mempcpy
) /* ld-linux-x86-64.so.2 */
1705 #elif defined(VGO_freebsd)
1706 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME
, mempcpy
)
1707 #elif defined(VGO_darwin)
1708 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1710 #elif defined(VGO_solaris)
1715 /*-------------------- memcpy_chk --------------------*/
1717 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1718 why we disable the overlap check on x86_64. */
1719 #if defined(VGP_amd64_linux)
1720 #define CHECK_OVERLAP 0
1722 #define CHECK_OVERLAP 1
1725 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1726 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1727 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1728 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1729 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1731 register HChar *d; \
1732 register const HChar *s; \
1738 if (CHECK_OVERLAP && is_overlap(dst, src, len, len)) \
1739 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1740 if ( dst > src ) { \
1741 d = (HChar *)dst + len - 1; \
1742 s = (const HChar *)src + len - 1; \
1746 } else if ( dst < src ) { \
1748 s = (const HChar *)src; \
1755 VALGRIND_PRINTF_BACKTRACE( \
1756 "*** memcpy_chk: buffer overflow detected ***: " \
1757 "program terminated\n"); \
1763 #if defined(VGO_linux)
1764 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME
, __memcpy_chk
)
1766 #elif defined(VGO_darwin)
1768 #elif defined(VGO_solaris)
1773 /*---------------------- strstr ----------------------*/
1775 #define STRSTR(soname, fnname) \
1776 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1777 (const char* haystack, const char* needle); \
1778 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1779 (const char* haystack, const char* needle) \
1781 const HChar* h = haystack; \
1782 const HChar* n = needle; \
1784 /* find the length of n, not including terminating zero */ \
1786 while (n[nlen]) nlen++; \
1788 /* if n is the empty string, match immediately. */ \
1789 if (nlen == 0) return CONST_CAST(HChar *,h); \
1791 /* assert(nlen >= 1); */ \
1795 const HChar hh = *h; \
1796 if (hh == 0) return NULL; \
1797 if (hh != n0) { h++; continue; } \
1800 for (i = 0; i < nlen; i++) { \
1804 /* assert(i >= 0 && i <= nlen); */ \
1806 return CONST_CAST(HChar *,h); \
1812 #if defined(VGO_linux)
1813 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1814 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse2
)
1815 STRSTR(VG_Z_LIBC_SONAME
, __strstr_sse42
)
1817 #elif defined(VGO_freebsd)
1818 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1820 #elif defined(VGO_darwin)
1822 #elif defined(VGO_solaris)
1823 STRSTR(VG_Z_LIBC_SONAME
, strstr
)
1827 /*---------------------- memmem ----------------------*/
1829 #define MEMMEM(soname, fnname) \
1830 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1831 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1832 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1833 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1835 const HChar* h = haystack; \
1836 const HChar* n = needle; \
1838 /* If the needle is the empty string, match immediately. */ \
1839 if (nlen == 0) return CONST_CAST(void *,h); \
1843 for (; hlen >= nlen; hlen--, h++) { \
1844 if (h[0] != n0) continue; \
1847 for (i = 1; i < nlen; i++) { \
1852 return CONST_CAST(HChar *,h); \
1858 #if defined(VGP_s390x_linux)
1859 MEMMEM(VG_Z_LIBC_SONAME
, memmem
)
1863 /*---------------------- strpbrk ----------------------*/
1865 #define STRPBRK(soname, fnname) \
1866 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1867 (const char* sV, const char* acceptV); \
1868 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1869 (const char* sV, const char* acceptV) \
1871 const HChar* s = sV; \
1872 const HChar* accept = acceptV; \
1874 /* find the length of 'accept', not including terminating zero */ \
1876 while (accept[nacc]) nacc++; \
1878 /* if n is the empty string, fail immediately. */ \
1879 if (nacc == 0) return NULL; \
1881 /* assert(nacc >= 1); */ \
1887 for (i = 0; i < nacc; i++) { \
1888 if (sc == accept[i]) \
1889 return CONST_CAST(HChar *,s); \
1897 #if defined(VGO_linux)
1898 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1900 #elif defined(VGO_freebsd)
1901 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1903 #elif defined(VGO_darwin)
1905 #elif defined(VGO_solaris)
1906 STRPBRK(VG_Z_LIBC_SONAME
, strpbrk
)
1911 /*---------------------- strcspn ----------------------*/
1913 #define STRCSPN(soname, fnname) \
1914 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1915 (const char* sV, const char* rejectV); \
1916 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1917 (const char* sV, const char* rejectV) \
1919 const HChar* s = sV; \
1920 const HChar* reject = rejectV; \
1922 /* find the length of 'reject', not including terminating zero */ \
1924 while (reject[nrej]) nrej++; \
1932 for (i = 0; i < nrej; i++) { \
1933 if (sc == reject[i]) \
1936 /* assert(i >= 0 && i <= nrej); */ \
1946 #if defined(VGO_linux)
1947 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1948 STRCSPN(VG_Z_LIBC_SONAME
, __GI_strcspn
)
1950 #elif defined(VGO_freebsd)
1951 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1953 #elif defined(VGO_darwin)
1955 #elif defined(VGO_solaris)
1956 STRCSPN(VG_Z_LIBC_SONAME
, strcspn
)
1961 /*---------------------- strspn ----------------------*/
1963 #define STRSPN(soname, fnname) \
1964 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1965 (const char* sV, const char* acceptV); \
1966 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1967 (const char* sV, const char* acceptV) \
1969 const UChar* s = (const UChar *)sV; \
1970 const UChar* accept = (const UChar *)acceptV; \
1972 /* find the length of 'accept', not including terminating zero */ \
1974 while (accept[nacc]) nacc++; \
1975 if (nacc == 0) return 0; \
1983 for (i = 0; i < nacc; i++) { \
1984 if (sc == accept[i]) \
1987 /* assert(i >= 0 && i <= nacc); */ \
1997 #if defined(VGO_linux)
1998 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2000 #elif defined(VGO_freebsd)
2001 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2003 #elif defined(VGO_darwin)
2005 #elif defined(VGO_solaris)
2006 STRSPN(VG_Z_LIBC_SONAME
, strspn
)
2011 /*---------------------- strcasestr ----------------------*/
2013 #define STRCASESTR(soname, fnname) \
2014 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2015 (const char* haystack, const char* needle); \
2016 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2017 (const char* haystack, const char* needle) \
2019 extern int tolower(int); \
2020 const HChar* h = haystack; \
2021 const HChar* n = needle; \
2023 /* find the length of n, not including terminating zero */ \
2025 while (n[nlen]) nlen++; \
2027 /* if n is the empty string, match immediately. */ \
2028 if (nlen == 0) return CONST_CAST(HChar *,h); \
2030 /* assert(nlen >= 1); */ \
2031 UChar n0 = tolower(n[0]); \
2034 UChar hh = tolower(*h); \
2035 if (hh == 0) return NULL; \
2036 if (hh != n0) { h++; continue; } \
2039 for (i = 0; i < nlen; i++) { \
2040 if (tolower(n[i]) != tolower(h[i])) \
2043 /* assert(i >= 0 && i <= nlen); */ \
2045 return CONST_CAST(HChar *,h); \
2051 #if defined(VGO_linux)
2052 # if !defined(VGPV_arm_linux_android) \
2053 && !defined(VGPV_x86_linux_android) \
2054 && !defined(VGPV_mips32_linux_android) \
2055 && !defined(VGPV_arm64_linux_android)
2056 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2059 #elif defined(VGO_freebsd)
2060 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2062 #elif defined(VGO_darwin)
2064 #elif defined(VGO_solaris)
2065 STRCASESTR(VG_Z_LIBC_SONAME
, strcasestr
)
2070 /*---------------------- wcslen ----------------------*/
2072 // This is a wchar_t equivalent to strlen. Unfortunately
2073 // we don't have wchar_t available here, but it looks like
2074 // a 32 bit int on Linux. I don't know if that is also
2077 #define WCSLEN(soname, fnname) \
2078 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2079 ( const Int* str ); \
2080 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2081 ( const Int* str ) \
2084 while (str[i] != 0) i++; \
2088 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2089 WCSLEN(VG_Z_LIBC_SONAME
, wcslen
)
2093 /*---------------------- wcsnlen ----------------------*/
2095 #define WCSNLEN(soname, fnname) \
2096 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2097 ( const Int *s, SizeT n ); \
2098 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2099 ( const Int *s, SizeT n ) \
2103 while (i < n && *p != 0) { \
2110 #if defined(VGO_linux) || defined(VGO_freebsd)
2111 WCSNLEN(VG_Z_LIBC_SONAME
, wcsnlen
)
2112 WCSNLEN(VG_Z_LIBC_SONAME
, __GI_wcsnlen
)
2115 /*---------------------- wcscmp ----------------------*/
2117 // This is a wchar_t equivalent to strcmp. We don't
2118 // have wchar_t available here, but in the GNU C Library
2119 // wchar_t is always 32 bits wide and wcscmp uses signed
2120 // comparison, not unsigned as in strcmp function.
2122 #define WCSCMP(soname, fnname) \
2123 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2124 ( const Int* s1, const Int* s2 ); \
2125 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2126 ( const Int* s1, const Int* s2 ) \
2133 if (c1 != c2) break; \
2134 if (c1 == 0) break; \
2137 if (c1 < c2) return -1; \
2138 if (c1 > c2) return 1; \
2142 #if defined(VGO_linux) || defined(VGO_freebsd)
2143 WCSCMP(VG_Z_LIBC_SONAME
, wcscmp
)
2146 /*---------------------- wcsncmp ----------------------*/
2148 // This is a wchar_t equivalent to strncmp. We don't
2149 // have wchar_t available here, but in the GNU C Library
2150 // wchar_t is always 32 bits wide and wcsncmp uses signed
2151 // comparison, not unsigned as in strncmp function.
2153 #define WCSNCMP(soname, fnname) \
2154 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2155 ( const Int* s1, const Int* s2, SizeT nmax ); \
2156 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2157 ( const Int* s1, const Int* s2, SizeT nmax ) \
2161 if (n >= nmax) return 0; \
2162 if (*s1 == 0 && *s2 == 0) return 0; \
2163 if (*s1 == 0) return -1; \
2164 if (*s2 == 0) return 1; \
2166 if (*s1 < *s2) return -1; \
2167 if (*s1 > *s2) return 1; \
2172 #if defined(VGO_linux) || defined(VGO_freebsd)
2173 WCSNCMP(VG_Z_LIBC_SONAME
, wcsncmp
)
2176 /*---------------------- wcscpy ----------------------*/
2178 // This is a wchar_t equivalent to strcpy. We don't
2179 // have wchar_t available here, but in the GNU C Library
2180 // wchar_t is always 32 bits wide.
2182 #define WCSCPY(soname, fnname) \
2183 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2184 ( Int* dst, const Int* src ); \
2185 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2186 ( Int* dst, const Int* src ) \
2188 const Int* src_orig = src; \
2189 Int* dst_orig = dst; \
2191 while (*src) *dst++ = *src++; \
2194 /* This checks for overlap after copying, unavoidable without */ \
2195 /* pre-counting length... should be ok */ \
2196 /* +4 because sizeof(wchar_t) == 4 */ \
2197 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2198 RECORD_COPY(srclen); \
2199 if (is_overlap(dst_orig, \
2201 /* +4 because sizeof(wchar_t) == 4 */ \
2202 (Addr)dst-(Addr)dst_orig+4, \
2204 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2209 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2210 WCSCPY(VG_Z_LIBC_SONAME
, wcscpy
)
2214 /*---------------------- wcschr ----------------------*/
2216 // This is a wchar_t equivalent to strchr. We don't
2217 // have wchar_t available here, but in the GNU C Library
2218 // wchar_t is always 32 bits wide.
2220 #define WCSCHR(soname, fnname) \
2221 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2222 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2226 if (*p == c) return CONST_CAST(Int *,p); \
2227 if (*p == 0) return NULL; \
2232 #if defined(VGO_linux) || defined(VGO_freebsd)
2233 WCSCHR(VG_Z_LIBC_SONAME
, wcschr
)
2235 /*---------------------- wcsrchr ----------------------*/
2237 // This is a wchar_t equivalent to strrchr. We don't
2238 // have wchar_t available here, but in the GNU C Library
2239 // wchar_t is always 32 bits wide.
2241 #define WCSRCHR(soname, fnname) \
2242 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2243 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2246 const Int* last = NULL; \
2248 if (*p == c) last = p; \
2249 if (*p == 0) return CONST_CAST(Int *,last); \
2254 #if defined(VGO_linux) || defined(VGO_freebsd)
2255 WCSRCHR(VG_Z_LIBC_SONAME
, wcsrchr
)
2258 /*---------------------- wmemchr ----------------------*/
2260 // This is a wchar_t equivalent to memchr. We don't
2261 // have wchar_t available here, but in the GNU C Library
2262 // wchar_t is always 32 bits wide.
2264 #define WMEMCHR(soname, fnname) \
2265 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2266 (const Int *s, Int c, SizeT n); \
2267 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2268 (const Int *s, Int c, SizeT n) \
2272 for (i = 0; i < n; i++) { \
2273 if (*p == c) return CONST_CAST(Int *,p); \
2279 #if defined(VGO_linux)
2280 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2281 WMEMCHR(VG_Z_LIBC_SONAME
, __GI_wmemchr
)
2284 #if defined(VGO_freebsd)
2285 WMEMCHR(VG_Z_LIBC_SONAME
, wmemchr
)
2288 /*---------------------- wmemcmp ----------------------*/
2290 #define WMEMCMP(soname, fnname) \
2291 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2292 ( const Int *b1, const Int *b2, SizeT n ); \
2293 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2294 ( const Int *b1, const Int *b2, SizeT n ) \
2296 for (SizeT i = 0U; i < n; ++i) { \
2297 if (b1[i] != b2[i]) \
2298 return b1[i] > b2[i] ? 1 : -1; \
2303 #if defined(VGO_linux) || defined(VGO_freebsd)
2304 WMEMCMP(VG_Z_LIBC_SONAME
, wmemcmp
)
2307 /*---------------------- wcsncpy ----------------------*/
2309 // This is a wchar_t equivalent to strncpy. We don't
2310 // have wchar_t available here, but in the GNU C Library
2311 // wchar_t is always 32 bits wide.
2313 #define WCSNCPY(soname, fnname) \
2314 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2315 ( Int* dst, const Int* src, SizeT n ); \
2316 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2317 ( Int* dst, const Int* src, SizeT n ) \
2319 const Int* src_orig = src; \
2320 Int* dst_orig = dst; \
2323 while (m < n && *src) { \
2328 /* This checks for overlap after copying, unavoidable without */ \
2329 /* pre-counting length... should be ok */ \
2330 /* +4 because sizeof(wchar_t) == 4 */ \
2331 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2332 RECORD_COPY(srclen); \
2333 if (is_overlap(dst_orig, \
2337 RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
2346 #if defined(VGO_linux) || defined(VGO_freebsd)
2347 WCSNCPY(VG_Z_LIBC_SONAME
, wcsncpy
)
2350 /*---------------------- memccpy ----------------------*/
2352 /* memccpy, mostly based on GNU libc source */
2353 #define MEMCCPY(soname, fnname) \
2354 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2355 ( void *dst, const void *src, Int c, SizeT len ); \
2356 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2357 ( void *dst, const void *src, Int c, SizeT len ) \
2359 const char *s = src; \
2365 if ((*d++ = *s++) == x) { \
2366 SizeT srclen = (i < len) ? i : len; \
2367 RECORD_COPY(srclen); \
2368 if (is_overlap(dst, src, srclen, srclen)) \
2369 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2375 if (is_overlap(dst, src, len, len)) \
2376 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2381 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_darwin) || defined(VGO_solaris)
2382 MEMCCPY(VG_Z_LIBC_SONAME
, memccpy
)
2385 /*------------------------------------------------------------*/
2386 /*--- Improve definedness checking of process environment ---*/
2387 /*------------------------------------------------------------*/
2389 #if defined(VGO_linux) || defined(VGO_freebsd)
2391 /* If these wind up getting generated via a macro, so that multiple
2392 versions of each function exist (as above), use the _EZU variants
2393 to assign equivalance class tags. */
2395 /*---------------------- putenv ----------------------*/
2397 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
);
2398 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, putenv
) (char* string
)
2402 const HChar
* p
= string
;
2403 VALGRIND_GET_ORIG_FN(fn
);
2404 /* Now by walking over the string we magically produce
2405 traces when hitting undefined memory. */
2408 __asm__
__volatile__("" ::: "memory");
2409 CALL_FN_W_W(result
, fn
, string
);
2414 /*---------------------- unsetenv ----------------------*/
2416 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
);
2417 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, unsetenv
) (const char* name
)
2421 const HChar
* p
= name
;
2422 VALGRIND_GET_ORIG_FN(fn
);
2423 /* Now by walking over the string we magically produce
2424 traces when hitting undefined memory. */
2427 __asm__
__volatile__("" ::: "memory");
2428 CALL_FN_W_W(result
, fn
, name
);
2433 /*---------------------- setenv ----------------------*/
2436 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2437 (const char* name
, const char* value
, int overwrite
);
2438 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME
, setenv
)
2439 (const char* name
, const char* value
, int overwrite
)
2444 VALGRIND_GET_ORIG_FN(fn
);
2445 /* Now by walking over the string we magically produce
2446 traces when hitting undefined memory. */
2448 for (p
= name
; *p
; p
++)
2449 __asm__
__volatile__("" ::: "memory");
2451 for (p
= value
; *p
; p
++)
2452 __asm__
__volatile__("" ::: "memory");
2453 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite
);
2454 CALL_FN_W_WWW(result
, fn
, name
, value
, overwrite
);
2458 #endif /* defined(VGO_linux) */
2460 /*--------------------------------------------------------------------*/
2462 /*--------------------------------------------------------------------*/