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