drd: Add support for C11 thrd_create()
[valgrind.git] / shared / vg_replace_strmem.c
blob10195b3348533a588f44b62cb151f066e0be3fa0
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
107 20470 WMEMCMP
110 #if defined(VGO_solaris)
112 Detour functions in the libc and the runtime linker. If a function isn't
113 much optimized (and no overlap checking is necessary) then redir the
114 function only in the libc. This way we can keep stacktraces in the tests
115 consistent.
117 #endif
120 /* Figure out if [dst .. dst+dstlen-1] overlaps with
121 [src .. src+srclen-1].
122 We assume that the address ranges do not wrap around
123 (which is safe since on Linux addresses >= 0xC0000000
124 are not accessible and the program will segfault in this
125 circumstance, presumably).
127 static inline
128 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
130 Addr loS, hiS, loD, hiD;
132 if (dstlen == 0 || srclen == 0)
133 return False;
135 loS = (Addr)src;
136 loD = (Addr)dst;
137 hiS = loS + srclen - 1;
138 hiD = loD + dstlen - 1;
140 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
141 if (loS < loD) {
142 return !(hiS < loD);
144 else if (loD < loS) {
145 return !(hiD < loS);
147 else {
148 /* They start at same place. Since we know neither of them has
149 zero length, they must overlap. */
150 return True;
155 /* Call here to exit if we can't continue. On Android we can't call
156 _exit for some reason, so we have to blunt-instrument it. */
157 __attribute__ ((__noreturn__))
158 static inline void my_exit ( int x )
160 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
161 || defined(VGPV_arm64_linux_android)
162 __asm__ __volatile__(".word 0xFFFFFFFF");
163 while (1) {}
164 # elif defined(VGPV_x86_linux_android)
165 __asm__ __volatile__("ud2");
166 while (1) {}
167 # else
168 extern __attribute__ ((__noreturn__)) void _exit(int status);
169 _exit(x);
170 # endif
174 // This is a macro rather than a function because we don't want to have an
175 // extra function in the stack trace.
176 #ifndef RECORD_OVERLAP_ERROR
177 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
178 #endif
180 // Used for tools that record bulk copies: memcpy, strcpy, etc.
181 #ifndef RECORD_COPY
182 #define RECORD_COPY(len) do { } while (0)
183 #define FOR_COPY(x)
184 #else
185 #define FOR_COPY(x) x
186 #endif
188 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
189 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
190 #endif
193 /*---------------------- strrchr ----------------------*/
195 #define STRRCHR(soname, fnname) \
196 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
197 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
199 HChar ch = (HChar)c; \
200 const HChar* p = s; \
201 const HChar* last = NULL; \
202 while (True) { \
203 if (*p == ch) last = p; \
204 if (*p == 0) return CONST_CAST(HChar *,last); \
205 p++; \
209 // Apparently rindex() is the same thing as strrchr()
210 #if defined(VGO_linux)
211 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
212 STRRCHR(VG_Z_LIBC_SONAME, rindex)
213 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
214 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
215 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
216 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
217 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
218 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
219 || defined(VGPV_mips32_linux_android)
220 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
221 #endif
223 #elif defined(VGO_freebsd)
224 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
225 STRRCHR(VG_Z_LIBC_SONAME, rindex)
226 STRRCHR(VG_Z_LD_ELF_SO_1, strrchr)
227 STRRCHR(VG_Z_LD_ELF32_SO_1, strrchr)
229 #elif defined(VGO_darwin)
230 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
231 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
232 //STRRCHR(VG_Z_DYLD, strrchr)
233 //STRRCHR(VG_Z_DYLD, rindex)
234 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
235 # if DARWIN_VERS >= DARWIN_10_9
236 STRRCHR(libsystemZucZddylib, strrchr)
237 # endif
239 #elif defined(VGO_solaris)
240 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
241 STRRCHR(VG_Z_LIBC_SONAME, rindex)
242 STRRCHR(VG_Z_LD_SO_1, strrchr)
244 #endif
247 /*---------------------- strchr ----------------------*/
249 #define STRCHR(soname, fnname) \
250 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
251 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
253 HChar ch = (HChar)c ; \
254 const HChar* p = s; \
255 while (True) { \
256 if (*p == ch) return CONST_CAST(HChar *,p); \
257 if (*p == 0) return NULL; \
258 p++; \
262 // Apparently index() is the same thing as strchr()
263 #if defined(VGO_linux)
264 STRCHR(VG_Z_LIBC_SONAME, strchr)
265 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
266 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
267 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
268 STRCHR(VG_Z_LIBC_SONAME, index)
269 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
270 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
271 STRCHR(VG_Z_LD_LINUX_SO_2, index)
272 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
273 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
274 # endif
276 #if defined(VGPV_mips32_linux_android)
277 STRCHR(NONE, __dl_strchr)
278 #endif
280 #elif defined(VGO_freebsd)
281 STRCHR(VG_Z_LIBC_SONAME, strchr)
282 STRCHR(VG_Z_LIBC_SONAME, index)
283 STRCHR(VG_Z_LD_ELF_SO_1, strchr)
284 STRCHR(VG_Z_LD_ELF32_SO_1, strchr)
286 #elif defined(VGO_darwin)
287 STRCHR(VG_Z_LIBC_SONAME, strchr)
288 # if DARWIN_VERS == DARWIN_10_9
289 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
290 # endif
291 # if DARWIN_VERS >= DARWIN_10_10
292 /* _platform_strchr$VARIANT$Generic */
293 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
294 /* _platform_strchr$VARIANT$Haswell */
295 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
296 # endif
297 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Base)
299 #elif defined(VGO_solaris)
300 STRCHR(VG_Z_LIBC_SONAME, strchr)
301 STRCHR(VG_Z_LIBC_SONAME, index)
302 STRCHR(VG_Z_LD_SO_1, strchr)
304 #endif
307 /*---------------------- strcat ----------------------*/
309 #define STRCAT(soname, fnname) \
310 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
311 ( char* dst, const char* src ); \
312 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
313 ( char* dst, const char* src ) \
315 const HChar* src_orig = src; \
316 HChar* dst_orig = dst; \
317 while (*dst) dst++; \
318 while (*src) *dst++ = *src++; \
319 *dst = 0; \
321 /* This is a bit redundant, I think; any overlap and the strcat will */ \
322 /* go forever... or until a seg fault occurs. */ \
323 if (is_overlap(dst_orig, \
324 src_orig, \
325 (Addr)dst-(Addr)dst_orig+1, \
326 (Addr)src-(Addr)src_orig+1)) \
327 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
329 return dst_orig; \
332 #if defined(VGO_linux)
333 STRCAT(VG_Z_LIBC_SONAME, strcat)
334 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
336 #elif defined(VGO_freebsd)
337 STRCAT(VG_Z_LIBC_SONAME, strcat)
338 STRCAT(VG_Z_LD_ELF_SO_1, strcat)
339 STRCAT(VG_Z_LD_ELF32_SO_1, strcat)
341 #elif defined(VGO_darwin)
342 //STRCAT(VG_Z_LIBC_SONAME, strcat)
344 #elif defined(VGO_solaris)
345 STRCAT(VG_Z_LIBC_SONAME, strcat)
346 STRCAT(VG_Z_LD_SO_1, strcat)
348 #endif
351 /*---------------------- strncat ----------------------*/
353 #define STRNCAT(soname, fnname) \
354 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
355 ( char* dst, const char* src, SizeT n ); \
356 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
357 ( char* dst, const char* src, SizeT n ) \
359 const HChar* src_orig = src; \
360 HChar* dst_orig = dst; \
361 SizeT m = 0; \
363 while (*dst) dst++; \
364 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
365 *dst = 0; /* always add null */ \
367 /* This checks for overlap after copying, unavoidable without */ \
368 /* pre-counting lengths... should be ok */ \
369 if (is_overlap(dst_orig, \
370 src_orig, \
371 (Addr)dst-(Addr)dst_orig+1, \
372 (Addr)src-(Addr)src_orig+1)) \
373 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
375 return dst_orig; \
378 #if defined(VGO_linux)
379 STRNCAT(VG_Z_LIBC_SONAME, strncat)
381 #elif defined(VGO_freebsd)
382 STRNCAT(VG_Z_LIBC_SONAME, strncat)
384 #elif defined(VGO_darwin)
385 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
386 //STRNCAT(VG_Z_DYLD, strncat)
388 #elif defined(VGO_solaris)
389 STRNCAT(VG_Z_LIBC_SONAME, strncat)
391 #endif
394 /*---------------------- strlcat ----------------------*/
396 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
397 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
398 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
399 Truncation occurred if retval >= n.
401 #define STRLCAT(soname, fnname) \
402 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
403 ( char* dst, const char* src, SizeT n ); \
404 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
405 ( char* dst, const char* src, SizeT n ) \
407 const HChar* src_orig = src; \
408 HChar* dst_orig = dst; \
409 SizeT m = 0; \
411 while (m < n && *dst) { m++; dst++; } \
412 if (m < n) { \
413 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
414 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
415 *dst = 0; \
416 } else { \
417 /* No space to copy anything to dst. m == n */ \
419 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
420 while (*src) { m++; src++; } \
421 /* This checks for overlap after copying, unavoidable without */ \
422 /* pre-counting lengths... should be ok */ \
423 if (is_overlap(dst_orig, \
424 src_orig, \
425 (Addr)dst-(Addr)dst_orig+1, \
426 (Addr)src-(Addr)src_orig+1)) \
427 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
429 return m; \
432 #if defined(VGO_linux)
434 #elif defined(VGO_freebsd)
435 STRLCAT(VG_Z_LD_ELF_SO_1, strlcat)
436 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
437 STRLCAT(VG_Z_LD_ELF32_SO_1, strlcat)
439 #elif defined(VGO_darwin)
440 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
441 //STRLCAT(VG_Z_DYLD, strlcat)
442 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
444 #elif defined(VGO_solaris)
445 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
447 #endif
450 /*---------------------- strnlen ----------------------*/
452 #define STRNLEN(soname, fnname) \
453 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
454 ( const char* str, SizeT n ); \
455 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
456 ( const char* str, SizeT n ) \
458 SizeT i = 0; \
459 while (i < n && str[i] != 0) i++; \
460 return i; \
463 #if defined(VGO_linux)
464 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
465 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
467 #elif defined(VGO_freebsd)
469 STRNLEN(VG_Z_LIBC_SONAME, srtnlen)
471 #elif defined(VGO_darwin)
472 # if DARWIN_VERS == DARWIN_10_9
473 STRNLEN(libsystemZucZddylib, strnlen)
474 # endif
476 #elif defined(VGO_solaris)
477 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
479 #endif
482 /*---------------------- strlen ----------------------*/
484 // Note that this replacement often doesn't get used because gcc inlines
485 // calls to strlen() with its own built-in version. This can be very
486 // confusing if you aren't expecting it. Other small functions in
487 // this file may also be inline by gcc.
489 #define STRLEN(soname, fnname) \
490 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
491 ( const char* str ); \
492 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
493 ( const char* str ) \
495 SizeT i = 0; \
496 while (str[i] != 0) i++; \
497 return i; \
500 #if defined(VGO_linux)
501 STRLEN(VG_Z_LIBC_SONAME, strlen)
502 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
503 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
504 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
505 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
506 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
507 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
508 # if defined(VGPV_arm_linux_android) \
509 || defined(VGPV_x86_linux_android) \
510 || defined(VGPV_mips32_linux_android)
511 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
512 # endif
514 #elif defined(VGO_freebsd)
515 STRLEN(VG_Z_LIBC_SONAME, strlen)
516 STRLEN(VG_Z_LD_ELF_SO_1, strlen)
517 STRLEN(VG_Z_LD_ELF32_SO_1, strlen)
519 #elif defined(VGO_darwin)
520 STRLEN(VG_Z_LIBC_SONAME, strlen)
521 # if DARWIN_VERS >= DARWIN_10_9
522 STRLEN(libsystemZucZddylib, strlen)
523 # endif
525 #elif defined(VGO_solaris)
526 STRLEN(VG_Z_LIBC_SONAME, strlen)
527 STRLEN(VG_Z_LD_SO_1, strlen)
529 #endif
532 /*---------------------- strcpy ----------------------*/
534 #define STRCPY(soname, fnname) \
535 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
536 ( char* dst, const char* src ); \
537 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
538 ( char* dst, const char* src ) \
540 const HChar* src_orig = src; \
541 HChar* dst_orig = dst; \
543 while (*src) *dst++ = *src++; \
544 *dst = 0; \
546 /* This happens after copying, unavoidable without */ \
547 /* pre-counting length... should be ok */ \
548 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
549 RECORD_COPY(srclen); \
550 if (is_overlap(dst_orig, \
551 src_orig, \
552 (Addr)dst-(Addr)dst_orig+1, \
553 srclen)) \
554 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
556 return dst_orig; \
559 #if defined(VGO_linux)
560 STRCPY(VG_Z_LIBC_SONAME, strcpy)
561 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
563 #elif defined(VGO_freebsd)
564 STRCPY(VG_Z_LIBC_SONAME, strcpy)
565 STRCPY(VG_Z_LD_ELF_SO_1, strcpy)
566 STRCPY(VG_Z_LD_ELF32_SO_1, strcpy)
568 #elif defined(VGO_darwin)
569 STRCPY(VG_Z_LIBC_SONAME, strcpy)
570 # if DARWIN_VERS == DARWIN_10_9
571 STRCPY(libsystemZucZddylib, strcpy)
572 # endif
574 #elif defined(VGO_solaris)
575 STRCPY(VG_Z_LIBC_SONAME, strcpy)
576 STRCPY(VG_Z_LD_SO_1, strcpy)
578 #endif
581 /*---------------------- strncpy ----------------------*/
583 #define STRNCPY(soname, fnname) \
584 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
585 ( char* dst, const char* src, SizeT n ); \
586 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
587 ( char* dst, const char* src, SizeT n ) \
589 const HChar* src_orig = src; \
590 HChar* dst_orig = dst; \
591 SizeT m = 0; \
593 while (m < n && *src) { m++; *dst++ = *src++; } \
594 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
595 /* but only m+1 bytes of src if terminator was found */ \
596 SizeT srclen = (m < n) ? m+1 : n; \
597 RECORD_COPY(srclen); \
598 if (is_overlap(dst_orig, src_orig, n, srclen)) \
599 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
600 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
602 return dst_orig; \
605 #if defined(VGO_linux)
606 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
607 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
608 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
609 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
611 #elif defined(VGO_freebsd)
612 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
613 STRNCPY(VG_Z_LD_ELF_SO_1, strncpy)
614 STRNCPY(VG_Z_LD_ELF32_SO_1, strncpy)
616 #elif defined(VGO_darwin)
617 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
618 # if DARWIN_VERS >= DARWIN_10_9
619 STRNCPY(libsystemZucZddylib, strncpy)
620 # endif
622 #elif defined(VGO_solaris)
623 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
624 STRNCPY(VG_Z_LD_SO_1, strncpy)
626 #endif
629 /*---------------------- strlcpy ----------------------*/
631 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
632 Returns strlen(src). Does not zero-fill the remainder of dst. */
633 #define STRLCPY(soname, fnname) \
634 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
635 ( char* dst, const char* src, SizeT n ); \
636 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
637 ( char* dst, const char* src, SizeT n ) \
639 const HChar* src_orig = src; \
640 HChar* dst_orig = dst; \
641 SizeT m = 0; \
643 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
645 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
646 /* m non-nul bytes have now been copied, and m <= n-1. */ \
647 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
648 /* but only m+1 bytes of src if terminator was found */ \
649 SizeT srclen = (m < n) ? m+1 : n; \
650 RECORD_COPY(srclen); \
651 if (is_overlap(dst_orig, src_orig, n, srclen)) \
652 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
653 /* Nul-terminate dst. */ \
654 if (n > 0) *dst = 0; \
655 /* Finish counting strlen(src). */ \
656 while (*src) src++; \
657 return src - src_orig; \
660 #if defined(VGO_linux)
662 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
663 || defined(VGPV_mips32_linux_android)
664 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
665 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
666 #endif
668 #elif defined(VGO_freebsd)
669 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
670 STRLCPY(VG_Z_LD_ELF_SO_1, strlcpy)
671 STRLCPY(VG_Z_LD_ELF32_SO_1, strlcpy)
672 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
674 #elif defined(VGO_darwin)
675 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
676 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
677 //STRLCPY(VG_Z_DYLD, strlcpy)
678 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
680 #elif defined(VGO_solaris)
681 /* special case for n == 0 which is undocumented but heavily used */
682 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
683 if (n == 0) { \
684 while (*src) src++; \
685 return src - src_orig; \
688 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
690 #endif
693 /*---------------------- strncmp ----------------------*/
695 #define STRNCMP(soname, fnname) \
696 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
697 ( const char* s1, const char* s2, SizeT nmax ); \
698 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
699 ( const char* s1, const char* s2, SizeT nmax ) \
701 SizeT n = 0; \
702 while (True) { \
703 if (n >= nmax) return 0; \
704 if (*s1 == 0 && *s2 == 0) return 0; \
705 if (*s1 == 0) return -1; \
706 if (*s2 == 0) return 1; \
708 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
709 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
711 s1++; s2++; n++; \
715 #if defined(VGO_linux)
716 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
717 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
718 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
719 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
720 STRNCMP(VG_Z_LD_LINUX_SO_2, strncmp)
721 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2, strncmp)
723 #elif defined(VGO_freebsd)
724 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
725 STRNCMP(VG_Z_LD_ELF_SO_1, strncmp)
726 STRNCMP(VG_Z_LD_ELF32_SO_1, strncmp)
728 #elif defined(VGO_darwin)
729 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
730 # if DARWIN_VERS >= DARWIN_10_9
731 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
732 # endif
734 #elif defined(VGO_solaris)
735 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
737 #endif
740 /*---------------------- strcasecmp ----------------------*/
742 #define STRCASECMP(soname, fnname) \
743 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
744 ( const char* s1, const char* s2 ); \
745 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
746 ( const char* s1, const char* s2 ) \
748 extern int tolower(int); \
749 register UChar c1; \
750 register UChar c2; \
751 while (True) { \
752 c1 = tolower(*(const UChar *)s1); \
753 c2 = tolower(*(const UChar *)s2); \
754 if (c1 != c2) break; \
755 if (c1 == 0) break; \
756 s1++; s2++; \
758 if ((UChar)c1 < (UChar)c2) return -1; \
759 if ((UChar)c1 > (UChar)c2) return 1; \
760 return 0; \
763 #if defined(VGO_linux)
764 # if !defined(VGPV_arm_linux_android) \
765 && !defined(VGPV_x86_linux_android) \
766 && !defined(VGPV_mips32_linux_android) \
767 && !defined(VGPV_arm64_linux_android)
768 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
769 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
770 # endif
772 #elif defined(VGO_freebsd)
773 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
774 STRNCMP(VG_Z_LD_ELF_SO_1, strcasecmp)
775 STRNCMP(VG_Z_LD_ELF32_SO_1, strcasecmp)
777 #elif defined(VGO_darwin)
778 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
780 #elif defined(VGO_solaris)
781 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
783 #endif
786 /*---------------------- strncasecmp ----------------------*/
788 #define STRNCASECMP(soname, fnname) \
789 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
790 ( const char* s1, const char* s2, SizeT nmax ); \
791 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
792 ( const char* s1, const char* s2, SizeT nmax ) \
794 extern int tolower(int); \
795 SizeT n = 0; \
796 while (True) { \
797 if (n >= nmax) return 0; \
798 if (*s1 == 0 && *s2 == 0) return 0; \
799 if (*s1 == 0) return -1; \
800 if (*s2 == 0) return 1; \
802 if (tolower(*(const UChar *)s1) \
803 < tolower(*(const UChar*)s2)) return -1; \
804 if (tolower(*(const UChar *)s1) \
805 > tolower(*(const UChar *)s2)) return 1; \
807 s1++; s2++; n++; \
811 #if defined(VGO_linux)
812 # if !defined(VGPV_arm_linux_android) \
813 && !defined(VGPV_x86_linux_android) \
814 && !defined(VGPV_mips32_linux_android) \
815 && !defined(VGPV_arm64_linux_android)
816 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
817 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
818 # endif
820 #elif defined(VGO_freebsd)
821 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
822 STRNCASECMP(VG_Z_LD_ELF_SO_1, strncasecmp)
823 STRNCASECMP(VG_Z_LD_ELF32_SO_1, strncasecmp)
825 #elif defined(VGO_darwin)
826 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
827 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
829 #elif defined(VGO_solaris)
830 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
832 #endif
835 /*---------------------- strcasecmp_l ----------------------*/
837 #define STRCASECMP_L(soname, fnname) \
838 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
839 ( const char* s1, const char* s2, void* locale ); \
840 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
841 ( const char* s1, const char* s2, void* locale ) \
843 extern int tolower_l(int, void*) __attribute__((weak)); \
844 register UChar c1; \
845 register UChar c2; \
846 while (True) { \
847 c1 = tolower_l(*(const UChar *)s1, locale); \
848 c2 = tolower_l(*(const UChar *)s2, locale); \
849 if (c1 != c2) break; \
850 if (c1 == 0) break; \
851 s1++; s2++; \
853 if ((UChar)c1 < (UChar)c2) return -1; \
854 if ((UChar)c1 > (UChar)c2) return 1; \
855 return 0; \
858 #if defined(VGO_linux)
859 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
860 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
861 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
863 #elif defined(VGO_freebsd)
864 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
866 #elif defined(VGO_darwin)
867 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
869 #elif defined(VGO_solaris)
871 #endif
874 /*---------------------- strncasecmp_l ----------------------*/
876 #define STRNCASECMP_L(soname, fnname) \
877 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
878 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
879 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
880 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
882 extern int tolower_l(int, void*) __attribute__((weak)); \
883 SizeT n = 0; \
884 while (True) { \
885 if (n >= nmax) return 0; \
886 if (*s1 == 0 && *s2 == 0) return 0; \
887 if (*s1 == 0) return -1; \
888 if (*s2 == 0) return 1; \
890 if (tolower_l(*(const UChar *)s1, locale) \
891 < tolower_l(*(const UChar *)s2, locale)) return -1; \
892 if (tolower_l(*(const UChar *)s1, locale) \
893 > tolower_l(*(const UChar *)s2, locale)) return 1; \
895 s1++; s2++; n++; \
899 #if defined(VGO_linux)
900 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
902 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
904 #elif defined(VGO_freebsd)
905 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
907 #elif defined(VGO_darwin)
908 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
909 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
911 #elif defined(VGO_solaris)
913 #endif
916 /*---------------------- strcmp ----------------------*/
918 #define STRCMP(soname, fnname) \
919 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
920 ( const char* s1, const char* s2 ); \
921 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
922 ( const char* s1, const char* s2 ) \
924 register UChar c1; \
925 register UChar c2; \
926 while (True) { \
927 c1 = *(const UChar *)s1; \
928 c2 = *(const UChar *)s2; \
929 if (c1 != c2) break; \
930 if (c1 == 0) break; \
931 s1++; s2++; \
933 if ((UChar)c1 < (UChar)c2) return -1; \
934 if ((UChar)c1 > (UChar)c2) return 1; \
935 return 0; \
938 #if defined(VGO_linux)
939 STRCMP(VG_Z_LIBC_SONAME, strcmp)
940 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
941 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
942 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
943 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
944 STRCMP(VG_Z_LD64_SO_1, strcmp)
945 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
946 || defined(VGPV_mips32_linux_android)
947 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
948 # endif
950 #elif defined(VGO_freebsd)
951 STRCMP(VG_Z_LIBC_SONAME, strcmp)
952 STRCMP(VG_Z_LD_ELF_SO_1, strcmp)
953 STRCMP(VG_Z_LD_ELF32_SO_1, strcmp)
955 #elif defined(VGO_darwin)
956 STRCMP(VG_Z_LIBC_SONAME, strcmp)
957 # if DARWIN_VERS >= DARWIN_10_9
958 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
959 # endif
961 #elif defined(VGO_solaris)
962 STRCMP(VG_Z_LIBC_SONAME, strcmp)
963 STRCMP(VG_Z_LD_SO_1, strcmp)
965 #endif
968 /*---------------------- memchr ----------------------*/
970 #define MEMCHR(soname, fnname) \
971 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
972 (const void *s, int c, SizeT n); \
973 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
974 (const void *s, int c, SizeT n) \
976 SizeT i; \
977 UChar c0 = (UChar)c; \
978 const UChar* p = s; \
979 for (i = 0; i < n; i++) \
980 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
981 return NULL; \
984 #if defined(VGO_linux)
985 MEMCHR(VG_Z_LIBC_SONAME, memchr)
986 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
988 #elif defined(VGO_freebsd)
989 MEMCHR(VG_Z_LIBC_SONAME, memchr)
991 #elif defined(VGO_darwin)
992 # if DARWIN_VERS == DARWIN_10_9
993 MEMCHR(VG_Z_DYLD, memchr)
994 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
995 # endif
996 # if DARWIN_VERS >= DARWIN_10_10
997 MEMCHR(VG_Z_DYLD, memchr)
998 /* _platform_memchr$VARIANT$Generic */
999 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
1000 /* _platform_memchr$VARIANT$Haswell */
1001 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
1002 # endif
1004 #elif defined(VGO_solaris)
1005 MEMCHR(VG_Z_LIBC_SONAME, memchr)
1007 #endif
1010 /*---------------------- memrchr ----------------------*/
1012 #define MEMRCHR(soname, fnname) \
1013 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1014 (const void *s, int c, SizeT n); \
1015 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1016 (const void *s, int c, SizeT n) \
1018 SizeT i; \
1019 UChar c0 = (UChar)c; \
1020 const UChar* p = s; \
1021 for (i = 0; i < n; i++) \
1022 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1023 return NULL; \
1026 #if defined(VGO_linux)
1027 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1029 #elif defined(VGO_freebsd)
1030 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1032 #elif defined(VGO_darwin)
1033 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1034 //MEMRCHR(VG_Z_DYLD, memrchr)
1036 #elif defined(VGO_solaris)
1038 #endif
1041 /*---------------------- memcpy ----------------------*/
1043 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1044 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1045 ( void *dst, const void *src, SizeT len ); \
1046 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1047 ( void *dst, const void *src, SizeT len ) \
1049 RECORD_COPY(len); \
1050 if (do_ol_check && is_overlap(dst, src, len, len)) \
1051 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1053 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1054 const Addr WM = WS - 1; /* 7 or 3 */ \
1056 if (len > 0) { \
1057 if (dst < src || !is_overlap(dst, src, len, len)) { \
1059 /* Copying backwards. */ \
1060 SizeT n = len; \
1061 Addr d = (Addr)dst; \
1062 Addr s = (Addr)src; \
1064 if (((s^d) & WM) == 0) { \
1065 /* s and d have same UWord alignment. */ \
1066 /* Pull up to a UWord boundary. */ \
1067 while ((s & WM) != 0 && n >= 1) \
1068 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1069 /* Copy UWords. */ \
1070 while (n >= WS * 4) \
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 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1075 while (n >= WS) \
1076 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1077 if (n == 0) \
1078 return dst; \
1080 if (((s|d) & 1) == 0) { \
1081 /* Both are 16-aligned; copy what we can thusly. */ \
1082 while (n >= 2) \
1083 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1085 /* Copy leftovers, or everything if misaligned. */ \
1086 while (n >= 1) \
1087 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1089 } else if (dst > src) { \
1091 SizeT n = len; \
1092 Addr d = ((Addr)dst) + n; \
1093 Addr s = ((Addr)src) + n; \
1095 /* Copying forwards. */ \
1096 if (((s^d) & WM) == 0) { \
1097 /* s and d have same UWord alignment. */ \
1098 /* Back down to a UWord boundary. */ \
1099 while ((s & WM) != 0 && n >= 1) \
1100 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1101 /* Copy UWords. */ \
1102 while (n >= WS * 4) \
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 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1107 while (n >= WS) \
1108 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1109 if (n == 0) \
1110 return dst; \
1112 if (((s|d) & 1) == 0) { \
1113 /* Both are 16-aligned; copy what we can thusly. */ \
1114 while (n >= 2) \
1115 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1117 /* Copy leftovers, or everything if misaligned. */ \
1118 while (n >= 1) \
1119 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1124 return dst; \
1127 #define MEMMOVE(soname, fnname) \
1128 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1130 #define MEMCPY(soname, fnname) \
1131 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1133 #if defined(VGO_linux)
1134 /* For older memcpy we have to use memmove-like semantics and skip
1135 the overlap check; sigh; see #275284. */
1136 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1137 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1138 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1139 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1140 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1141 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_avx_unaligned_erms)
1142 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1143 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1144 /* icc9 blats these around all over the place. Not only in the main
1145 executable but various .so's. They are highly tuned and read
1146 memory beyond the source boundary (although work correctly and
1147 never go across page boundaries), so give errors when run
1148 natively, at least for misaligned source arg. Just intercepting
1149 in the exe only until we understand more about the problem. See
1150 http://bugs.kde.org/show_bug.cgi?id=139776
1152 MEMCPY(NONE, ZuintelZufastZumemcpy)
1154 #elif defined(VGO_freebsd)
1155 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1156 MEMCPY(VG_Z_LD_ELF_SO_1, memcpy)
1157 MEMCPY(VG_Z_LD_ELF32_SO_1, memcpy)
1159 #elif defined(VGO_darwin)
1160 # if DARWIN_VERS <= DARWIN_10_6
1161 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1162 # endif
1163 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1164 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1166 #elif defined(VGO_solaris)
1167 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1168 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
1169 MEMCPY(VG_Z_LD_SO_1, memcpy)
1171 #endif
1174 /*---------------------- memcmp ----------------------*/
1176 #define MEMCMP(soname, fnname) \
1177 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1178 ( const void *s1V, const void *s2V, SizeT n ); \
1179 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1180 ( const void *s1V, const void *s2V, SizeT n ) \
1182 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1183 const SizeT WM = WS - 1; /* 7 or 3 */ \
1184 Addr s1A = (Addr)s1V; \
1185 Addr s2A = (Addr)s2V; \
1187 if (((s1A | s2A) & WM) == 0) { \
1188 /* Both areas are word aligned. Skip over the */ \
1189 /* equal prefix as fast as possible. */ \
1190 while (n >= WS) { \
1191 UWord w1 = *(UWord*)s1A; \
1192 UWord w2 = *(UWord*)s2A; \
1193 if (w1 != w2) break; \
1194 s1A += WS; \
1195 s2A += WS; \
1196 n -= WS; \
1200 const UChar* s1 = (const UChar*) s1A; \
1201 const UChar* s2 = (const UChar*) s2A; \
1203 while (n != 0) { \
1204 UChar a0 = s1[0]; \
1205 UChar b0 = s2[0]; \
1206 s1 += 1; \
1207 s2 += 1; \
1208 int res = ((int)a0) - ((int)b0); \
1209 if (res != 0) \
1210 return res; \
1211 n -= 1; \
1213 return 0; \
1216 #if defined(VGO_linux)
1217 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1218 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1219 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1220 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1221 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1222 MEMCMP(VG_Z_LD_SO_1, bcmp)
1224 #elif defined(VGO_freebsd)
1225 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1226 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1227 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_memcmp)
1228 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_bcmp)
1230 #elif defined(VGO_darwin)
1231 # if DARWIN_VERS >= DARWIN_10_9
1232 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1233 # endif
1235 #elif defined(VGO_solaris)
1236 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1237 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1238 MEMCMP(VG_Z_LD_SO_1, memcmp)
1240 #endif
1243 /*---------------------- stpcpy ----------------------*/
1245 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1246 DEST. (minor variant of strcpy) */
1247 #define STPCPY(soname, fnname) \
1248 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1249 ( char* dst, const char* src ); \
1250 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1251 ( char* dst, const char* src ) \
1253 const HChar* src_orig = src; \
1254 HChar* dst_orig = dst; \
1256 while (*src) *dst++ = *src++; \
1257 *dst = 0; \
1259 /* This checks for overlap after copying, unavoidable without */ \
1260 /* pre-counting length... should be ok */ \
1261 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1262 RECORD_COPY(srclen); \
1263 if (is_overlap(dst_orig, \
1264 src_orig, \
1265 (Addr)dst-(Addr)dst_orig+1, \
1266 srclen)) \
1267 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1269 return dst; \
1272 #if defined(VGO_linux)
1273 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1274 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1275 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1276 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1277 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1278 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1279 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1281 #elif defined(VGO_freebsd)
1282 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1283 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1284 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1286 #elif defined(VGO_freebsd)
1287 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1288 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1289 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1291 #elif defined(VGO_darwin)
1292 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1293 //STPCPY(VG_Z_DYLD, stpcpy)
1295 #elif defined(VGO_solaris)
1296 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1298 #endif
1301 /*---------------------- stpncpy ----------------------*/
1303 #define STPNCPY(soname, fnname) \
1304 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1305 ( char* dst, const char* src, SizeT n ); \
1306 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1307 ( char* dst, const char* src, SizeT n ) \
1309 const HChar* src_orig = src; \
1310 HChar* dst_str = dst; \
1311 SizeT m = 0; \
1313 while (m < n && *src) { m++; *dst++ = *src++; } \
1314 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1315 /* but only m+1 bytes of src if terminator was found */ \
1316 SizeT srclen = (m < n) ? m+1 : n; \
1317 RECORD_COPY(srclen); \
1318 if (is_overlap(dst_str, src_orig, n, srclen)) \
1319 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1320 dst_str = dst; \
1321 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1323 return dst_str; \
1326 #if defined(VGO_linux) || defined(VGO_freebsd)
1327 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1328 #endif
1331 /*---------------------- memset ----------------------*/
1333 #define MEMSET(soname, fnname) \
1334 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1335 (void *s, Int c, SizeT n); \
1336 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1337 (void *s, Int c, SizeT n) \
1339 if (sizeof(void*) == 8) { \
1340 Addr a = (Addr)s; \
1341 ULong c8 = (c & 0xFF); \
1342 c8 = (c8 << 8) | c8; \
1343 c8 = (c8 << 16) | c8; \
1344 c8 = (c8 << 32) | c8; \
1345 while ((a & 7) != 0 && n >= 1) \
1346 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1347 while (n >= 32) \
1348 { *(ULong*)a = c8; a += 8; n -= 8; \
1349 *(ULong*)a = c8; a += 8; n -= 8; \
1350 *(ULong*)a = c8; a += 8; n -= 8; \
1351 *(ULong*)a = c8; a += 8; n -= 8; } \
1352 while (n >= 8) \
1353 { *(ULong*)a = c8; a += 8; n -= 8; } \
1354 while (n >= 1) \
1355 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1356 return s; \
1357 } else { \
1358 Addr a = (Addr)s; \
1359 UInt c4 = (c & 0xFF); \
1360 c4 = (c4 << 8) | c4; \
1361 c4 = (c4 << 16) | c4; \
1362 while ((a & 3) != 0 && n >= 1) \
1363 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1364 while (n >= 16) \
1365 { *(UInt*)a = c4; a += 4; n -= 4; \
1366 *(UInt*)a = c4; a += 4; n -= 4; \
1367 *(UInt*)a = c4; a += 4; n -= 4; \
1368 *(UInt*)a = c4; a += 4; n -= 4; } \
1369 while (n >= 4) \
1370 { *(UInt*)a = c4; a += 4; n -= 4; } \
1371 while (n >= 1) \
1372 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1373 return s; \
1377 #if defined(VGO_linux)
1378 MEMSET(VG_Z_LIBC_SONAME, memset)
1380 #elif defined(VGO_freebsd)
1381 MEMSET(VG_Z_LIBC_SONAME, memset)
1382 MEMSET(VG_Z_LD_ELF_SO_1, memset)
1383 MEMSET(VG_Z_LD_ELF32_SO_1, memset)
1385 #elif defined(VGO_darwin)
1386 //MEMSET(VG_Z_LIBC_SONAME, memset)
1387 //MEMSET(VG_Z_DYLD, memset)
1388 MEMSET(VG_Z_LIBC_SONAME, memset)
1390 #elif defined(VGO_solaris)
1391 MEMSET(VG_Z_LIBC_SONAME, memset)
1392 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1394 #endif
1397 /*---------------------- memmove ----------------------*/
1399 /* memmove -- use the MEMMOVE defn above. */
1401 #if defined(VGO_linux)
1402 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1403 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1404 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1405 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1406 to call memcpy. */
1407 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1409 #elif defined(VGO_freebsd)
1410 MEMMOVE(VG_Z_LD_ELF_SO_1, memmove)
1411 MEMMOVE(VG_Z_LD_ELF32_SO_1, memmove)
1412 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1414 #elif defined(VGO_darwin)
1415 # if DARWIN_VERS <= DARWIN_10_6
1416 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1417 # endif
1418 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1419 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1420 # if DARWIN_VERS >= DARWIN_10_9
1421 /* _platform_memmove$VARIANT$Ivybridge */
1422 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1423 # endif
1425 #elif defined(VGO_solaris)
1426 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1427 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1428 MEMMOVE(VG_Z_LD_SO_1, memmove)
1430 #endif
1433 /*---------------------- bcopy ----------------------*/
1435 #define BCOPY(soname, fnname) \
1436 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1437 (const void *srcV, void *dstV, SizeT n); \
1438 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1439 (const void *srcV, void *dstV, SizeT n) \
1441 RECORD_COPY(n); \
1442 SizeT i; \
1443 HChar* dst = dstV; \
1444 const HChar* src = srcV; \
1445 if (dst < src) { \
1446 for (i = 0; i < n; i++) \
1447 dst[i] = src[i]; \
1449 else \
1450 if (dst > src) { \
1451 for (i = 0; i < n; i++) \
1452 dst[n-i-1] = src[n-i-1]; \
1456 #if defined(VGO_linux)
1457 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1459 #elif defined(VGO_freebsd)
1460 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1461 BCOPY(VG_Z_LD_ELF_SO_1, bcopy)
1462 BCOPY(VG_Z_LD_ELF32_SO_1, bcopy)
1464 #elif defined(VGO_darwin)
1465 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1466 //BCOPY(VG_Z_DYLD, bcopy)
1468 #elif defined(VGO_darwin)
1469 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1471 #endif
1474 /*-------------------- memmove_chk --------------------*/
1476 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1477 There is no specific part of glibc that this is copied from. */
1478 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1479 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1480 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1481 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1482 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1484 RECORD_COPY(n); \
1485 SizeT i; \
1486 HChar* dst = dstV; \
1487 const HChar* src = srcV; \
1488 if (destlen < n) \
1489 goto badness; \
1490 if (dst < src) { \
1491 for (i = 0; i < n; i++) \
1492 dst[i] = src[i]; \
1494 else \
1495 if (dst > src) { \
1496 for (i = 0; i < n; i++) \
1497 dst[n-i-1] = src[n-i-1]; \
1499 return dst; \
1500 badness: \
1501 VALGRIND_PRINTF_BACKTRACE( \
1502 "*** memmove_chk: buffer overflow detected ***: " \
1503 "program terminated\n"); \
1504 my_exit(1); \
1505 /*NOTREACHED*/ \
1506 return NULL; \
1509 #if defined(VGO_linux)
1510 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1512 #elif defined(VGO_darwin)
1514 #elif defined(VGO_solaris)
1516 #endif
1519 /*-------------------- strchrnul --------------------*/
1521 /* Find the first occurrence of C in S or the final NUL byte. */
1522 #define GLIBC232_STRCHRNUL(soname, fnname) \
1523 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1524 (const char* s, int c_in); \
1525 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1526 (const char* s, int c_in) \
1528 HChar c = (HChar) c_in; \
1529 const HChar* char_ptr = s; \
1530 while (1) { \
1531 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1532 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1533 char_ptr++; \
1537 #if defined(VGO_linux)
1538 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1540 #elif defined(VGO_freebsd)
1541 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1543 #elif defined(VGO_darwin)
1545 #elif defined(VGO_solaris)
1547 #endif
1550 /*---------------------- rawmemchr ----------------------*/
1552 /* Find the first occurrence of C in S. */
1553 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1554 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1555 (const void* s, int c_in); \
1556 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1557 (const void* s, int c_in) \
1559 UChar c = (UChar) c_in; \
1560 const UChar* char_ptr = s; \
1561 while (1) { \
1562 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1563 char_ptr++; \
1567 #if defined (VGO_linux)
1568 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1569 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1571 #elif defined(VGO_darwin)
1573 #elif defined(VGO_solaris)
1575 #endif
1578 /*---------------------- strcpy_chk ----------------------*/
1580 /* glibc variant of strcpy that checks the dest is big enough.
1581 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1582 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1583 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1584 (char* dst, const char* src, SizeT len); \
1585 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1586 (char* dst, const char* src, SizeT len) \
1588 FOR_COPY(const HChar* src_orig = src); \
1589 HChar* ret = dst; \
1590 if (! len) \
1591 goto badness; \
1592 while ((*dst++ = *src++) != '\0') \
1593 if (--len == 0) \
1594 goto badness; \
1595 RECORD_COPY((Addr)src-(Addr)src_orig); \
1596 return ret; \
1597 badness: \
1598 VALGRIND_PRINTF_BACKTRACE( \
1599 "*** strcpy_chk: buffer overflow detected ***: " \
1600 "program terminated\n"); \
1601 my_exit(1); \
1602 /*NOTREACHED*/ \
1603 return NULL; \
1606 #if defined(VGO_linux)
1607 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1609 #elif defined(VGO_darwin)
1611 #elif defined(VGO_solaris)
1613 #endif
1616 /*---------------------- stpcpy_chk ----------------------*/
1618 /* glibc variant of stpcpy that checks the dest is big enough.
1619 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1620 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1621 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1622 (char* dst, const char* src, SizeT len); \
1623 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1624 (char* dst, const char* src, SizeT len) \
1626 FOR_COPY(const HChar* src_orig = src); \
1627 if (! len) \
1628 goto badness; \
1629 while ((*dst++ = *src++) != '\0') \
1630 if (--len == 0) \
1631 goto badness; \
1632 RECORD_COPY((Addr)src-(Addr)src_orig); \
1633 return dst - 1; \
1634 badness: \
1635 VALGRIND_PRINTF_BACKTRACE( \
1636 "*** stpcpy_chk: buffer overflow detected ***: " \
1637 "program terminated\n"); \
1638 my_exit(1); \
1639 /*NOTREACHED*/ \
1640 return NULL; \
1643 #if defined(VGO_linux)
1644 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1646 #elif defined(VGO_darwin)
1648 #elif defined(VGO_solaris)
1650 #endif
1653 /*---------------------- mempcpy ----------------------*/
1655 /* mempcpy */
1656 #define GLIBC25_MEMPCPY(soname, fnname) \
1657 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1658 ( void *dst, const void *src, SizeT len ); \
1659 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1660 ( void *dst, const void *src, SizeT len ) \
1662 RECORD_COPY(len); \
1663 SizeT len_saved = len; \
1665 if (len == 0) \
1666 return dst; \
1668 if (is_overlap(dst, src, len, len)) \
1669 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1671 if ( dst > src ) { \
1672 register HChar *d = (char *)dst + len - 1; \
1673 register const HChar *s = (const char *)src + len - 1; \
1674 while ( len-- ) { \
1675 *d-- = *s--; \
1677 } else if ( dst < src ) { \
1678 register HChar *d = dst; \
1679 register const HChar *s = src; \
1680 while ( len-- ) { \
1681 *d++ = *s++; \
1684 return (void*)( ((char*)dst) + len_saved ); \
1687 #if defined(VGO_linux)
1688 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1689 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1690 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1691 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1692 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1694 #elif defined(VGO_freebsd)
1695 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1696 #elif defined(VGO_darwin)
1697 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1699 #elif defined(VGO_solaris)
1701 #endif
1704 /*-------------------- memcpy_chk --------------------*/
1706 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1707 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1708 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1709 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1710 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1712 register HChar *d; \
1713 register const HChar *s; \
1714 if (dstlen < len) \
1715 goto badness; \
1716 RECORD_COPY(len); \
1717 if (len == 0) \
1718 return dst; \
1719 if (is_overlap(dst, src, len, len)) \
1720 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1721 if ( dst > src ) { \
1722 d = (HChar *)dst + len - 1; \
1723 s = (const HChar *)src + len - 1; \
1724 while ( len-- ) { \
1725 *d-- = *s--; \
1727 } else if ( dst < src ) { \
1728 d = (HChar *)dst; \
1729 s = (const HChar *)src; \
1730 while ( len-- ) { \
1731 *d++ = *s++; \
1734 return dst; \
1735 badness: \
1736 VALGRIND_PRINTF_BACKTRACE( \
1737 "*** memcpy_chk: buffer overflow detected ***: " \
1738 "program terminated\n"); \
1739 my_exit(1); \
1740 /*NOTREACHED*/ \
1741 return NULL; \
1744 #if defined(VGO_linux)
1745 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1747 #elif defined(VGO_darwin)
1749 #elif defined(VGO_solaris)
1751 #endif
1754 /*---------------------- strstr ----------------------*/
1756 #define STRSTR(soname, fnname) \
1757 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1758 (const char* haystack, const char* needle); \
1759 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1760 (const char* haystack, const char* needle) \
1762 const HChar* h = haystack; \
1763 const HChar* n = needle; \
1765 /* find the length of n, not including terminating zero */ \
1766 UWord nlen = 0; \
1767 while (n[nlen]) nlen++; \
1769 /* if n is the empty string, match immediately. */ \
1770 if (nlen == 0) return CONST_CAST(HChar *,h); \
1772 /* assert(nlen >= 1); */ \
1773 HChar n0 = n[0]; \
1775 while (1) { \
1776 const HChar hh = *h; \
1777 if (hh == 0) return NULL; \
1778 if (hh != n0) { h++; continue; } \
1780 UWord i; \
1781 for (i = 0; i < nlen; i++) { \
1782 if (n[i] != h[i]) \
1783 break; \
1785 /* assert(i >= 0 && i <= nlen); */ \
1786 if (i == nlen) \
1787 return CONST_CAST(HChar *,h); \
1789 h++; \
1793 #if defined(VGO_linux)
1794 STRSTR(VG_Z_LIBC_SONAME, strstr)
1795 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1796 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1798 #elif defined(VGO_freebsd)
1799 STRSTR(VG_Z_LIBC_SONAME, strstr)
1801 #elif defined(VGO_darwin)
1803 #elif defined(VGO_solaris)
1804 STRSTR(VG_Z_LIBC_SONAME, strstr)
1806 #endif
1808 /*---------------------- memmem ----------------------*/
1810 #define MEMMEM(soname, fnname) \
1811 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1812 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1813 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1814 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1816 const HChar* h = haystack; \
1817 const HChar* n = needle; \
1819 /* If the needle is the empty string, match immediately. */ \
1820 if (nlen == 0) return CONST_CAST(void *,h); \
1822 HChar n0 = n[0]; \
1824 for (; hlen >= nlen; hlen--, h++) { \
1825 if (h[0] != n0) continue; \
1827 UWord i; \
1828 for (i = 1; i < nlen; i++) { \
1829 if (n[i] != h[i]) \
1830 break; \
1832 if (i == nlen) \
1833 return CONST_CAST(HChar *,h); \
1836 return NULL; \
1839 #if defined(VGP_s390x_linux)
1840 MEMMEM(VG_Z_LIBC_SONAME, memmem)
1841 #endif
1844 /*---------------------- strpbrk ----------------------*/
1846 #define STRPBRK(soname, fnname) \
1847 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1848 (const char* sV, const char* acceptV); \
1849 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1850 (const char* sV, const char* acceptV) \
1852 const HChar* s = sV; \
1853 const HChar* accept = acceptV; \
1855 /* find the length of 'accept', not including terminating zero */ \
1856 UWord nacc = 0; \
1857 while (accept[nacc]) nacc++; \
1859 /* if n is the empty string, fail immediately. */ \
1860 if (nacc == 0) return NULL; \
1862 /* assert(nacc >= 1); */ \
1863 while (1) { \
1864 UWord i; \
1865 HChar sc = *s; \
1866 if (sc == 0) \
1867 break; \
1868 for (i = 0; i < nacc; i++) { \
1869 if (sc == accept[i]) \
1870 return CONST_CAST(HChar *,s); \
1872 s++; \
1875 return NULL; \
1878 #if defined(VGO_linux)
1879 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1881 #elif defined(VGO_freebsd)
1882 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1884 #elif defined(VGO_darwin)
1886 #elif defined(VGO_solaris)
1887 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1889 #endif
1892 /*---------------------- strcspn ----------------------*/
1894 #define STRCSPN(soname, fnname) \
1895 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1896 (const char* sV, const char* rejectV); \
1897 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1898 (const char* sV, const char* rejectV) \
1900 const HChar* s = sV; \
1901 const HChar* reject = rejectV; \
1903 /* find the length of 'reject', not including terminating zero */ \
1904 UWord nrej = 0; \
1905 while (reject[nrej]) nrej++; \
1907 UWord len = 0; \
1908 while (1) { \
1909 UWord i; \
1910 HChar sc = *s; \
1911 if (sc == 0) \
1912 break; \
1913 for (i = 0; i < nrej; i++) { \
1914 if (sc == reject[i]) \
1915 break; \
1917 /* assert(i >= 0 && i <= nrej); */ \
1918 if (i < nrej) \
1919 break; \
1920 s++; \
1921 len++; \
1924 return len; \
1927 #if defined(VGO_linux)
1928 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1929 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1931 #elif defined(VGO_freebsd)
1932 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1934 #elif defined(VGO_darwin)
1936 #elif defined(VGO_solaris)
1937 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1939 #endif
1942 /*---------------------- strspn ----------------------*/
1944 #define STRSPN(soname, fnname) \
1945 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1946 (const char* sV, const char* acceptV); \
1947 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1948 (const char* sV, const char* acceptV) \
1950 const UChar* s = (const UChar *)sV; \
1951 const UChar* accept = (const UChar *)acceptV; \
1953 /* find the length of 'accept', not including terminating zero */ \
1954 UWord nacc = 0; \
1955 while (accept[nacc]) nacc++; \
1956 if (nacc == 0) return 0; \
1958 UWord len = 0; \
1959 while (1) { \
1960 UWord i; \
1961 UChar sc = *s; \
1962 if (sc == 0) \
1963 break; \
1964 for (i = 0; i < nacc; i++) { \
1965 if (sc == accept[i]) \
1966 break; \
1968 /* assert(i >= 0 && i <= nacc); */ \
1969 if (i == nacc) \
1970 break; \
1971 s++; \
1972 len++; \
1975 return len; \
1978 #if defined(VGO_linux)
1979 STRSPN(VG_Z_LIBC_SONAME, strspn)
1981 #elif defined(VGO_freebsd)
1982 STRSPN(VG_Z_LIBC_SONAME, strspn)
1984 #elif defined(VGO_darwin)
1986 #elif defined(VGO_solaris)
1987 STRSPN(VG_Z_LIBC_SONAME, strspn)
1989 #endif
1992 /*---------------------- strcasestr ----------------------*/
1994 #define STRCASESTR(soname, fnname) \
1995 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1996 (const char* haystack, const char* needle); \
1997 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1998 (const char* haystack, const char* needle) \
2000 extern int tolower(int); \
2001 const HChar* h = haystack; \
2002 const HChar* n = needle; \
2004 /* find the length of n, not including terminating zero */ \
2005 UWord nlen = 0; \
2006 while (n[nlen]) nlen++; \
2008 /* if n is the empty string, match immediately. */ \
2009 if (nlen == 0) return CONST_CAST(HChar *,h); \
2011 /* assert(nlen >= 1); */ \
2012 UChar n0 = tolower(n[0]); \
2014 while (1) { \
2015 UChar hh = tolower(*h); \
2016 if (hh == 0) return NULL; \
2017 if (hh != n0) { h++; continue; } \
2019 UWord i; \
2020 for (i = 0; i < nlen; i++) { \
2021 if (tolower(n[i]) != tolower(h[i])) \
2022 break; \
2024 /* assert(i >= 0 && i <= nlen); */ \
2025 if (i == nlen) \
2026 return CONST_CAST(HChar *,h); \
2028 h++; \
2032 #if defined(VGO_linux)
2033 # if !defined(VGPV_arm_linux_android) \
2034 && !defined(VGPV_x86_linux_android) \
2035 && !defined(VGPV_mips32_linux_android) \
2036 && !defined(VGPV_arm64_linux_android)
2037 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2038 # endif
2040 #elif defined(VGO_freebsd)
2041 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2043 #elif defined(VGO_darwin)
2045 #elif defined(VGO_solaris)
2046 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2048 #endif
2051 /*---------------------- wcslen ----------------------*/
2053 // This is a wchar_t equivalent to strlen. Unfortunately
2054 // we don't have wchar_t available here, but it looks like
2055 // a 32 bit int on Linux. I don't know if that is also
2056 // valid on MacOSX.
2058 #define WCSLEN(soname, fnname) \
2059 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2060 ( const Int* str ); \
2061 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2062 ( const Int* str ) \
2064 SizeT i = 0; \
2065 while (str[i] != 0) i++; \
2066 return i; \
2069 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2070 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
2072 #endif
2074 /*---------------------- wcsnlen ----------------------*/
2076 #define WCSNLEN(soname, fnname) \
2077 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2078 ( const Int *s, SizeT n ); \
2079 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2080 ( const Int *s, SizeT n ) \
2082 SizeT i = 0; \
2083 const Int* p = s; \
2084 while (i < n && *p != 0) { \
2085 i++; \
2086 p++; \
2088 return i; \
2091 #if defined(VGO_linux) || defined(VGO_freebsd)
2092 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
2093 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
2094 #endif
2096 /*---------------------- wcscmp ----------------------*/
2098 // This is a wchar_t equivalent to strcmp. We don't
2099 // have wchar_t available here, but in the GNU C Library
2100 // wchar_t is always 32 bits wide and wcscmp uses signed
2101 // comparison, not unsigned as in strcmp function.
2103 #define WCSCMP(soname, fnname) \
2104 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2105 ( const Int* s1, const Int* s2 ); \
2106 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2107 ( const Int* s1, const Int* s2 ) \
2109 register Int c1; \
2110 register Int c2; \
2111 while (True) { \
2112 c1 = *s1; \
2113 c2 = *s2; \
2114 if (c1 != c2) break; \
2115 if (c1 == 0) break; \
2116 s1++; s2++; \
2118 if (c1 < c2) return -1; \
2119 if (c1 > c2) return 1; \
2120 return 0; \
2123 #if defined(VGO_linux) || defined(VGO_freebsd)
2124 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
2125 #endif
2127 /*---------------------- wcsncmp ----------------------*/
2129 // This is a wchar_t equivalent to strncmp. We don't
2130 // have wchar_t available here, but in the GNU C Library
2131 // wchar_t is always 32 bits wide and wcsncmp uses signed
2132 // comparison, not unsigned as in strncmp function.
2134 #define WCSNCMP(soname, fnname) \
2135 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2136 ( const Int* s1, const Int* s2, SizeT nmax ); \
2137 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2138 ( const Int* s1, const Int* s2, SizeT nmax ) \
2140 SizeT n = 0; \
2141 while (True) { \
2142 if (n >= nmax) return 0; \
2143 if (*s1 == 0 && *s2 == 0) return 0; \
2144 if (*s1 == 0) return -1; \
2145 if (*s2 == 0) return 1; \
2147 if (*s1 < *s2) return -1; \
2148 if (*s1 > *s2) return 1; \
2150 s1++; s2++; n++; \
2153 #if defined(VGO_linux) || defined(VGO_freebsd)
2154 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
2155 #endif
2157 /*---------------------- wcscpy ----------------------*/
2159 // This is a wchar_t equivalent to strcpy. We don't
2160 // have wchar_t available here, but in the GNU C Library
2161 // wchar_t is always 32 bits wide.
2163 #define WCSCPY(soname, fnname) \
2164 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2165 ( Int* dst, const Int* src ); \
2166 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2167 ( Int* dst, const Int* src ) \
2169 const Int* src_orig = src; \
2170 Int* dst_orig = dst; \
2172 while (*src) *dst++ = *src++; \
2173 *dst = 0; \
2175 /* This checks for overlap after copying, unavoidable without */ \
2176 /* pre-counting length... should be ok */ \
2177 /* +4 because sizeof(wchar_t) == 4 */ \
2178 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2179 RECORD_COPY(srclen); \
2180 if (is_overlap(dst_orig, \
2181 src_orig, \
2182 /* +4 because sizeof(wchar_t) == 4 */ \
2183 (Addr)dst-(Addr)dst_orig+4, \
2184 srclen)) \
2185 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2187 return dst_orig; \
2190 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2191 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2192 #endif
2195 /*---------------------- wcschr ----------------------*/
2197 // This is a wchar_t equivalent to strchr. We don't
2198 // have wchar_t available here, but in the GNU C Library
2199 // wchar_t is always 32 bits wide.
2201 #define WCSCHR(soname, fnname) \
2202 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2203 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2205 const Int* p = s; \
2206 while (True) { \
2207 if (*p == c) return CONST_CAST(Int *,p); \
2208 if (*p == 0) return NULL; \
2209 p++; \
2213 #if defined(VGO_linux) || defined(VGO_freebsd)
2214 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2215 #endif
2216 /*---------------------- wcsrchr ----------------------*/
2218 // This is a wchar_t equivalent to strrchr. We don't
2219 // have wchar_t available here, but in the GNU C Library
2220 // wchar_t is always 32 bits wide.
2222 #define WCSRCHR(soname, fnname) \
2223 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2224 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2226 const Int* p = s; \
2227 const Int* last = NULL; \
2228 while (True) { \
2229 if (*p == c) last = p; \
2230 if (*p == 0) return CONST_CAST(Int *,last); \
2231 p++; \
2235 #if defined(VGO_linux) || defined(VGO_freebsd)
2236 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2237 #endif
2239 /*---------------------- wmemchr ----------------------*/
2241 // This is a wchar_t equivalent to memchr. We don't
2242 // have wchar_t available here, but in the GNU C Library
2243 // wchar_t is always 32 bits wide.
2245 #define WMEMCHR(soname, fnname) \
2246 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2247 (const Int *s, Int c, SizeT n); \
2248 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2249 (const Int *s, Int c, SizeT n) \
2251 SizeT i; \
2252 const Int* p = s; \
2253 for (i = 0; i < n; i++) { \
2254 if (*p == c) return CONST_CAST(Int *,p); \
2255 p++; \
2257 return NULL; \
2260 #if defined(VGO_linux)
2261 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2262 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2263 #endif
2265 #if defined(VGO_freebsd)
2266 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2267 #endif
2270 #define WMEMCMP(soname, fnname) \
2271 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2272 ( const Int *b1, const Int *b2, SizeT n ); \
2273 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2274 ( const Int *b1, const Int *b2, SizeT n ) \
2276 for (SizeT i = 0U; i < n; ++i) { \
2277 if (b1[i] != b2[i]) \
2278 return b1[i] > b2[i] ? 1 : -1; \
2280 return 0; \
2283 #if defined(VGO_linux)
2284 WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
2285 #endif
2288 /*------------------------------------------------------------*/
2289 /*--- Improve definedness checking of process environment ---*/
2290 /*------------------------------------------------------------*/
2292 #if defined(VGO_linux) || defined(VGO_freebsd)
2294 /* If these wind up getting generated via a macro, so that multiple
2295 versions of each function exist (as above), use the _EZU variants
2296 to assign equivalance class tags. */
2298 /*---------------------- putenv ----------------------*/
2300 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2301 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2303 OrigFn fn;
2304 Word result;
2305 const HChar* p = string;
2306 VALGRIND_GET_ORIG_FN(fn);
2307 /* Now by walking over the string we magically produce
2308 traces when hitting undefined memory. */
2309 if (p)
2310 while (*p++)
2311 __asm__ __volatile__("" ::: "memory");
2312 CALL_FN_W_W(result, fn, string);
2313 return result;
2317 /*---------------------- unsetenv ----------------------*/
2319 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2320 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2322 OrigFn fn;
2323 Word result;
2324 const HChar* p = name;
2325 VALGRIND_GET_ORIG_FN(fn);
2326 /* Now by walking over the string we magically produce
2327 traces when hitting undefined memory. */
2328 if (p)
2329 while (*p++)
2330 __asm__ __volatile__("" ::: "memory");
2331 CALL_FN_W_W(result, fn, name);
2332 return result;
2336 /*---------------------- setenv ----------------------*/
2338 /* setenv */
2339 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2340 (const char* name, const char* value, int overwrite);
2341 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2342 (const char* name, const char* value, int overwrite)
2344 OrigFn fn;
2345 Word result;
2346 const HChar* p;
2347 VALGRIND_GET_ORIG_FN(fn);
2348 /* Now by walking over the string we magically produce
2349 traces when hitting undefined memory. */
2350 if (name)
2351 for (p = name; *p; p++)
2352 __asm__ __volatile__("" ::: "memory");
2353 if (value)
2354 for (p = value; *p; p++)
2355 __asm__ __volatile__("" ::: "memory");
2356 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2357 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2358 return result;
2361 #endif /* defined(VGO_linux) */
2363 /*--------------------------------------------------------------------*/
2364 /*--- end ---*/
2365 /*--------------------------------------------------------------------*/