drd/tests/swapcontext: Improve the portability of this test further
[valgrind.git] / shared / vg_replace_strmem.c
blobaaa29940aacbb620db06e1a15fe2c3fd9b44d445
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
108 #if defined(VGO_solaris)
110 Detour functions in the libc and the runtime linker. If a function isn't
111 much optimized (and no overlap checking is necessary) then redir the
112 function only in the libc. This way we can keep stacktraces in the tests
113 consistent.
115 #endif
118 /* Figure out if [dst .. dst+dstlen-1] overlaps with
119 [src .. src+srclen-1].
120 We assume that the address ranges do not wrap around
121 (which is safe since on Linux addresses >= 0xC0000000
122 are not accessible and the program will segfault in this
123 circumstance, presumably).
125 static inline
126 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
128 Addr loS, hiS, loD, hiD;
130 if (dstlen == 0 || srclen == 0)
131 return False;
133 loS = (Addr)src;
134 loD = (Addr)dst;
135 hiS = loS + srclen - 1;
136 hiD = loD + dstlen - 1;
138 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
139 if (loS < loD) {
140 return !(hiS < loD);
142 else if (loD < loS) {
143 return !(hiD < loS);
145 else {
146 /* They start at same place. Since we know neither of them has
147 zero length, they must overlap. */
148 return True;
153 /* Call here to exit if we can't continue. On Android we can't call
154 _exit for some reason, so we have to blunt-instrument it. */
155 __attribute__ ((__noreturn__))
156 static inline void my_exit ( int x )
158 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
159 || defined(VGPV_arm64_linux_android)
160 __asm__ __volatile__(".word 0xFFFFFFFF");
161 while (1) {}
162 # elif defined(VGPV_x86_linux_android)
163 __asm__ __volatile__("ud2");
164 while (1) {}
165 # else
166 extern __attribute__ ((__noreturn__)) void _exit(int status);
167 _exit(x);
168 # endif
172 // This is a macro rather than a function because we don't want to have an
173 // extra function in the stack trace.
174 #ifndef RECORD_OVERLAP_ERROR
175 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
176 #endif
178 // Used for tools that record bulk copies: memcpy, strcpy, etc.
179 #ifndef RECORD_COPY
180 #define RECORD_COPY(len) do { } while (0)
181 #define FOR_COPY(x)
182 #else
183 #define FOR_COPY(x) x
184 #endif
186 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
187 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
188 #endif
191 /*---------------------- strrchr ----------------------*/
193 #define STRRCHR(soname, fnname) \
194 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
195 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
197 HChar ch = (HChar)c; \
198 const HChar* p = s; \
199 const HChar* last = NULL; \
200 while (True) { \
201 if (*p == ch) last = p; \
202 if (*p == 0) return CONST_CAST(HChar *,last); \
203 p++; \
207 // Apparently rindex() is the same thing as strrchr()
208 #if defined(VGO_linux)
209 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
210 STRRCHR(VG_Z_LIBC_SONAME, rindex)
211 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
212 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
213 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
214 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
215 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
216 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
217 || defined(VGPV_mips32_linux_android)
218 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
219 #endif
221 #elif defined(VGO_darwin)
222 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
223 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
224 //STRRCHR(VG_Z_DYLD, strrchr)
225 //STRRCHR(VG_Z_DYLD, rindex)
226 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
227 # if DARWIN_VERS >= DARWIN_10_9
228 STRRCHR(libsystemZucZddylib, strrchr)
229 # endif
231 #elif defined(VGO_solaris)
232 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
233 STRRCHR(VG_Z_LIBC_SONAME, rindex)
234 STRRCHR(VG_Z_LD_SO_1, strrchr)
236 #endif
239 /*---------------------- strchr ----------------------*/
241 #define STRCHR(soname, fnname) \
242 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
243 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
245 HChar ch = (HChar)c ; \
246 const HChar* p = s; \
247 while (True) { \
248 if (*p == ch) return CONST_CAST(HChar *,p); \
249 if (*p == 0) return NULL; \
250 p++; \
254 // Apparently index() is the same thing as strchr()
255 #if defined(VGO_linux)
256 STRCHR(VG_Z_LIBC_SONAME, strchr)
257 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
258 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
259 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
260 STRCHR(VG_Z_LIBC_SONAME, index)
261 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
262 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
263 STRCHR(VG_Z_LD_LINUX_SO_2, index)
264 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
265 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
266 # endif
268 #if defined(VGPV_mips32_linux_android)
269 STRCHR(NONE, __dl_strchr)
270 #endif
272 #elif defined(VGO_darwin)
273 STRCHR(VG_Z_LIBC_SONAME, strchr)
274 # if DARWIN_VERS == DARWIN_10_9
275 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
276 # endif
277 # if DARWIN_VERS >= DARWIN_10_10
278 /* _platform_strchr$VARIANT$Generic */
279 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
280 /* _platform_strchr$VARIANT$Haswell */
281 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
282 # endif
284 #elif defined(VGO_solaris)
285 STRCHR(VG_Z_LIBC_SONAME, strchr)
286 STRCHR(VG_Z_LIBC_SONAME, index)
287 STRCHR(VG_Z_LD_SO_1, strchr)
289 #endif
292 /*---------------------- strcat ----------------------*/
294 #define STRCAT(soname, fnname) \
295 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
296 ( char* dst, const char* src ); \
297 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
298 ( char* dst, const char* src ) \
300 const HChar* src_orig = src; \
301 HChar* dst_orig = dst; \
302 while (*dst) dst++; \
303 while (*src) *dst++ = *src++; \
304 *dst = 0; \
306 /* This is a bit redundant, I think; any overlap and the strcat will */ \
307 /* go forever... or until a seg fault occurs. */ \
308 if (is_overlap(dst_orig, \
309 src_orig, \
310 (Addr)dst-(Addr)dst_orig+1, \
311 (Addr)src-(Addr)src_orig+1)) \
312 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
314 return dst_orig; \
317 #if defined(VGO_linux)
318 STRCAT(VG_Z_LIBC_SONAME, strcat)
319 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
321 #elif defined(VGO_darwin)
322 //STRCAT(VG_Z_LIBC_SONAME, strcat)
324 #elif defined(VGO_solaris)
325 STRCAT(VG_Z_LIBC_SONAME, strcat)
326 STRCAT(VG_Z_LD_SO_1, strcat)
328 #endif
331 /*---------------------- strncat ----------------------*/
333 #define STRNCAT(soname, fnname) \
334 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
335 ( char* dst, const char* src, SizeT n ); \
336 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
337 ( char* dst, const char* src, SizeT n ) \
339 const HChar* src_orig = src; \
340 HChar* dst_orig = dst; \
341 SizeT m = 0; \
343 while (*dst) dst++; \
344 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
345 *dst = 0; /* always add null */ \
347 /* This checks for overlap after copying, unavoidable without */ \
348 /* pre-counting lengths... should be ok */ \
349 if (is_overlap(dst_orig, \
350 src_orig, \
351 (Addr)dst-(Addr)dst_orig+1, \
352 (Addr)src-(Addr)src_orig+1)) \
353 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
355 return dst_orig; \
358 #if defined(VGO_linux)
359 STRNCAT(VG_Z_LIBC_SONAME, strncat)
361 #elif defined(VGO_darwin)
362 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
363 //STRNCAT(VG_Z_DYLD, strncat)
365 #elif defined(VGO_solaris)
366 STRNCAT(VG_Z_LIBC_SONAME, strncat)
368 #endif
371 /*---------------------- strlcat ----------------------*/
373 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
374 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
375 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
376 Truncation occurred if retval >= n.
378 #define STRLCAT(soname, fnname) \
379 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
380 ( char* dst, const char* src, SizeT n ); \
381 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
382 ( char* dst, const char* src, SizeT n ) \
384 const HChar* src_orig = src; \
385 HChar* dst_orig = dst; \
386 SizeT m = 0; \
388 while (m < n && *dst) { m++; dst++; } \
389 if (m < n) { \
390 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
391 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
392 *dst = 0; \
393 } else { \
394 /* No space to copy anything to dst. m == n */ \
396 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
397 while (*src) { m++; src++; } \
398 /* This checks for overlap after copying, unavoidable without */ \
399 /* pre-counting lengths... should be ok */ \
400 if (is_overlap(dst_orig, \
401 src_orig, \
402 (Addr)dst-(Addr)dst_orig+1, \
403 (Addr)src-(Addr)src_orig+1)) \
404 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
406 return m; \
409 #if defined(VGO_linux)
411 #elif defined(VGO_darwin)
412 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
413 //STRLCAT(VG_Z_DYLD, strlcat)
414 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
416 #elif defined(VGO_solaris)
417 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
419 #endif
422 /*---------------------- strnlen ----------------------*/
424 #define STRNLEN(soname, fnname) \
425 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
426 ( const char* str, SizeT n ); \
427 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
428 ( const char* str, SizeT n ) \
430 SizeT i = 0; \
431 while (i < n && str[i] != 0) i++; \
432 return i; \
435 #if defined(VGO_linux)
436 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
437 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
439 #elif defined(VGO_darwin)
440 # if DARWIN_VERS == DARWIN_10_9
441 STRNLEN(libsystemZucZddylib, strnlen)
442 # endif
444 #elif defined(VGO_solaris)
445 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
447 #endif
450 /*---------------------- strlen ----------------------*/
452 // Note that this replacement often doesn't get used because gcc inlines
453 // calls to strlen() with its own built-in version. This can be very
454 // confusing if you aren't expecting it. Other small functions in
455 // this file may also be inline by gcc.
457 #define STRLEN(soname, fnname) \
458 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
459 ( const char* str ); \
460 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
461 ( const char* str ) \
463 SizeT i = 0; \
464 while (str[i] != 0) i++; \
465 return i; \
468 #if defined(VGO_linux)
469 STRLEN(VG_Z_LIBC_SONAME, strlen)
470 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
471 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
472 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
473 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
474 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
475 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
476 # if defined(VGPV_arm_linux_android) \
477 || defined(VGPV_x86_linux_android) \
478 || defined(VGPV_mips32_linux_android)
479 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
480 # endif
482 #elif defined(VGO_darwin)
483 STRLEN(VG_Z_LIBC_SONAME, strlen)
484 # if DARWIN_VERS >= DARWIN_10_9
485 STRLEN(libsystemZucZddylib, strlen)
486 # endif
488 #elif defined(VGO_solaris)
489 STRLEN(VG_Z_LIBC_SONAME, strlen)
490 STRLEN(VG_Z_LD_SO_1, strlen)
492 #endif
495 /*---------------------- strcpy ----------------------*/
497 #define STRCPY(soname, fnname) \
498 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
499 ( char* dst, const char* src ); \
500 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
501 ( char* dst, const char* src ) \
503 const HChar* src_orig = src; \
504 HChar* dst_orig = dst; \
506 while (*src) *dst++ = *src++; \
507 *dst = 0; \
509 /* This happens after copying, unavoidable without */ \
510 /* pre-counting length... should be ok */ \
511 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
512 RECORD_COPY(srclen); \
513 if (is_overlap(dst_orig, \
514 src_orig, \
515 (Addr)dst-(Addr)dst_orig+1, \
516 srclen)) \
517 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
519 return dst_orig; \
522 #if defined(VGO_linux)
523 STRCPY(VG_Z_LIBC_SONAME, strcpy)
524 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
526 #elif defined(VGO_darwin)
527 STRCPY(VG_Z_LIBC_SONAME, strcpy)
528 # if DARWIN_VERS == DARWIN_10_9
529 STRCPY(libsystemZucZddylib, strcpy)
530 # endif
532 #elif defined(VGO_solaris)
533 STRCPY(VG_Z_LIBC_SONAME, strcpy)
534 STRCPY(VG_Z_LD_SO_1, strcpy)
536 #endif
539 /*---------------------- strncpy ----------------------*/
541 #define STRNCPY(soname, fnname) \
542 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
543 ( char* dst, const char* src, SizeT n ); \
544 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
545 ( char* dst, const char* src, SizeT n ) \
547 const HChar* src_orig = src; \
548 HChar* dst_orig = dst; \
549 SizeT m = 0; \
551 while (m < n && *src) { m++; *dst++ = *src++; } \
552 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
553 /* but only m+1 bytes of src if terminator was found */ \
554 SizeT srclen = (m < n) ? m+1 : n; \
555 RECORD_COPY(srclen); \
556 if (is_overlap(dst_orig, src_orig, n, srclen)) \
557 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
558 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
560 return dst_orig; \
563 #if defined(VGO_linux)
564 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
565 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
566 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
567 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
569 #elif defined(VGO_darwin)
570 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
571 # if DARWIN_VERS >= DARWIN_10_9
572 STRNCPY(libsystemZucZddylib, strncpy)
573 # endif
575 #elif defined(VGO_solaris)
576 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
577 STRNCPY(VG_Z_LD_SO_1, strncpy)
579 #endif
582 /*---------------------- strlcpy ----------------------*/
584 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
585 Returns strlen(src). Does not zero-fill the remainder of dst. */
586 #define STRLCPY(soname, fnname) \
587 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
588 ( char* dst, const char* src, SizeT n ); \
589 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
590 ( char* dst, const char* src, SizeT n ) \
592 const HChar* src_orig = src; \
593 HChar* dst_orig = dst; \
594 SizeT m = 0; \
596 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
598 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
599 /* m non-nul bytes have now been copied, and m <= n-1. */ \
600 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
601 /* but only m+1 bytes of src if terminator was found */ \
602 SizeT srclen = (m < n) ? m+1 : n; \
603 RECORD_COPY(srclen); \
604 if (is_overlap(dst_orig, src_orig, n, srclen)) \
605 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
606 /* Nul-terminate dst. */ \
607 if (n > 0) *dst = 0; \
608 /* Finish counting strlen(src). */ \
609 while (*src) src++; \
610 return src - src_orig; \
613 #if defined(VGO_linux)
615 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
616 || defined(VGPV_mips32_linux_android)
617 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
618 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
619 #endif
621 #elif defined(VGO_darwin)
622 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
623 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
624 //STRLCPY(VG_Z_DYLD, strlcpy)
625 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
627 #elif defined(VGO_solaris)
628 /* special case for n == 0 which is undocumented but heavily used */
629 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
630 if (n == 0) { \
631 while (*src) src++; \
632 return src - src_orig; \
635 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
637 #endif
640 /*---------------------- strncmp ----------------------*/
642 #define STRNCMP(soname, fnname) \
643 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
644 ( const char* s1, const char* s2, SizeT nmax ); \
645 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
646 ( const char* s1, const char* s2, SizeT nmax ) \
648 SizeT n = 0; \
649 while (True) { \
650 if (n >= nmax) return 0; \
651 if (*s1 == 0 && *s2 == 0) return 0; \
652 if (*s1 == 0) return -1; \
653 if (*s2 == 0) return 1; \
655 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
656 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
658 s1++; s2++; n++; \
662 #if defined(VGO_linux)
663 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
664 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
665 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
666 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
668 #elif defined(VGO_darwin)
669 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
670 # if DARWIN_VERS >= DARWIN_10_9
671 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
672 # endif
674 #elif defined(VGO_solaris)
675 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
677 #endif
680 /*---------------------- strcasecmp ----------------------*/
682 #define STRCASECMP(soname, fnname) \
683 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
684 ( const char* s1, const char* s2 ); \
685 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
686 ( const char* s1, const char* s2 ) \
688 extern int tolower(int); \
689 register UChar c1; \
690 register UChar c2; \
691 while (True) { \
692 c1 = tolower(*(const UChar *)s1); \
693 c2 = tolower(*(const UChar *)s2); \
694 if (c1 != c2) break; \
695 if (c1 == 0) break; \
696 s1++; s2++; \
698 if ((UChar)c1 < (UChar)c2) return -1; \
699 if ((UChar)c1 > (UChar)c2) return 1; \
700 return 0; \
703 #if defined(VGO_linux)
704 # if !defined(VGPV_arm_linux_android) \
705 && !defined(VGPV_x86_linux_android) \
706 && !defined(VGPV_mips32_linux_android) \
707 && !defined(VGPV_arm64_linux_android)
708 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
709 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
710 # endif
712 #elif defined(VGO_darwin)
713 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
715 #elif defined(VGO_solaris)
716 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
718 #endif
721 /*---------------------- strncasecmp ----------------------*/
723 #define STRNCASECMP(soname, fnname) \
724 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
725 ( const char* s1, const char* s2, SizeT nmax ); \
726 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
727 ( const char* s1, const char* s2, SizeT nmax ) \
729 extern int tolower(int); \
730 SizeT n = 0; \
731 while (True) { \
732 if (n >= nmax) return 0; \
733 if (*s1 == 0 && *s2 == 0) return 0; \
734 if (*s1 == 0) return -1; \
735 if (*s2 == 0) return 1; \
737 if (tolower(*(const UChar *)s1) \
738 < tolower(*(const UChar*)s2)) return -1; \
739 if (tolower(*(const UChar *)s1) \
740 > tolower(*(const UChar *)s2)) return 1; \
742 s1++; s2++; n++; \
746 #if defined(VGO_linux)
747 # if !defined(VGPV_arm_linux_android) \
748 && !defined(VGPV_x86_linux_android) \
749 && !defined(VGPV_mips32_linux_android) \
750 && !defined(VGPV_arm64_linux_android)
751 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
752 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
753 # endif
755 #elif defined(VGO_darwin)
756 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
757 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
759 #elif defined(VGO_solaris)
760 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
762 #endif
765 /*---------------------- strcasecmp_l ----------------------*/
767 #define STRCASECMP_L(soname, fnname) \
768 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
769 ( const char* s1, const char* s2, void* locale ); \
770 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
771 ( const char* s1, const char* s2, void* locale ) \
773 extern int tolower_l(int, void*) __attribute__((weak)); \
774 register UChar c1; \
775 register UChar c2; \
776 while (True) { \
777 c1 = tolower_l(*(const UChar *)s1, locale); \
778 c2 = tolower_l(*(const UChar *)s2, locale); \
779 if (c1 != c2) break; \
780 if (c1 == 0) break; \
781 s1++; s2++; \
783 if ((UChar)c1 < (UChar)c2) return -1; \
784 if ((UChar)c1 > (UChar)c2) return 1; \
785 return 0; \
788 #if defined(VGO_linux)
789 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
790 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
791 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
793 #elif defined(VGO_darwin)
794 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
796 #elif defined(VGO_solaris)
798 #endif
801 /*---------------------- strncasecmp_l ----------------------*/
803 #define STRNCASECMP_L(soname, fnname) \
804 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
805 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
806 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
807 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
809 extern int tolower_l(int, void*) __attribute__((weak)); \
810 SizeT n = 0; \
811 while (True) { \
812 if (n >= nmax) return 0; \
813 if (*s1 == 0 && *s2 == 0) return 0; \
814 if (*s1 == 0) return -1; \
815 if (*s2 == 0) return 1; \
817 if (tolower_l(*(const UChar *)s1, locale) \
818 < tolower_l(*(const UChar *)s2, locale)) return -1; \
819 if (tolower_l(*(const UChar *)s1, locale) \
820 > tolower_l(*(const UChar *)s2, locale)) return 1; \
822 s1++; s2++; n++; \
826 #if defined(VGO_linux)
827 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
828 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
829 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
831 #elif defined(VGO_darwin)
832 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
833 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
835 #elif defined(VGO_solaris)
837 #endif
840 /*---------------------- strcmp ----------------------*/
842 #define STRCMP(soname, fnname) \
843 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
844 ( const char* s1, const char* s2 ); \
845 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
846 ( const char* s1, const char* s2 ) \
848 register UChar c1; \
849 register UChar c2; \
850 while (True) { \
851 c1 = *(const UChar *)s1; \
852 c2 = *(const UChar *)s2; \
853 if (c1 != c2) break; \
854 if (c1 == 0) break; \
855 s1++; s2++; \
857 if ((UChar)c1 < (UChar)c2) return -1; \
858 if ((UChar)c1 > (UChar)c2) return 1; \
859 return 0; \
862 #if defined(VGO_linux)
863 STRCMP(VG_Z_LIBC_SONAME, strcmp)
864 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
865 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
866 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
867 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
868 STRCMP(VG_Z_LD64_SO_1, strcmp)
869 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
870 || defined(VGPV_mips32_linux_android)
871 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
872 # endif
874 #elif defined(VGO_darwin)
875 STRCMP(VG_Z_LIBC_SONAME, strcmp)
876 # if DARWIN_VERS >= DARWIN_10_9
877 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
878 # endif
880 #elif defined(VGO_solaris)
881 STRCMP(VG_Z_LIBC_SONAME, strcmp)
882 STRCMP(VG_Z_LD_SO_1, strcmp)
884 #endif
887 /*---------------------- memchr ----------------------*/
889 #define MEMCHR(soname, fnname) \
890 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
891 (const void *s, int c, SizeT n); \
892 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
893 (const void *s, int c, SizeT n) \
895 SizeT i; \
896 UChar c0 = (UChar)c; \
897 const UChar* p = s; \
898 for (i = 0; i < n; i++) \
899 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
900 return NULL; \
903 #if defined(VGO_linux)
904 MEMCHR(VG_Z_LIBC_SONAME, memchr)
905 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
907 #elif defined(VGO_darwin)
908 # if DARWIN_VERS == DARWIN_10_9
909 MEMCHR(VG_Z_DYLD, memchr)
910 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
911 # endif
912 # if DARWIN_VERS >= DARWIN_10_10
913 MEMCHR(VG_Z_DYLD, memchr)
914 /* _platform_memchr$VARIANT$Generic */
915 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
916 /* _platform_memchr$VARIANT$Haswell */
917 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
918 # endif
920 #elif defined(VGO_solaris)
921 MEMCHR(VG_Z_LIBC_SONAME, memchr)
923 #endif
926 /*---------------------- memrchr ----------------------*/
928 #define MEMRCHR(soname, fnname) \
929 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
930 (const void *s, int c, SizeT n); \
931 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
932 (const void *s, int c, SizeT n) \
934 SizeT i; \
935 UChar c0 = (UChar)c; \
936 const UChar* p = s; \
937 for (i = 0; i < n; i++) \
938 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
939 return NULL; \
942 #if defined(VGO_linux)
943 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
945 #elif defined(VGO_darwin)
946 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
947 //MEMRCHR(VG_Z_DYLD, memrchr)
949 #elif defined(VGO_solaris)
951 #endif
954 /*---------------------- memcpy ----------------------*/
956 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
957 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
958 ( void *dst, const void *src, SizeT len ); \
959 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
960 ( void *dst, const void *src, SizeT len ) \
962 RECORD_COPY(len); \
963 if (do_ol_check && is_overlap(dst, src, len, len)) \
964 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
966 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
967 const Addr WM = WS - 1; /* 7 or 3 */ \
969 if (len > 0) { \
970 if (dst < src || !is_overlap(dst, src, len, len)) { \
972 /* Copying backwards. */ \
973 SizeT n = len; \
974 Addr d = (Addr)dst; \
975 Addr s = (Addr)src; \
977 if (((s^d) & WM) == 0) { \
978 /* s and d have same UWord alignment. */ \
979 /* Pull up to a UWord boundary. */ \
980 while ((s & WM) != 0 && n >= 1) \
981 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
982 /* Copy UWords. */ \
983 while (n >= WS * 4) \
984 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
985 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
986 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
987 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
988 while (n >= WS) \
989 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
990 if (n == 0) \
991 return dst; \
993 if (((s|d) & 1) == 0) { \
994 /* Both are 16-aligned; copy what we can thusly. */ \
995 while (n >= 2) \
996 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
998 /* Copy leftovers, or everything if misaligned. */ \
999 while (n >= 1) \
1000 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1002 } else if (dst > src) { \
1004 SizeT n = len; \
1005 Addr d = ((Addr)dst) + n; \
1006 Addr s = ((Addr)src) + n; \
1008 /* Copying forwards. */ \
1009 if (((s^d) & WM) == 0) { \
1010 /* s and d have same UWord alignment. */ \
1011 /* Back down to a UWord boundary. */ \
1012 while ((s & WM) != 0 && n >= 1) \
1013 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1014 /* Copy UWords. */ \
1015 while (n >= WS * 4) \
1016 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1017 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1018 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1019 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1020 while (n >= WS) \
1021 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1022 if (n == 0) \
1023 return dst; \
1025 if (((s|d) & 1) == 0) { \
1026 /* Both are 16-aligned; copy what we can thusly. */ \
1027 while (n >= 2) \
1028 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1030 /* Copy leftovers, or everything if misaligned. */ \
1031 while (n >= 1) \
1032 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1037 return dst; \
1040 #define MEMMOVE(soname, fnname) \
1041 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1043 #define MEMCPY(soname, fnname) \
1044 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1046 #if defined(VGO_linux)
1047 /* For older memcpy we have to use memmove-like semantics and skip
1048 the overlap check; sigh; see #275284. */
1049 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1050 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1051 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1052 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1053 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1054 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_avx_unaligned_erms)
1055 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1056 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1057 /* icc9 blats these around all over the place. Not only in the main
1058 executable but various .so's. They are highly tuned and read
1059 memory beyond the source boundary (although work correctly and
1060 never go across page boundaries), so give errors when run
1061 natively, at least for misaligned source arg. Just intercepting
1062 in the exe only until we understand more about the problem. See
1063 http://bugs.kde.org/show_bug.cgi?id=139776
1065 MEMCPY(NONE, ZuintelZufastZumemcpy)
1067 #elif defined(VGO_darwin)
1068 # if DARWIN_VERS <= DARWIN_10_6
1069 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1070 # endif
1071 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1072 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1074 #elif defined(VGO_solaris)
1075 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1076 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
1077 MEMCPY(VG_Z_LD_SO_1, memcpy)
1079 #endif
1082 /*---------------------- memcmp ----------------------*/
1084 #define MEMCMP(soname, fnname) \
1085 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1086 ( const void *s1V, const void *s2V, SizeT n ); \
1087 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1088 ( const void *s1V, const void *s2V, SizeT n ) \
1090 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1091 const SizeT WM = WS - 1; /* 7 or 3 */ \
1092 Addr s1A = (Addr)s1V; \
1093 Addr s2A = (Addr)s2V; \
1095 if (((s1A | s2A) & WM) == 0) { \
1096 /* Both areas are word aligned. Skip over the */ \
1097 /* equal prefix as fast as possible. */ \
1098 while (n >= WS) { \
1099 UWord w1 = *(UWord*)s1A; \
1100 UWord w2 = *(UWord*)s2A; \
1101 if (w1 != w2) break; \
1102 s1A += WS; \
1103 s2A += WS; \
1104 n -= WS; \
1108 const UChar* s1 = (const UChar*) s1A; \
1109 const UChar* s2 = (const UChar*) s2A; \
1111 while (n != 0) { \
1112 UChar a0 = s1[0]; \
1113 UChar b0 = s2[0]; \
1114 s1 += 1; \
1115 s2 += 1; \
1116 int res = ((int)a0) - ((int)b0); \
1117 if (res != 0) \
1118 return res; \
1119 n -= 1; \
1121 return 0; \
1124 #if defined(VGO_linux)
1125 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1126 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1127 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1128 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1129 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1130 MEMCMP(VG_Z_LD_SO_1, bcmp)
1132 #elif defined(VGO_darwin)
1133 # if DARWIN_VERS >= DARWIN_10_9
1134 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1135 # endif
1137 #elif defined(VGO_solaris)
1138 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1139 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1140 MEMCMP(VG_Z_LD_SO_1, memcmp)
1142 #endif
1145 /*---------------------- stpcpy ----------------------*/
1147 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1148 DEST. (minor variant of strcpy) */
1149 #define STPCPY(soname, fnname) \
1150 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1151 ( char* dst, const char* src ); \
1152 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1153 ( char* dst, const char* src ) \
1155 const HChar* src_orig = src; \
1156 HChar* dst_orig = dst; \
1158 while (*src) *dst++ = *src++; \
1159 *dst = 0; \
1161 /* This checks for overlap after copying, unavoidable without */ \
1162 /* pre-counting length... should be ok */ \
1163 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1164 RECORD_COPY(srclen); \
1165 if (is_overlap(dst_orig, \
1166 src_orig, \
1167 (Addr)dst-(Addr)dst_orig+1, \
1168 srclen)) \
1169 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1171 return dst; \
1174 #if defined(VGO_linux)
1175 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1176 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1177 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1178 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1179 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1180 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1181 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1183 #elif defined(VGO_darwin)
1184 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1185 //STPCPY(VG_Z_DYLD, stpcpy)
1187 #elif defined(VGO_solaris)
1188 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1190 #endif
1193 /*---------------------- stpncpy ----------------------*/
1195 #define STPNCPY(soname, fnname) \
1196 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1197 ( char* dst, const char* src, SizeT n ); \
1198 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1199 ( char* dst, const char* src, SizeT n ) \
1201 const HChar* src_orig = src; \
1202 HChar* dst_str = dst; \
1203 SizeT m = 0; \
1205 while (m < n && *src) { m++; *dst++ = *src++; } \
1206 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1207 /* but only m+1 bytes of src if terminator was found */ \
1208 SizeT srclen = (m < n) ? m+1 : n; \
1209 RECORD_COPY(srclen); \
1210 if (is_overlap(dst_str, src_orig, n, srclen)) \
1211 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1212 dst_str = dst; \
1213 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1215 return dst_str; \
1218 #if defined(VGO_linux)
1219 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1220 #endif
1223 /*---------------------- memset ----------------------*/
1225 #define MEMSET(soname, fnname) \
1226 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1227 (void *s, Int c, SizeT n); \
1228 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1229 (void *s, Int c, SizeT n) \
1231 if (sizeof(void*) == 8) { \
1232 Addr a = (Addr)s; \
1233 ULong c8 = (c & 0xFF); \
1234 c8 = (c8 << 8) | c8; \
1235 c8 = (c8 << 16) | c8; \
1236 c8 = (c8 << 32) | c8; \
1237 while ((a & 7) != 0 && n >= 1) \
1238 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1239 while (n >= 32) \
1240 { *(ULong*)a = c8; a += 8; n -= 8; \
1241 *(ULong*)a = c8; a += 8; n -= 8; \
1242 *(ULong*)a = c8; a += 8; n -= 8; \
1243 *(ULong*)a = c8; a += 8; n -= 8; } \
1244 while (n >= 8) \
1245 { *(ULong*)a = c8; a += 8; n -= 8; } \
1246 while (n >= 1) \
1247 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1248 return s; \
1249 } else { \
1250 Addr a = (Addr)s; \
1251 UInt c4 = (c & 0xFF); \
1252 c4 = (c4 << 8) | c4; \
1253 c4 = (c4 << 16) | c4; \
1254 while ((a & 3) != 0 && n >= 1) \
1255 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1256 while (n >= 16) \
1257 { *(UInt*)a = c4; a += 4; n -= 4; \
1258 *(UInt*)a = c4; a += 4; n -= 4; \
1259 *(UInt*)a = c4; a += 4; n -= 4; \
1260 *(UInt*)a = c4; a += 4; n -= 4; } \
1261 while (n >= 4) \
1262 { *(UInt*)a = c4; a += 4; n -= 4; } \
1263 while (n >= 1) \
1264 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1265 return s; \
1269 #if defined(VGO_linux)
1270 MEMSET(VG_Z_LIBC_SONAME, memset)
1272 #elif defined(VGO_darwin)
1273 //MEMSET(VG_Z_LIBC_SONAME, memset)
1274 //MEMSET(VG_Z_DYLD, memset)
1275 MEMSET(VG_Z_LIBC_SONAME, memset)
1277 #elif defined(VGO_solaris)
1278 MEMSET(VG_Z_LIBC_SONAME, memset)
1279 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1281 #endif
1284 /*---------------------- memmove ----------------------*/
1286 /* memmove -- use the MEMMOVE defn above. */
1288 #if defined(VGO_linux)
1289 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1290 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1291 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1292 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1293 to call memcpy. */
1294 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1296 #elif defined(VGO_darwin)
1297 # if DARWIN_VERS <= DARWIN_10_6
1298 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1299 # endif
1300 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1301 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1302 # if DARWIN_VERS >= DARWIN_10_9
1303 /* _platform_memmove$VARIANT$Ivybridge */
1304 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1305 # endif
1307 #elif defined(VGO_solaris)
1308 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1309 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1310 MEMMOVE(VG_Z_LD_SO_1, memmove)
1312 #endif
1315 /*---------------------- bcopy ----------------------*/
1317 #define BCOPY(soname, fnname) \
1318 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1319 (const void *srcV, void *dstV, SizeT n); \
1320 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1321 (const void *srcV, void *dstV, SizeT n) \
1323 RECORD_COPY(n); \
1324 SizeT i; \
1325 HChar* dst = dstV; \
1326 const HChar* src = srcV; \
1327 if (dst < src) { \
1328 for (i = 0; i < n; i++) \
1329 dst[i] = src[i]; \
1331 else \
1332 if (dst > src) { \
1333 for (i = 0; i < n; i++) \
1334 dst[n-i-1] = src[n-i-1]; \
1338 #if defined(VGO_linux)
1339 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1341 #elif defined(VGO_darwin)
1342 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1343 //BCOPY(VG_Z_DYLD, bcopy)
1345 #elif defined(VGO_darwin)
1346 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1348 #endif
1351 /*-------------------- memmove_chk --------------------*/
1353 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1354 There is no specific part of glibc that this is copied from. */
1355 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1356 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1357 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1358 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1359 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1361 RECORD_COPY(n); \
1362 SizeT i; \
1363 HChar* dst = dstV; \
1364 const HChar* src = srcV; \
1365 if (destlen < n) \
1366 goto badness; \
1367 if (dst < src) { \
1368 for (i = 0; i < n; i++) \
1369 dst[i] = src[i]; \
1371 else \
1372 if (dst > src) { \
1373 for (i = 0; i < n; i++) \
1374 dst[n-i-1] = src[n-i-1]; \
1376 return dst; \
1377 badness: \
1378 VALGRIND_PRINTF_BACKTRACE( \
1379 "*** memmove_chk: buffer overflow detected ***: " \
1380 "program terminated\n"); \
1381 my_exit(1); \
1382 /*NOTREACHED*/ \
1383 return NULL; \
1386 #if defined(VGO_linux)
1387 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1389 #elif defined(VGO_darwin)
1391 #elif defined(VGO_solaris)
1393 #endif
1396 /*-------------------- strchrnul --------------------*/
1398 /* Find the first occurrence of C in S or the final NUL byte. */
1399 #define GLIBC232_STRCHRNUL(soname, fnname) \
1400 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1401 (const char* s, int c_in); \
1402 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1403 (const char* s, int c_in) \
1405 HChar c = (HChar) c_in; \
1406 const HChar* char_ptr = s; \
1407 while (1) { \
1408 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1409 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1410 char_ptr++; \
1414 #if defined(VGO_linux)
1415 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1417 #elif defined(VGO_darwin)
1419 #elif defined(VGO_solaris)
1421 #endif
1424 /*---------------------- rawmemchr ----------------------*/
1426 /* Find the first occurrence of C in S. */
1427 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1428 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1429 (const void* s, int c_in); \
1430 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1431 (const void* s, int c_in) \
1433 UChar c = (UChar) c_in; \
1434 const UChar* char_ptr = s; \
1435 while (1) { \
1436 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1437 char_ptr++; \
1441 #if defined (VGO_linux)
1442 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1443 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1445 #elif defined(VGO_darwin)
1447 #elif defined(VGO_solaris)
1449 #endif
1452 /*---------------------- strcpy_chk ----------------------*/
1454 /* glibc variant of strcpy that checks the dest is big enough.
1455 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1456 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1457 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1458 (char* dst, const char* src, SizeT len); \
1459 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1460 (char* dst, const char* src, SizeT len) \
1462 FOR_COPY(const HChar* src_orig = src); \
1463 HChar* ret = dst; \
1464 if (! len) \
1465 goto badness; \
1466 while ((*dst++ = *src++) != '\0') \
1467 if (--len == 0) \
1468 goto badness; \
1469 RECORD_COPY((Addr)src-(Addr)src_orig); \
1470 return ret; \
1471 badness: \
1472 VALGRIND_PRINTF_BACKTRACE( \
1473 "*** strcpy_chk: buffer overflow detected ***: " \
1474 "program terminated\n"); \
1475 my_exit(1); \
1476 /*NOTREACHED*/ \
1477 return NULL; \
1480 #if defined(VGO_linux)
1481 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1483 #elif defined(VGO_darwin)
1485 #elif defined(VGO_solaris)
1487 #endif
1490 /*---------------------- stpcpy_chk ----------------------*/
1492 /* glibc variant of stpcpy that checks the dest is big enough.
1493 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1494 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1495 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1496 (char* dst, const char* src, SizeT len); \
1497 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1498 (char* dst, const char* src, SizeT len) \
1500 FOR_COPY(const HChar* src_orig = src); \
1501 if (! len) \
1502 goto badness; \
1503 while ((*dst++ = *src++) != '\0') \
1504 if (--len == 0) \
1505 goto badness; \
1506 RECORD_COPY((Addr)src-(Addr)src_orig); \
1507 return dst - 1; \
1508 badness: \
1509 VALGRIND_PRINTF_BACKTRACE( \
1510 "*** stpcpy_chk: buffer overflow detected ***: " \
1511 "program terminated\n"); \
1512 my_exit(1); \
1513 /*NOTREACHED*/ \
1514 return NULL; \
1517 #if defined(VGO_linux)
1518 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1520 #elif defined(VGO_darwin)
1522 #elif defined(VGO_solaris)
1524 #endif
1527 /*---------------------- mempcpy ----------------------*/
1529 /* mempcpy */
1530 #define GLIBC25_MEMPCPY(soname, fnname) \
1531 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1532 ( void *dst, const void *src, SizeT len ); \
1533 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1534 ( void *dst, const void *src, SizeT len ) \
1536 RECORD_COPY(len); \
1537 SizeT len_saved = len; \
1539 if (len == 0) \
1540 return dst; \
1542 if (is_overlap(dst, src, len, len)) \
1543 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1545 if ( dst > src ) { \
1546 register HChar *d = (char *)dst + len - 1; \
1547 register const HChar *s = (const char *)src + len - 1; \
1548 while ( len-- ) { \
1549 *d-- = *s--; \
1551 } else if ( dst < src ) { \
1552 register HChar *d = dst; \
1553 register const HChar *s = src; \
1554 while ( len-- ) { \
1555 *d++ = *s++; \
1558 return (void*)( ((char*)dst) + len_saved ); \
1561 #if defined(VGO_linux)
1562 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1563 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1564 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1565 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1566 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1568 #elif defined(VGO_darwin)
1569 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1571 #elif defined(VGO_solaris)
1573 #endif
1576 /*-------------------- memcpy_chk --------------------*/
1578 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1579 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1580 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1581 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1582 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1584 register HChar *d; \
1585 register const HChar *s; \
1586 if (dstlen < len) \
1587 goto badness; \
1588 RECORD_COPY(len); \
1589 if (len == 0) \
1590 return dst; \
1591 if (is_overlap(dst, src, len, len)) \
1592 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1593 if ( dst > src ) { \
1594 d = (HChar *)dst + len - 1; \
1595 s = (const HChar *)src + len - 1; \
1596 while ( len-- ) { \
1597 *d-- = *s--; \
1599 } else if ( dst < src ) { \
1600 d = (HChar *)dst; \
1601 s = (const HChar *)src; \
1602 while ( len-- ) { \
1603 *d++ = *s++; \
1606 return dst; \
1607 badness: \
1608 VALGRIND_PRINTF_BACKTRACE( \
1609 "*** memcpy_chk: buffer overflow detected ***: " \
1610 "program terminated\n"); \
1611 my_exit(1); \
1612 /*NOTREACHED*/ \
1613 return NULL; \
1616 #if defined(VGO_linux)
1617 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1619 #elif defined(VGO_darwin)
1621 #elif defined(VGO_solaris)
1623 #endif
1626 /*---------------------- strstr ----------------------*/
1628 #define STRSTR(soname, fnname) \
1629 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1630 (const char* haystack, const char* needle); \
1631 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1632 (const char* haystack, const char* needle) \
1634 const HChar* h = haystack; \
1635 const HChar* n = needle; \
1637 /* find the length of n, not including terminating zero */ \
1638 UWord nlen = 0; \
1639 while (n[nlen]) nlen++; \
1641 /* if n is the empty string, match immediately. */ \
1642 if (nlen == 0) return CONST_CAST(HChar *,h); \
1644 /* assert(nlen >= 1); */ \
1645 HChar n0 = n[0]; \
1647 while (1) { \
1648 const HChar hh = *h; \
1649 if (hh == 0) return NULL; \
1650 if (hh != n0) { h++; continue; } \
1652 UWord i; \
1653 for (i = 0; i < nlen; i++) { \
1654 if (n[i] != h[i]) \
1655 break; \
1657 /* assert(i >= 0 && i <= nlen); */ \
1658 if (i == nlen) \
1659 return CONST_CAST(HChar *,h); \
1661 h++; \
1665 #if defined(VGO_linux)
1666 STRSTR(VG_Z_LIBC_SONAME, strstr)
1667 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1668 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1670 #elif defined(VGO_darwin)
1672 #elif defined(VGO_solaris)
1673 STRSTR(VG_Z_LIBC_SONAME, strstr)
1675 #endif
1678 /*---------------------- strpbrk ----------------------*/
1680 #define STRPBRK(soname, fnname) \
1681 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1682 (const char* sV, const char* acceptV); \
1683 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1684 (const char* sV, const char* acceptV) \
1686 const HChar* s = sV; \
1687 const HChar* accept = acceptV; \
1689 /* find the length of 'accept', not including terminating zero */ \
1690 UWord nacc = 0; \
1691 while (accept[nacc]) nacc++; \
1693 /* if n is the empty string, fail immediately. */ \
1694 if (nacc == 0) return NULL; \
1696 /* assert(nacc >= 1); */ \
1697 while (1) { \
1698 UWord i; \
1699 HChar sc = *s; \
1700 if (sc == 0) \
1701 break; \
1702 for (i = 0; i < nacc; i++) { \
1703 if (sc == accept[i]) \
1704 return CONST_CAST(HChar *,s); \
1706 s++; \
1709 return NULL; \
1712 #if defined(VGO_linux)
1713 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1715 #elif defined(VGO_darwin)
1717 #elif defined(VGO_solaris)
1718 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1720 #endif
1723 /*---------------------- strcspn ----------------------*/
1725 #define STRCSPN(soname, fnname) \
1726 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1727 (const char* sV, const char* rejectV); \
1728 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1729 (const char* sV, const char* rejectV) \
1731 const HChar* s = sV; \
1732 const HChar* reject = rejectV; \
1734 /* find the length of 'reject', not including terminating zero */ \
1735 UWord nrej = 0; \
1736 while (reject[nrej]) nrej++; \
1738 UWord len = 0; \
1739 while (1) { \
1740 UWord i; \
1741 HChar sc = *s; \
1742 if (sc == 0) \
1743 break; \
1744 for (i = 0; i < nrej; i++) { \
1745 if (sc == reject[i]) \
1746 break; \
1748 /* assert(i >= 0 && i <= nrej); */ \
1749 if (i < nrej) \
1750 break; \
1751 s++; \
1752 len++; \
1755 return len; \
1758 #if defined(VGO_linux)
1759 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1760 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1762 #elif defined(VGO_darwin)
1764 #elif defined(VGO_solaris)
1765 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1767 #endif
1770 /*---------------------- strspn ----------------------*/
1772 #define STRSPN(soname, fnname) \
1773 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1774 (const char* sV, const char* acceptV); \
1775 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1776 (const char* sV, const char* acceptV) \
1778 const UChar* s = (const UChar *)sV; \
1779 const UChar* accept = (const UChar *)acceptV; \
1781 /* find the length of 'accept', not including terminating zero */ \
1782 UWord nacc = 0; \
1783 while (accept[nacc]) nacc++; \
1784 if (nacc == 0) return 0; \
1786 UWord len = 0; \
1787 while (1) { \
1788 UWord i; \
1789 UChar sc = *s; \
1790 if (sc == 0) \
1791 break; \
1792 for (i = 0; i < nacc; i++) { \
1793 if (sc == accept[i]) \
1794 break; \
1796 /* assert(i >= 0 && i <= nacc); */ \
1797 if (i == nacc) \
1798 break; \
1799 s++; \
1800 len++; \
1803 return len; \
1806 #if defined(VGO_linux)
1807 STRSPN(VG_Z_LIBC_SONAME, strspn)
1809 #elif defined(VGO_darwin)
1811 #elif defined(VGO_solaris)
1812 STRSPN(VG_Z_LIBC_SONAME, strspn)
1814 #endif
1817 /*---------------------- strcasestr ----------------------*/
1819 #define STRCASESTR(soname, fnname) \
1820 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1821 (const char* haystack, const char* needle); \
1822 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1823 (const char* haystack, const char* needle) \
1825 extern int tolower(int); \
1826 const HChar* h = haystack; \
1827 const HChar* n = needle; \
1829 /* find the length of n, not including terminating zero */ \
1830 UWord nlen = 0; \
1831 while (n[nlen]) nlen++; \
1833 /* if n is the empty string, match immediately. */ \
1834 if (nlen == 0) return CONST_CAST(HChar *,h); \
1836 /* assert(nlen >= 1); */ \
1837 UChar n0 = tolower(n[0]); \
1839 while (1) { \
1840 UChar hh = tolower(*h); \
1841 if (hh == 0) return NULL; \
1842 if (hh != n0) { h++; continue; } \
1844 UWord i; \
1845 for (i = 0; i < nlen; i++) { \
1846 if (tolower(n[i]) != tolower(h[i])) \
1847 break; \
1849 /* assert(i >= 0 && i <= nlen); */ \
1850 if (i == nlen) \
1851 return CONST_CAST(HChar *,h); \
1853 h++; \
1857 #if defined(VGO_linux)
1858 # if !defined(VGPV_arm_linux_android) \
1859 && !defined(VGPV_x86_linux_android) \
1860 && !defined(VGPV_mips32_linux_android) \
1861 && !defined(VGPV_arm64_linux_android)
1862 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1863 # endif
1865 #elif defined(VGO_darwin)
1867 #elif defined(VGO_solaris)
1868 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1870 #endif
1873 /*---------------------- wcslen ----------------------*/
1875 // This is a wchar_t equivalent to strlen. Unfortunately
1876 // we don't have wchar_t available here, but it looks like
1877 // a 32 bit int on Linux. I don't know if that is also
1878 // valid on MacOSX.
1880 #define WCSLEN(soname, fnname) \
1881 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1882 ( const Int* str ); \
1883 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1884 ( const Int* str ) \
1886 SizeT i = 0; \
1887 while (str[i] != 0) i++; \
1888 return i; \
1891 #if defined(VGO_linux)
1892 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1894 #elif defined(VGO_darwin)
1896 #elif defined(VGO_solaris)
1897 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1899 #endif
1901 /*---------------------- wcsnlen ----------------------*/
1903 #define WCSNLEN(soname, fnname) \
1904 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
1905 ( const Int *s, SizeT n ); \
1906 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
1907 ( const Int *s, SizeT n ) \
1909 SizeT i = 0; \
1910 const Int* p = s; \
1911 while (i < n && *p != 0) { \
1912 i++; \
1913 p++; \
1915 return i; \
1918 #if defined(VGO_linux)
1919 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
1920 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
1921 #endif
1923 /*---------------------- wcscmp ----------------------*/
1925 // This is a wchar_t equivalent to strcmp. We don't
1926 // have wchar_t available here, but in the GNU C Library
1927 // wchar_t is always 32 bits wide and wcscmp uses signed
1928 // comparison, not unsigned as in strcmp function.
1930 #define WCSCMP(soname, fnname) \
1931 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1932 ( const Int* s1, const Int* s2 ); \
1933 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1934 ( const Int* s1, const Int* s2 ) \
1936 register Int c1; \
1937 register Int c2; \
1938 while (True) { \
1939 c1 = *s1; \
1940 c2 = *s2; \
1941 if (c1 != c2) break; \
1942 if (c1 == 0) break; \
1943 s1++; s2++; \
1945 if (c1 < c2) return -1; \
1946 if (c1 > c2) return 1; \
1947 return 0; \
1950 #if defined(VGO_linux)
1951 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
1952 #endif
1954 /*---------------------- wcsncmp ----------------------*/
1956 // This is a wchar_t equivalent to strncmp. We don't
1957 // have wchar_t available here, but in the GNU C Library
1958 // wchar_t is always 32 bits wide and wcsncmp uses signed
1959 // comparison, not unsigned as in strncmp function.
1961 #define WCSNCMP(soname, fnname) \
1962 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
1963 ( const Int* s1, const Int* s2, SizeT nmax ); \
1964 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
1965 ( const Int* s1, const Int* s2, SizeT nmax ) \
1967 SizeT n = 0; \
1968 while (True) { \
1969 if (n >= nmax) return 0; \
1970 if (*s1 == 0 && *s2 == 0) return 0; \
1971 if (*s1 == 0) return -1; \
1972 if (*s2 == 0) return 1; \
1974 if (*s1 < *s2) return -1; \
1975 if (*s1 > *s2) return 1; \
1977 s1++; s2++; n++; \
1980 #if defined(VGO_linux)
1981 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
1982 #endif
1984 /*---------------------- wcscpy ----------------------*/
1986 // This is a wchar_t equivalent to strcpy. We don't
1987 // have wchar_t available here, but in the GNU C Library
1988 // wchar_t is always 32 bits wide.
1990 #define WCSCPY(soname, fnname) \
1991 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1992 ( Int* dst, const Int* src ); \
1993 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1994 ( Int* dst, const Int* src ) \
1996 const Int* src_orig = src; \
1997 Int* dst_orig = dst; \
1999 while (*src) *dst++ = *src++; \
2000 *dst = 0; \
2002 /* This checks for overlap after copying, unavoidable without */ \
2003 /* pre-counting length... should be ok */ \
2004 /* +4 because sizeof(wchar_t) == 4 */ \
2005 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2006 RECORD_COPY(srclen); \
2007 if (is_overlap(dst_orig, \
2008 src_orig, \
2009 /* +4 because sizeof(wchar_t) == 4 */ \
2010 (Addr)dst-(Addr)dst_orig+4, \
2011 srclen)) \
2012 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2014 return dst_orig; \
2017 #if defined(VGO_linux) || defined(VGO_solaris)
2018 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2019 #endif
2022 /*---------------------- wcschr ----------------------*/
2024 // This is a wchar_t equivalent to strchr. We don't
2025 // have wchar_t available here, but in the GNU C Library
2026 // wchar_t is always 32 bits wide.
2028 #define WCSCHR(soname, fnname) \
2029 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2030 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2032 const Int* p = s; \
2033 while (True) { \
2034 if (*p == c) return CONST_CAST(Int *,p); \
2035 if (*p == 0) return NULL; \
2036 p++; \
2040 #if defined(VGO_linux)
2041 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2042 #endif
2043 /*---------------------- wcsrchr ----------------------*/
2045 // This is a wchar_t equivalent to strrchr. We don't
2046 // have wchar_t available here, but in the GNU C Library
2047 // wchar_t is always 32 bits wide.
2049 #define WCSRCHR(soname, fnname) \
2050 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2051 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2053 const Int* p = s; \
2054 const Int* last = NULL; \
2055 while (True) { \
2056 if (*p == c) last = p; \
2057 if (*p == 0) return CONST_CAST(Int *,last); \
2058 p++; \
2062 #if defined(VGO_linux)
2063 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2064 #endif
2066 /*---------------------- wmemchr ----------------------*/
2068 // This is a wchar_t equivalent to memchr. We don't
2069 // have wchar_t available here, but in the GNU C Library
2070 // wchar_t is always 32 bits wide.
2072 #define WMEMCHR(soname, fnname) \
2073 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2074 (const Int *s, Int c, SizeT n); \
2075 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2076 (const Int *s, Int c, SizeT n) \
2078 SizeT i; \
2079 const Int* p = s; \
2080 for (i = 0; i < n; i++) { \
2081 if (*p == c) return CONST_CAST(Int *,p); \
2082 p++; \
2084 return NULL; \
2087 #if defined(VGO_linux)
2088 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2089 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2090 #endif
2092 /*------------------------------------------------------------*/
2093 /*--- Improve definedness checking of process environment ---*/
2094 /*------------------------------------------------------------*/
2096 #if defined(VGO_linux)
2098 /* If these wind up getting generated via a macro, so that multiple
2099 versions of each function exist (as above), use the _EZU variants
2100 to assign equivalance class tags. */
2102 /*---------------------- putenv ----------------------*/
2104 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2105 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2107 OrigFn fn;
2108 Word result;
2109 const HChar* p = string;
2110 VALGRIND_GET_ORIG_FN(fn);
2111 /* Now by walking over the string we magically produce
2112 traces when hitting undefined memory. */
2113 if (p)
2114 while (*p++)
2115 __asm__ __volatile__("" ::: "memory");
2116 CALL_FN_W_W(result, fn, string);
2117 return result;
2121 /*---------------------- unsetenv ----------------------*/
2123 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2124 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2126 OrigFn fn;
2127 Word result;
2128 const HChar* p = name;
2129 VALGRIND_GET_ORIG_FN(fn);
2130 /* Now by walking over the string we magically produce
2131 traces when hitting undefined memory. */
2132 if (p)
2133 while (*p++)
2134 __asm__ __volatile__("" ::: "memory");
2135 CALL_FN_W_W(result, fn, name);
2136 return result;
2140 /*---------------------- setenv ----------------------*/
2142 /* setenv */
2143 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2144 (const char* name, const char* value, int overwrite);
2145 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2146 (const char* name, const char* value, int overwrite)
2148 OrigFn fn;
2149 Word result;
2150 const HChar* p;
2151 VALGRIND_GET_ORIG_FN(fn);
2152 /* Now by walking over the string we magically produce
2153 traces when hitting undefined memory. */
2154 if (name)
2155 for (p = name; *p; p++)
2156 __asm__ __volatile__("" ::: "memory");
2157 if (value)
2158 for (p = value; *p; p++)
2159 __asm__ __volatile__("" ::: "memory");
2160 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2161 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2162 return result;
2165 #endif /* defined(VGO_linux) */
2167 /*--------------------------------------------------------------------*/
2168 /*--- end ---*/
2169 /*--------------------------------------------------------------------*/