Merge error, missing continuation in Makefile.am
[valgrind.git] / shared / vg_replace_strmem.c
blobb32f13f76d54cd480093cdc64a6bebdfbaead4dc
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)
1228 #elif defined(VGO_darwin)
1229 # if DARWIN_VERS >= DARWIN_10_9
1230 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1231 # endif
1233 #elif defined(VGO_solaris)
1234 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1235 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1236 MEMCMP(VG_Z_LD_SO_1, memcmp)
1238 #endif
1241 /*---------------------- stpcpy ----------------------*/
1243 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1244 DEST. (minor variant of strcpy) */
1245 #define STPCPY(soname, fnname) \
1246 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1247 ( char* dst, const char* src ); \
1248 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1249 ( char* dst, const char* src ) \
1251 const HChar* src_orig = src; \
1252 HChar* dst_orig = dst; \
1254 while (*src) *dst++ = *src++; \
1255 *dst = 0; \
1257 /* This checks for overlap after copying, unavoidable without */ \
1258 /* pre-counting length... should be ok */ \
1259 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1260 RECORD_COPY(srclen); \
1261 if (is_overlap(dst_orig, \
1262 src_orig, \
1263 (Addr)dst-(Addr)dst_orig+1, \
1264 srclen)) \
1265 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1267 return dst; \
1270 #if defined(VGO_linux)
1271 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1272 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1273 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1274 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1275 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1276 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1277 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1279 #elif defined(VGO_freebsd)
1280 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1281 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1282 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1284 #elif defined(VGO_freebsd)
1285 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1286 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1287 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1289 #elif defined(VGO_darwin)
1290 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1291 //STPCPY(VG_Z_DYLD, stpcpy)
1293 #elif defined(VGO_solaris)
1294 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1296 #endif
1299 /*---------------------- stpncpy ----------------------*/
1301 #define STPNCPY(soname, fnname) \
1302 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1303 ( char* dst, const char* src, SizeT n ); \
1304 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1305 ( char* dst, const char* src, SizeT n ) \
1307 const HChar* src_orig = src; \
1308 HChar* dst_str = dst; \
1309 SizeT m = 0; \
1311 while (m < n && *src) { m++; *dst++ = *src++; } \
1312 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1313 /* but only m+1 bytes of src if terminator was found */ \
1314 SizeT srclen = (m < n) ? m+1 : n; \
1315 RECORD_COPY(srclen); \
1316 if (is_overlap(dst_str, src_orig, n, srclen)) \
1317 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1318 dst_str = dst; \
1319 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1321 return dst_str; \
1324 #if defined(VGO_linux) || defined(VGO_freebsd)
1325 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1326 #endif
1329 /*---------------------- memset ----------------------*/
1331 #define MEMSET(soname, fnname) \
1332 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1333 (void *s, Int c, SizeT n); \
1334 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1335 (void *s, Int c, SizeT n) \
1337 if (sizeof(void*) == 8) { \
1338 Addr a = (Addr)s; \
1339 ULong c8 = (c & 0xFF); \
1340 c8 = (c8 << 8) | c8; \
1341 c8 = (c8 << 16) | c8; \
1342 c8 = (c8 << 32) | c8; \
1343 while ((a & 7) != 0 && n >= 1) \
1344 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1345 while (n >= 32) \
1346 { *(ULong*)a = c8; a += 8; n -= 8; \
1347 *(ULong*)a = c8; a += 8; n -= 8; \
1348 *(ULong*)a = c8; a += 8; n -= 8; \
1349 *(ULong*)a = c8; a += 8; n -= 8; } \
1350 while (n >= 8) \
1351 { *(ULong*)a = c8; a += 8; n -= 8; } \
1352 while (n >= 1) \
1353 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1354 return s; \
1355 } else { \
1356 Addr a = (Addr)s; \
1357 UInt c4 = (c & 0xFF); \
1358 c4 = (c4 << 8) | c4; \
1359 c4 = (c4 << 16) | c4; \
1360 while ((a & 3) != 0 && n >= 1) \
1361 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1362 while (n >= 16) \
1363 { *(UInt*)a = c4; a += 4; n -= 4; \
1364 *(UInt*)a = c4; a += 4; n -= 4; \
1365 *(UInt*)a = c4; a += 4; n -= 4; \
1366 *(UInt*)a = c4; a += 4; n -= 4; } \
1367 while (n >= 4) \
1368 { *(UInt*)a = c4; a += 4; n -= 4; } \
1369 while (n >= 1) \
1370 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1371 return s; \
1375 #if defined(VGO_linux)
1376 MEMSET(VG_Z_LIBC_SONAME, memset)
1378 #elif defined(VGO_freebsd)
1379 MEMSET(VG_Z_LIBC_SONAME, memset)
1380 MEMSET(VG_Z_LD_ELF_SO_1, memset)
1381 MEMSET(VG_Z_LD_ELF32_SO_1, memset)
1383 #elif defined(VGO_darwin)
1384 //MEMSET(VG_Z_LIBC_SONAME, memset)
1385 //MEMSET(VG_Z_DYLD, memset)
1386 MEMSET(VG_Z_LIBC_SONAME, memset)
1388 #elif defined(VGO_solaris)
1389 MEMSET(VG_Z_LIBC_SONAME, memset)
1390 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1392 #endif
1395 /*---------------------- memmove ----------------------*/
1397 /* memmove -- use the MEMMOVE defn above. */
1399 #if defined(VGO_linux)
1400 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1401 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1402 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1403 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1404 to call memcpy. */
1405 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1407 #elif defined(VGO_freebsd)
1408 MEMMOVE(VG_Z_LD_ELF_SO_1, memmove)
1409 MEMMOVE(VG_Z_LD_ELF32_SO_1, memmove)
1410 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1412 #elif defined(VGO_darwin)
1413 # if DARWIN_VERS <= DARWIN_10_6
1414 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1415 # endif
1416 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1417 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1418 # if DARWIN_VERS >= DARWIN_10_9
1419 /* _platform_memmove$VARIANT$Ivybridge */
1420 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1421 # endif
1423 #elif defined(VGO_solaris)
1424 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1425 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1426 MEMMOVE(VG_Z_LD_SO_1, memmove)
1428 #endif
1431 /*---------------------- bcopy ----------------------*/
1433 #define BCOPY(soname, fnname) \
1434 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1435 (const void *srcV, void *dstV, SizeT n); \
1436 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1437 (const void *srcV, void *dstV, SizeT n) \
1439 RECORD_COPY(n); \
1440 SizeT i; \
1441 HChar* dst = dstV; \
1442 const HChar* src = srcV; \
1443 if (dst < src) { \
1444 for (i = 0; i < n; i++) \
1445 dst[i] = src[i]; \
1447 else \
1448 if (dst > src) { \
1449 for (i = 0; i < n; i++) \
1450 dst[n-i-1] = src[n-i-1]; \
1454 #if defined(VGO_linux)
1455 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1457 #elif defined(VGO_freebsd)
1458 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1459 BCOPY(VG_Z_LD_ELF_SO_1, bcopy)
1460 BCOPY(VG_Z_LD_ELF32_SO_1, bcopy)
1462 #elif defined(VGO_darwin)
1463 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1464 //BCOPY(VG_Z_DYLD, bcopy)
1466 #elif defined(VGO_darwin)
1467 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1469 #endif
1472 /*-------------------- memmove_chk --------------------*/
1474 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1475 There is no specific part of glibc that this is copied from. */
1476 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1477 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1478 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1479 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1480 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1482 RECORD_COPY(n); \
1483 SizeT i; \
1484 HChar* dst = dstV; \
1485 const HChar* src = srcV; \
1486 if (destlen < n) \
1487 goto badness; \
1488 if (dst < src) { \
1489 for (i = 0; i < n; i++) \
1490 dst[i] = src[i]; \
1492 else \
1493 if (dst > src) { \
1494 for (i = 0; i < n; i++) \
1495 dst[n-i-1] = src[n-i-1]; \
1497 return dst; \
1498 badness: \
1499 VALGRIND_PRINTF_BACKTRACE( \
1500 "*** memmove_chk: buffer overflow detected ***: " \
1501 "program terminated\n"); \
1502 my_exit(1); \
1503 /*NOTREACHED*/ \
1504 return NULL; \
1507 #if defined(VGO_linux)
1508 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1510 #elif defined(VGO_darwin)
1512 #elif defined(VGO_solaris)
1514 #endif
1517 /*-------------------- strchrnul --------------------*/
1519 /* Find the first occurrence of C in S or the final NUL byte. */
1520 #define GLIBC232_STRCHRNUL(soname, fnname) \
1521 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1522 (const char* s, int c_in); \
1523 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1524 (const char* s, int c_in) \
1526 HChar c = (HChar) c_in; \
1527 const HChar* char_ptr = s; \
1528 while (1) { \
1529 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1530 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1531 char_ptr++; \
1535 #if defined(VGO_linux)
1536 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1538 #elif defined(VGO_freebsd)
1539 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1541 #elif defined(VGO_darwin)
1543 #elif defined(VGO_solaris)
1545 #endif
1548 /*---------------------- rawmemchr ----------------------*/
1550 /* Find the first occurrence of C in S. */
1551 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1552 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1553 (const void* s, int c_in); \
1554 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1555 (const void* s, int c_in) \
1557 UChar c = (UChar) c_in; \
1558 const UChar* char_ptr = s; \
1559 while (1) { \
1560 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1561 char_ptr++; \
1565 #if defined (VGO_linux)
1566 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1567 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1569 #elif defined(VGO_darwin)
1571 #elif defined(VGO_solaris)
1573 #endif
1576 /*---------------------- strcpy_chk ----------------------*/
1578 /* glibc variant of strcpy that checks the dest is big enough.
1579 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1580 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1581 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1582 (char* dst, const char* src, SizeT len); \
1583 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1584 (char* dst, const char* src, SizeT len) \
1586 FOR_COPY(const HChar* src_orig = src); \
1587 HChar* ret = dst; \
1588 if (! len) \
1589 goto badness; \
1590 while ((*dst++ = *src++) != '\0') \
1591 if (--len == 0) \
1592 goto badness; \
1593 RECORD_COPY((Addr)src-(Addr)src_orig); \
1594 return ret; \
1595 badness: \
1596 VALGRIND_PRINTF_BACKTRACE( \
1597 "*** strcpy_chk: buffer overflow detected ***: " \
1598 "program terminated\n"); \
1599 my_exit(1); \
1600 /*NOTREACHED*/ \
1601 return NULL; \
1604 #if defined(VGO_linux)
1605 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1607 #elif defined(VGO_darwin)
1609 #elif defined(VGO_solaris)
1611 #endif
1614 /*---------------------- stpcpy_chk ----------------------*/
1616 /* glibc variant of stpcpy that checks the dest is big enough.
1617 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1618 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1619 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1620 (char* dst, const char* src, SizeT len); \
1621 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1622 (char* dst, const char* src, SizeT len) \
1624 FOR_COPY(const HChar* src_orig = src); \
1625 if (! len) \
1626 goto badness; \
1627 while ((*dst++ = *src++) != '\0') \
1628 if (--len == 0) \
1629 goto badness; \
1630 RECORD_COPY((Addr)src-(Addr)src_orig); \
1631 return dst - 1; \
1632 badness: \
1633 VALGRIND_PRINTF_BACKTRACE( \
1634 "*** stpcpy_chk: buffer overflow detected ***: " \
1635 "program terminated\n"); \
1636 my_exit(1); \
1637 /*NOTREACHED*/ \
1638 return NULL; \
1641 #if defined(VGO_linux)
1642 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1644 #elif defined(VGO_darwin)
1646 #elif defined(VGO_solaris)
1648 #endif
1651 /*---------------------- mempcpy ----------------------*/
1653 /* mempcpy */
1654 #define GLIBC25_MEMPCPY(soname, fnname) \
1655 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1656 ( void *dst, const void *src, SizeT len ); \
1657 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1658 ( void *dst, const void *src, SizeT len ) \
1660 RECORD_COPY(len); \
1661 SizeT len_saved = len; \
1663 if (len == 0) \
1664 return dst; \
1666 if (is_overlap(dst, src, len, len)) \
1667 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1669 if ( dst > src ) { \
1670 register HChar *d = (char *)dst + len - 1; \
1671 register const HChar *s = (const char *)src + len - 1; \
1672 while ( len-- ) { \
1673 *d-- = *s--; \
1675 } else if ( dst < src ) { \
1676 register HChar *d = dst; \
1677 register const HChar *s = src; \
1678 while ( len-- ) { \
1679 *d++ = *s++; \
1682 return (void*)( ((char*)dst) + len_saved ); \
1685 #if defined(VGO_linux)
1686 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1687 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1688 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1689 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1690 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1692 #elif defined(VGO_freebsd)
1693 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1694 #elif defined(VGO_darwin)
1695 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1697 #elif defined(VGO_solaris)
1699 #endif
1702 /*-------------------- memcpy_chk --------------------*/
1704 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1705 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1706 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1707 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1708 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1710 register HChar *d; \
1711 register const HChar *s; \
1712 if (dstlen < len) \
1713 goto badness; \
1714 RECORD_COPY(len); \
1715 if (len == 0) \
1716 return dst; \
1717 if (is_overlap(dst, src, len, len)) \
1718 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1719 if ( dst > src ) { \
1720 d = (HChar *)dst + len - 1; \
1721 s = (const HChar *)src + len - 1; \
1722 while ( len-- ) { \
1723 *d-- = *s--; \
1725 } else if ( dst < src ) { \
1726 d = (HChar *)dst; \
1727 s = (const HChar *)src; \
1728 while ( len-- ) { \
1729 *d++ = *s++; \
1732 return dst; \
1733 badness: \
1734 VALGRIND_PRINTF_BACKTRACE( \
1735 "*** memcpy_chk: buffer overflow detected ***: " \
1736 "program terminated\n"); \
1737 my_exit(1); \
1738 /*NOTREACHED*/ \
1739 return NULL; \
1742 #if defined(VGO_linux)
1743 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1745 #elif defined(VGO_darwin)
1747 #elif defined(VGO_solaris)
1749 #endif
1752 /*---------------------- strstr ----------------------*/
1754 #define STRSTR(soname, fnname) \
1755 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1756 (const char* haystack, const char* needle); \
1757 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1758 (const char* haystack, const char* needle) \
1760 const HChar* h = haystack; \
1761 const HChar* n = needle; \
1763 /* find the length of n, not including terminating zero */ \
1764 UWord nlen = 0; \
1765 while (n[nlen]) nlen++; \
1767 /* if n is the empty string, match immediately. */ \
1768 if (nlen == 0) return CONST_CAST(HChar *,h); \
1770 /* assert(nlen >= 1); */ \
1771 HChar n0 = n[0]; \
1773 while (1) { \
1774 const HChar hh = *h; \
1775 if (hh == 0) return NULL; \
1776 if (hh != n0) { h++; continue; } \
1778 UWord i; \
1779 for (i = 0; i < nlen; i++) { \
1780 if (n[i] != h[i]) \
1781 break; \
1783 /* assert(i >= 0 && i <= nlen); */ \
1784 if (i == nlen) \
1785 return CONST_CAST(HChar *,h); \
1787 h++; \
1791 #if defined(VGO_linux)
1792 STRSTR(VG_Z_LIBC_SONAME, strstr)
1793 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1794 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1796 #elif defined(VGO_freebsd)
1797 STRSTR(VG_Z_LIBC_SONAME, strstr)
1799 #elif defined(VGO_darwin)
1801 #elif defined(VGO_solaris)
1802 STRSTR(VG_Z_LIBC_SONAME, strstr)
1804 #endif
1806 /*---------------------- memmem ----------------------*/
1808 #define MEMMEM(soname, fnname) \
1809 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1810 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1811 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1812 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1814 const HChar* h = haystack; \
1815 const HChar* n = needle; \
1817 /* If the needle is the empty string, match immediately. */ \
1818 if (nlen == 0) return CONST_CAST(void *,h); \
1820 HChar n0 = n[0]; \
1822 for (; hlen >= nlen; hlen--, h++) { \
1823 if (h[0] != n0) continue; \
1825 UWord i; \
1826 for (i = 1; i < nlen; i++) { \
1827 if (n[i] != h[i]) \
1828 break; \
1830 if (i == nlen) \
1831 return CONST_CAST(HChar *,h); \
1834 return NULL; \
1837 #if defined(VGP_s390x_linux)
1838 MEMMEM(VG_Z_LIBC_SONAME, memmem)
1839 #endif
1842 /*---------------------- strpbrk ----------------------*/
1844 #define STRPBRK(soname, fnname) \
1845 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1846 (const char* sV, const char* acceptV); \
1847 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1848 (const char* sV, const char* acceptV) \
1850 const HChar* s = sV; \
1851 const HChar* accept = acceptV; \
1853 /* find the length of 'accept', not including terminating zero */ \
1854 UWord nacc = 0; \
1855 while (accept[nacc]) nacc++; \
1857 /* if n is the empty string, fail immediately. */ \
1858 if (nacc == 0) return NULL; \
1860 /* assert(nacc >= 1); */ \
1861 while (1) { \
1862 UWord i; \
1863 HChar sc = *s; \
1864 if (sc == 0) \
1865 break; \
1866 for (i = 0; i < nacc; i++) { \
1867 if (sc == accept[i]) \
1868 return CONST_CAST(HChar *,s); \
1870 s++; \
1873 return NULL; \
1876 #if defined(VGO_linux)
1877 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1879 #elif defined(VGO_freebsd)
1880 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1882 #elif defined(VGO_darwin)
1884 #elif defined(VGO_solaris)
1885 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1887 #endif
1890 /*---------------------- strcspn ----------------------*/
1892 #define STRCSPN(soname, fnname) \
1893 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1894 (const char* sV, const char* rejectV); \
1895 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1896 (const char* sV, const char* rejectV) \
1898 const HChar* s = sV; \
1899 const HChar* reject = rejectV; \
1901 /* find the length of 'reject', not including terminating zero */ \
1902 UWord nrej = 0; \
1903 while (reject[nrej]) nrej++; \
1905 UWord len = 0; \
1906 while (1) { \
1907 UWord i; \
1908 HChar sc = *s; \
1909 if (sc == 0) \
1910 break; \
1911 for (i = 0; i < nrej; i++) { \
1912 if (sc == reject[i]) \
1913 break; \
1915 /* assert(i >= 0 && i <= nrej); */ \
1916 if (i < nrej) \
1917 break; \
1918 s++; \
1919 len++; \
1922 return len; \
1925 #if defined(VGO_linux)
1926 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1927 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1929 #elif defined(VGO_freebsd)
1930 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1932 #elif defined(VGO_darwin)
1934 #elif defined(VGO_solaris)
1935 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1937 #endif
1940 /*---------------------- strspn ----------------------*/
1942 #define STRSPN(soname, fnname) \
1943 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1944 (const char* sV, const char* acceptV); \
1945 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1946 (const char* sV, const char* acceptV) \
1948 const UChar* s = (const UChar *)sV; \
1949 const UChar* accept = (const UChar *)acceptV; \
1951 /* find the length of 'accept', not including terminating zero */ \
1952 UWord nacc = 0; \
1953 while (accept[nacc]) nacc++; \
1954 if (nacc == 0) return 0; \
1956 UWord len = 0; \
1957 while (1) { \
1958 UWord i; \
1959 UChar sc = *s; \
1960 if (sc == 0) \
1961 break; \
1962 for (i = 0; i < nacc; i++) { \
1963 if (sc == accept[i]) \
1964 break; \
1966 /* assert(i >= 0 && i <= nacc); */ \
1967 if (i == nacc) \
1968 break; \
1969 s++; \
1970 len++; \
1973 return len; \
1976 #if defined(VGO_linux)
1977 STRSPN(VG_Z_LIBC_SONAME, strspn)
1979 #elif defined(VGO_freebsd)
1980 STRSPN(VG_Z_LIBC_SONAME, strspn)
1982 #elif defined(VGO_darwin)
1984 #elif defined(VGO_solaris)
1985 STRSPN(VG_Z_LIBC_SONAME, strspn)
1987 #endif
1990 /*---------------------- strcasestr ----------------------*/
1992 #define STRCASESTR(soname, fnname) \
1993 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1994 (const char* haystack, const char* needle); \
1995 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1996 (const char* haystack, const char* needle) \
1998 extern int tolower(int); \
1999 const HChar* h = haystack; \
2000 const HChar* n = needle; \
2002 /* find the length of n, not including terminating zero */ \
2003 UWord nlen = 0; \
2004 while (n[nlen]) nlen++; \
2006 /* if n is the empty string, match immediately. */ \
2007 if (nlen == 0) return CONST_CAST(HChar *,h); \
2009 /* assert(nlen >= 1); */ \
2010 UChar n0 = tolower(n[0]); \
2012 while (1) { \
2013 UChar hh = tolower(*h); \
2014 if (hh == 0) return NULL; \
2015 if (hh != n0) { h++; continue; } \
2017 UWord i; \
2018 for (i = 0; i < nlen; i++) { \
2019 if (tolower(n[i]) != tolower(h[i])) \
2020 break; \
2022 /* assert(i >= 0 && i <= nlen); */ \
2023 if (i == nlen) \
2024 return CONST_CAST(HChar *,h); \
2026 h++; \
2030 #if defined(VGO_linux)
2031 # if !defined(VGPV_arm_linux_android) \
2032 && !defined(VGPV_x86_linux_android) \
2033 && !defined(VGPV_mips32_linux_android) \
2034 && !defined(VGPV_arm64_linux_android)
2035 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2036 # endif
2038 #elif defined(VGO_freebsd)
2039 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2041 #elif defined(VGO_darwin)
2043 #elif defined(VGO_solaris)
2044 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2046 #endif
2049 /*---------------------- wcslen ----------------------*/
2051 // This is a wchar_t equivalent to strlen. Unfortunately
2052 // we don't have wchar_t available here, but it looks like
2053 // a 32 bit int on Linux. I don't know if that is also
2054 // valid on MacOSX.
2056 #define WCSLEN(soname, fnname) \
2057 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2058 ( const Int* str ); \
2059 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2060 ( const Int* str ) \
2062 SizeT i = 0; \
2063 while (str[i] != 0) i++; \
2064 return i; \
2067 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2068 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
2070 #endif
2072 /*---------------------- wcsnlen ----------------------*/
2074 #define WCSNLEN(soname, fnname) \
2075 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2076 ( const Int *s, SizeT n ); \
2077 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2078 ( const Int *s, SizeT n ) \
2080 SizeT i = 0; \
2081 const Int* p = s; \
2082 while (i < n && *p != 0) { \
2083 i++; \
2084 p++; \
2086 return i; \
2089 #if defined(VGO_linux) || defined(VGO_freebsd)
2090 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
2091 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
2092 #endif
2094 /*---------------------- wcscmp ----------------------*/
2096 // This is a wchar_t equivalent to strcmp. We don't
2097 // have wchar_t available here, but in the GNU C Library
2098 // wchar_t is always 32 bits wide and wcscmp uses signed
2099 // comparison, not unsigned as in strcmp function.
2101 #define WCSCMP(soname, fnname) \
2102 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2103 ( const Int* s1, const Int* s2 ); \
2104 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2105 ( const Int* s1, const Int* s2 ) \
2107 register Int c1; \
2108 register Int c2; \
2109 while (True) { \
2110 c1 = *s1; \
2111 c2 = *s2; \
2112 if (c1 != c2) break; \
2113 if (c1 == 0) break; \
2114 s1++; s2++; \
2116 if (c1 < c2) return -1; \
2117 if (c1 > c2) return 1; \
2118 return 0; \
2121 #if defined(VGO_linux) || defined(VGO_freebsd)
2122 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
2123 #endif
2125 /*---------------------- wcsncmp ----------------------*/
2127 // This is a wchar_t equivalent to strncmp. We don't
2128 // have wchar_t available here, but in the GNU C Library
2129 // wchar_t is always 32 bits wide and wcsncmp uses signed
2130 // comparison, not unsigned as in strncmp function.
2132 #define WCSNCMP(soname, fnname) \
2133 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2134 ( const Int* s1, const Int* s2, SizeT nmax ); \
2135 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2136 ( const Int* s1, const Int* s2, SizeT nmax ) \
2138 SizeT n = 0; \
2139 while (True) { \
2140 if (n >= nmax) return 0; \
2141 if (*s1 == 0 && *s2 == 0) return 0; \
2142 if (*s1 == 0) return -1; \
2143 if (*s2 == 0) return 1; \
2145 if (*s1 < *s2) return -1; \
2146 if (*s1 > *s2) return 1; \
2148 s1++; s2++; n++; \
2151 #if defined(VGO_linux) || defined(VGO_freebsd)
2152 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
2153 #endif
2155 /*---------------------- wcscpy ----------------------*/
2157 // This is a wchar_t equivalent to strcpy. We don't
2158 // have wchar_t available here, but in the GNU C Library
2159 // wchar_t is always 32 bits wide.
2161 #define WCSCPY(soname, fnname) \
2162 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2163 ( Int* dst, const Int* src ); \
2164 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2165 ( Int* dst, const Int* src ) \
2167 const Int* src_orig = src; \
2168 Int* dst_orig = dst; \
2170 while (*src) *dst++ = *src++; \
2171 *dst = 0; \
2173 /* This checks for overlap after copying, unavoidable without */ \
2174 /* pre-counting length... should be ok */ \
2175 /* +4 because sizeof(wchar_t) == 4 */ \
2176 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2177 RECORD_COPY(srclen); \
2178 if (is_overlap(dst_orig, \
2179 src_orig, \
2180 /* +4 because sizeof(wchar_t) == 4 */ \
2181 (Addr)dst-(Addr)dst_orig+4, \
2182 srclen)) \
2183 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2185 return dst_orig; \
2188 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2189 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2190 #endif
2193 /*---------------------- wcschr ----------------------*/
2195 // This is a wchar_t equivalent to strchr. We don't
2196 // have wchar_t available here, but in the GNU C Library
2197 // wchar_t is always 32 bits wide.
2199 #define WCSCHR(soname, fnname) \
2200 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2201 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2203 const Int* p = s; \
2204 while (True) { \
2205 if (*p == c) return CONST_CAST(Int *,p); \
2206 if (*p == 0) return NULL; \
2207 p++; \
2211 #if defined(VGO_linux) || defined(VGO_freebsd)
2212 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2213 #endif
2214 /*---------------------- wcsrchr ----------------------*/
2216 // This is a wchar_t equivalent to strrchr. We don't
2217 // have wchar_t available here, but in the GNU C Library
2218 // wchar_t is always 32 bits wide.
2220 #define WCSRCHR(soname, fnname) \
2221 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2222 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2224 const Int* p = s; \
2225 const Int* last = NULL; \
2226 while (True) { \
2227 if (*p == c) last = p; \
2228 if (*p == 0) return CONST_CAST(Int *,last); \
2229 p++; \
2233 #if defined(VGO_linux) || defined(VGO_freebsd)
2234 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2235 #endif
2237 /*---------------------- wmemchr ----------------------*/
2239 // This is a wchar_t equivalent to memchr. We don't
2240 // have wchar_t available here, but in the GNU C Library
2241 // wchar_t is always 32 bits wide.
2243 #define WMEMCHR(soname, fnname) \
2244 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2245 (const Int *s, Int c, SizeT n); \
2246 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2247 (const Int *s, Int c, SizeT n) \
2249 SizeT i; \
2250 const Int* p = s; \
2251 for (i = 0; i < n; i++) { \
2252 if (*p == c) return CONST_CAST(Int *,p); \
2253 p++; \
2255 return NULL; \
2258 #if defined(VGO_linux)
2259 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2260 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2261 #endif
2263 #if defined(VGO_freebsd)
2264 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2265 #endif
2268 #define WMEMCMP(soname, fnname) \
2269 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2270 ( const Int *b1, const Int *b2, SizeT n ); \
2271 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2272 ( const Int *b1, const Int *b2, SizeT n ) \
2274 for (SizeT i = 0U; i < n; ++i) { \
2275 if (b1[i] != b2[i]) \
2276 return b1[i] > b2[i] ? 1 : -1; \
2278 return 0; \
2281 #if defined(VGO_linux)
2282 WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
2283 #endif
2286 /*------------------------------------------------------------*/
2287 /*--- Improve definedness checking of process environment ---*/
2288 /*------------------------------------------------------------*/
2290 #if defined(VGO_linux) || defined(VGO_freebsd)
2292 /* If these wind up getting generated via a macro, so that multiple
2293 versions of each function exist (as above), use the _EZU variants
2294 to assign equivalance class tags. */
2296 /*---------------------- putenv ----------------------*/
2298 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2299 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2301 OrigFn fn;
2302 Word result;
2303 const HChar* p = string;
2304 VALGRIND_GET_ORIG_FN(fn);
2305 /* Now by walking over the string we magically produce
2306 traces when hitting undefined memory. */
2307 if (p)
2308 while (*p++)
2309 __asm__ __volatile__("" ::: "memory");
2310 CALL_FN_W_W(result, fn, string);
2311 return result;
2315 /*---------------------- unsetenv ----------------------*/
2317 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2318 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2320 OrigFn fn;
2321 Word result;
2322 const HChar* p = name;
2323 VALGRIND_GET_ORIG_FN(fn);
2324 /* Now by walking over the string we magically produce
2325 traces when hitting undefined memory. */
2326 if (p)
2327 while (*p++)
2328 __asm__ __volatile__("" ::: "memory");
2329 CALL_FN_W_W(result, fn, name);
2330 return result;
2334 /*---------------------- setenv ----------------------*/
2336 /* setenv */
2337 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2338 (const char* name, const char* value, int overwrite);
2339 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2340 (const char* name, const char* value, int overwrite)
2342 OrigFn fn;
2343 Word result;
2344 const HChar* p;
2345 VALGRIND_GET_ORIG_FN(fn);
2346 /* Now by walking over the string we magically produce
2347 traces when hitting undefined memory. */
2348 if (name)
2349 for (p = name; *p; p++)
2350 __asm__ __volatile__("" ::: "memory");
2351 if (value)
2352 for (p = value; *p; p++)
2353 __asm__ __volatile__("" ::: "memory");
2354 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2355 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2356 return result;
2359 #endif /* defined(VGO_linux) */
2361 /*--------------------------------------------------------------------*/
2362 /*--- end ---*/
2363 /*--------------------------------------------------------------------*/