Bug 401284 - False positive "Source and destination overlap in strncat"
[valgrind.git] / shared / vg_replace_strmem.c
blob747b903fefd93530779fe33115ee26c234d4c635
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
108 20480 WCSNCPY
111 #if defined(VGO_solaris)
113 Detour functions in the libc and the runtime linker. If a function isn't
114 much optimized (and no overlap checking is necessary) then redir the
115 function only in the libc. This way we can keep stacktraces in the tests
116 consistent.
118 #endif
121 /* Figure out if [dst .. dst+dstlen-1] overlaps with
122 [src .. src+srclen-1].
123 We assume that the address ranges do not wrap around
124 (which is safe since on Linux addresses >= 0xC0000000
125 are not accessible and the program will segfault in this
126 circumstance, presumably).
128 static inline
129 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
131 Addr loS, hiS, loD, hiD;
133 if (dstlen == 0 || srclen == 0)
134 return False;
136 loS = (Addr)src;
137 loD = (Addr)dst;
138 hiS = loS + srclen - 1;
139 hiD = loD + dstlen - 1;
141 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
142 if (loS < loD) {
143 return !(hiS < loD);
145 else if (loD < loS) {
146 return !(hiD < loS);
148 else {
149 /* They start at same place. Since we know neither of them has
150 zero length, they must overlap. */
151 return True;
156 /* Call here to exit if we can't continue. On Android we can't call
157 _exit for some reason, so we have to blunt-instrument it. */
158 __attribute__ ((__noreturn__))
159 static inline void my_exit ( int x )
161 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
162 || defined(VGPV_arm64_linux_android)
163 __asm__ __volatile__(".word 0xFFFFFFFF");
164 while (1) {}
165 # elif defined(VGPV_x86_linux_android)
166 __asm__ __volatile__("ud2");
167 while (1) {}
168 # else
169 extern __attribute__ ((__noreturn__)) void _exit(int status);
170 _exit(x);
171 # endif
175 // This is a macro rather than a function because we don't want to have an
176 // extra function in the stack trace.
177 #ifndef RECORD_OVERLAP_ERROR
178 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
179 #endif
181 // Used for tools that record bulk copies: memcpy, strcpy, etc.
182 #ifndef RECORD_COPY
183 #define RECORD_COPY(len) do { } while (0)
184 #define FOR_COPY(x)
185 #else
186 #define FOR_COPY(x) x
187 #endif
189 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
190 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
191 #endif
194 /*---------------------- strrchr ----------------------*/
196 #define STRRCHR(soname, fnname) \
197 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
198 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
200 HChar ch = (HChar)c; \
201 const HChar* p = s; \
202 const HChar* last = NULL; \
203 while (True) { \
204 if (*p == ch) last = p; \
205 if (*p == 0) return CONST_CAST(HChar *,last); \
206 p++; \
210 // Apparently rindex() is the same thing as strrchr()
211 #if defined(VGO_linux)
212 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
213 STRRCHR(VG_Z_LIBC_SONAME, rindex)
214 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
215 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
216 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
217 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
218 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
219 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
220 || defined(VGPV_mips32_linux_android)
221 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
222 #endif
224 #elif defined(VGO_freebsd)
225 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
226 STRRCHR(VG_Z_LIBC_SONAME, rindex)
227 STRRCHR(VG_Z_LD_ELF_SO_1, strrchr)
228 STRRCHR(VG_Z_LD_ELF32_SO_1, strrchr)
230 #elif defined(VGO_darwin)
231 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
232 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
233 //STRRCHR(VG_Z_DYLD, strrchr)
234 //STRRCHR(VG_Z_DYLD, rindex)
235 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
236 # if DARWIN_VERS >= DARWIN_10_9
237 STRRCHR(libsystemZucZddylib, strrchr)
238 # endif
240 #elif defined(VGO_solaris)
241 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
242 STRRCHR(VG_Z_LIBC_SONAME, rindex)
243 STRRCHR(VG_Z_LD_SO_1, strrchr)
245 #endif
248 /*---------------------- strchr ----------------------*/
250 #define STRCHR(soname, fnname) \
251 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
252 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
254 HChar ch = (HChar)c ; \
255 const HChar* p = s; \
256 while (True) { \
257 if (*p == ch) return CONST_CAST(HChar *,p); \
258 if (*p == 0) return NULL; \
259 p++; \
263 // Apparently index() is the same thing as strchr()
264 #if defined(VGO_linux)
265 STRCHR(VG_Z_LIBC_SONAME, strchr)
266 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
267 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
268 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
269 STRCHR(VG_Z_LIBC_SONAME, index)
270 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
271 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
272 STRCHR(VG_Z_LD_LINUX_SO_2, index)
273 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
274 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
275 # endif
277 #if defined(VGPV_mips32_linux_android)
278 STRCHR(NONE, __dl_strchr)
279 #endif
281 #elif defined(VGO_freebsd)
282 STRCHR(VG_Z_LIBC_SONAME, strchr)
283 STRCHR(VG_Z_LIBC_SONAME, index)
284 STRCHR(VG_Z_LD_ELF_SO_1, strchr)
285 STRCHR(VG_Z_LD_ELF32_SO_1, strchr)
287 #elif defined(VGO_darwin)
288 STRCHR(VG_Z_LIBC_SONAME, strchr)
289 # if DARWIN_VERS == DARWIN_10_9
290 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
291 # endif
292 # if DARWIN_VERS >= DARWIN_10_10
293 /* _platform_strchr$VARIANT$Generic */
294 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
295 /* _platform_strchr$VARIANT$Haswell */
296 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
297 # endif
298 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Base)
300 #elif defined(VGO_solaris)
301 STRCHR(VG_Z_LIBC_SONAME, strchr)
302 STRCHR(VG_Z_LIBC_SONAME, index)
303 STRCHR(VG_Z_LD_SO_1, strchr)
305 #endif
308 /*---------------------- strcat ----------------------*/
310 #define STRCAT(soname, fnname) \
311 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
312 ( char* dst, const char* src ); \
313 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
314 ( char* dst, const char* src ) \
316 const HChar* src_orig = src; \
317 HChar* dst_orig = dst; \
318 while (*dst) dst++; \
319 while (*src) *dst++ = *src++; \
320 *dst = 0; \
322 /* This is a bit redundant, I think; any overlap and the strcat will */ \
323 /* go forever... or until a seg fault occurs. */ \
324 if (is_overlap(dst_orig, \
325 src_orig, \
326 (Addr)dst-(Addr)dst_orig+1, \
327 (Addr)src-(Addr)src_orig+1)) \
328 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
330 return dst_orig; \
333 #if defined(VGO_linux)
334 STRCAT(VG_Z_LIBC_SONAME, strcat)
335 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
337 #elif defined(VGO_freebsd)
338 STRCAT(VG_Z_LIBC_SONAME, strcat)
339 STRCAT(VG_Z_LD_ELF_SO_1, strcat)
340 STRCAT(VG_Z_LD_ELF32_SO_1, strcat)
342 #elif defined(VGO_darwin)
343 //STRCAT(VG_Z_LIBC_SONAME, strcat)
345 #elif defined(VGO_solaris)
346 STRCAT(VG_Z_LIBC_SONAME, strcat)
347 STRCAT(VG_Z_LD_SO_1, strcat)
349 #endif
352 /*---------------------- strncat ----------------------*/
354 #define STRNCAT(soname, fnname) \
355 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
356 ( char* dst, const char* src, SizeT n ); \
357 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
358 ( char* dst, const char* src, SizeT n ) \
360 const HChar* src_orig = src; \
361 HChar* dst_orig = dst; \
362 SizeT m = 0; \
364 while (*dst) dst++; \
365 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
366 *dst = 0; /* always add null */ \
368 /* This checks for overlap after copying, unavoidable without */ \
369 /* pre-counting lengths... should be ok */ \
370 if (is_overlap(dst_orig, \
371 src_orig, \
372 (Addr)dst-(Addr)dst_orig+1, \
373 (Addr)src-(Addr)src_orig)) \
374 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
376 return dst_orig; \
379 #if defined(VGO_linux)
380 STRNCAT(VG_Z_LIBC_SONAME, strncat)
382 #elif defined(VGO_freebsd)
383 STRNCAT(VG_Z_LIBC_SONAME, strncat)
385 #elif defined(VGO_darwin)
386 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
387 //STRNCAT(VG_Z_DYLD, strncat)
389 #elif defined(VGO_solaris)
390 STRNCAT(VG_Z_LIBC_SONAME, strncat)
392 #endif
395 /*---------------------- strlcat ----------------------*/
397 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
398 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
399 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
400 Truncation occurred if retval >= n.
402 #define STRLCAT(soname, fnname) \
403 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
404 ( char* dst, const char* src, SizeT n ); \
405 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
406 ( char* dst, const char* src, SizeT n ) \
408 const HChar* src_orig = src; \
409 HChar* dst_orig = dst; \
410 SizeT m = 0; \
412 while (m < n && *dst) { m++; dst++; } \
413 if (m < n) { \
414 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
415 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
416 *dst = 0; \
417 } else { \
418 /* No space to copy anything to dst. m == n */ \
420 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
421 while (*src) { m++; src++; } \
422 /* This checks for overlap after copying, unavoidable without */ \
423 /* pre-counting lengths... should be ok */ \
424 if (is_overlap(dst_orig, \
425 src_orig, \
426 (Addr)dst-(Addr)dst_orig+1, \
427 (Addr)src-(Addr)src_orig+1)) \
428 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
430 return m; \
433 #if defined(VGO_linux)
435 #elif defined(VGO_freebsd)
436 STRLCAT(VG_Z_LD_ELF_SO_1, strlcat)
437 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
438 STRLCAT(VG_Z_LD_ELF32_SO_1, strlcat)
440 #elif defined(VGO_darwin)
441 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
442 //STRLCAT(VG_Z_DYLD, strlcat)
443 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
445 #elif defined(VGO_solaris)
446 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
448 #endif
451 /*---------------------- strnlen ----------------------*/
453 #define STRNLEN(soname, fnname) \
454 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
455 ( const char* str, SizeT n ); \
456 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
457 ( const char* str, SizeT n ) \
459 SizeT i = 0; \
460 while (i < n && str[i] != 0) i++; \
461 return i; \
464 #if defined(VGO_linux)
465 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
466 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
468 #elif defined(VGO_freebsd)
470 STRNLEN(VG_Z_LIBC_SONAME, srtnlen)
472 #elif defined(VGO_darwin)
473 # if DARWIN_VERS == DARWIN_10_9
474 STRNLEN(libsystemZucZddylib, strnlen)
475 # endif
477 #elif defined(VGO_solaris)
478 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
480 #endif
483 /*---------------------- strlen ----------------------*/
485 // Note that this replacement often doesn't get used because gcc inlines
486 // calls to strlen() with its own built-in version. This can be very
487 // confusing if you aren't expecting it. Other small functions in
488 // this file may also be inline by gcc.
490 #define STRLEN(soname, fnname) \
491 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
492 ( const char* str ); \
493 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
494 ( const char* str ) \
496 SizeT i = 0; \
497 while (str[i] != 0) i++; \
498 return i; \
501 #if defined(VGO_linux)
502 STRLEN(VG_Z_LIBC_SONAME, strlen)
503 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
504 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
505 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
506 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
507 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
508 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
509 # if defined(VGPV_arm_linux_android) \
510 || defined(VGPV_x86_linux_android) \
511 || defined(VGPV_mips32_linux_android)
512 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
513 # endif
515 #elif defined(VGO_freebsd)
516 STRLEN(VG_Z_LIBC_SONAME, strlen)
517 STRLEN(VG_Z_LD_ELF_SO_1, strlen)
518 STRLEN(VG_Z_LD_ELF32_SO_1, strlen)
520 #elif defined(VGO_darwin)
521 STRLEN(VG_Z_LIBC_SONAME, strlen)
522 # if DARWIN_VERS >= DARWIN_10_9
523 STRLEN(libsystemZucZddylib, strlen)
524 # endif
526 #elif defined(VGO_solaris)
527 STRLEN(VG_Z_LIBC_SONAME, strlen)
528 STRLEN(VG_Z_LD_SO_1, strlen)
530 #endif
533 /*---------------------- strcpy ----------------------*/
535 #define STRCPY(soname, fnname) \
536 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
537 ( char* dst, const char* src ); \
538 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
539 ( char* dst, const char* src ) \
541 const HChar* src_orig = src; \
542 HChar* dst_orig = dst; \
544 while (*src) *dst++ = *src++; \
545 *dst = 0; \
547 /* This happens after copying, unavoidable without */ \
548 /* pre-counting length... should be ok */ \
549 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
550 RECORD_COPY(srclen); \
551 if (is_overlap(dst_orig, \
552 src_orig, \
553 (Addr)dst-(Addr)dst_orig+1, \
554 srclen)) \
555 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
557 return dst_orig; \
560 #if defined(VGO_linux)
561 STRCPY(VG_Z_LIBC_SONAME, strcpy)
562 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
564 #elif defined(VGO_freebsd)
565 STRCPY(VG_Z_LIBC_SONAME, strcpy)
566 STRCPY(VG_Z_LD_ELF_SO_1, strcpy)
567 STRCPY(VG_Z_LD_ELF32_SO_1, strcpy)
569 #elif defined(VGO_darwin)
570 STRCPY(VG_Z_LIBC_SONAME, strcpy)
571 # if DARWIN_VERS == DARWIN_10_9
572 STRCPY(libsystemZucZddylib, strcpy)
573 # endif
575 #elif defined(VGO_solaris)
576 STRCPY(VG_Z_LIBC_SONAME, strcpy)
577 STRCPY(VG_Z_LD_SO_1, strcpy)
579 #endif
582 /*---------------------- strncpy ----------------------*/
584 #define STRNCPY(soname, fnname) \
585 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
586 ( char* dst, const char* src, SizeT n ); \
587 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
588 ( char* dst, const char* src, SizeT n ) \
590 const HChar* src_orig = src; \
591 HChar* dst_orig = dst; \
592 SizeT m = 0; \
594 while (m < n && *src) { m++; *dst++ = *src++; } \
595 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
596 /* but only m+1 bytes of src if terminator was found */ \
597 SizeT srclen = (m < n) ? m+1 : n; \
598 RECORD_COPY(srclen); \
599 if (is_overlap(dst_orig, src_orig, n, srclen)) \
600 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
601 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
603 return dst_orig; \
606 #if defined(VGO_linux)
607 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
608 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
609 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
610 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
612 #elif defined(VGO_freebsd)
613 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
614 STRNCPY(VG_Z_LD_ELF_SO_1, strncpy)
615 STRNCPY(VG_Z_LD_ELF32_SO_1, strncpy)
617 #elif defined(VGO_darwin)
618 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
619 # if DARWIN_VERS >= DARWIN_10_9
620 STRNCPY(libsystemZucZddylib, strncpy)
621 # endif
623 #elif defined(VGO_solaris)
624 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
625 STRNCPY(VG_Z_LD_SO_1, strncpy)
627 #endif
630 /*---------------------- strlcpy ----------------------*/
632 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
633 Returns strlen(src). Does not zero-fill the remainder of dst. */
634 #define STRLCPY(soname, fnname) \
635 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
636 ( char* dst, const char* src, SizeT n ); \
637 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
638 ( char* dst, const char* src, SizeT n ) \
640 const HChar* src_orig = src; \
641 HChar* dst_orig = dst; \
642 SizeT m = 0; \
644 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
646 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
647 /* m non-nul bytes have now been copied, and m <= n-1. */ \
648 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
649 /* but only m+1 bytes of src if terminator was found */ \
650 SizeT srclen = (m < n) ? m+1 : n; \
651 RECORD_COPY(srclen); \
652 if (is_overlap(dst_orig, src_orig, n, srclen)) \
653 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
654 /* Nul-terminate dst. */ \
655 if (n > 0) *dst = 0; \
656 /* Finish counting strlen(src). */ \
657 while (*src) src++; \
658 return src - src_orig; \
661 #if defined(VGO_linux)
663 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
664 || defined(VGPV_mips32_linux_android)
665 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
666 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
667 #endif
669 #elif defined(VGO_freebsd)
670 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
671 STRLCPY(VG_Z_LD_ELF_SO_1, strlcpy)
672 STRLCPY(VG_Z_LD_ELF32_SO_1, strlcpy)
673 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
675 #elif defined(VGO_darwin)
676 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
677 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
678 //STRLCPY(VG_Z_DYLD, strlcpy)
679 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
681 #elif defined(VGO_solaris)
682 /* special case for n == 0 which is undocumented but heavily used */
683 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
684 if (n == 0) { \
685 while (*src) src++; \
686 return src - src_orig; \
689 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
691 #endif
694 /*---------------------- strncmp ----------------------*/
696 #define STRNCMP(soname, fnname) \
697 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
698 ( const char* s1, const char* s2, SizeT nmax ); \
699 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
700 ( const char* s1, const char* s2, SizeT nmax ) \
702 SizeT n = 0; \
703 while (True) { \
704 if (n >= nmax) return 0; \
705 if (*s1 == 0 && *s2 == 0) return 0; \
706 if (*s1 == 0) return -1; \
707 if (*s2 == 0) return 1; \
709 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
710 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
712 s1++; s2++; n++; \
716 #if defined(VGO_linux)
717 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
718 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
719 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
720 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
721 STRNCMP(VG_Z_LD_LINUX_SO_2, strncmp)
722 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2, strncmp)
724 #elif defined(VGO_freebsd)
725 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
726 STRNCMP(VG_Z_LD_ELF_SO_1, strncmp)
727 STRNCMP(VG_Z_LD_ELF32_SO_1, strncmp)
729 #elif defined(VGO_darwin)
730 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
731 # if DARWIN_VERS >= DARWIN_10_9
732 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
733 # endif
735 #elif defined(VGO_solaris)
736 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
738 #endif
741 /*---------------------- strcasecmp ----------------------*/
743 #define STRCASECMP(soname, fnname) \
744 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
745 ( const char* s1, const char* s2 ); \
746 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
747 ( const char* s1, const char* s2 ) \
749 extern int tolower(int); \
750 register UChar c1; \
751 register UChar c2; \
752 while (True) { \
753 c1 = tolower(*(const UChar *)s1); \
754 c2 = tolower(*(const UChar *)s2); \
755 if (c1 != c2) break; \
756 if (c1 == 0) break; \
757 s1++; s2++; \
759 if ((UChar)c1 < (UChar)c2) return -1; \
760 if ((UChar)c1 > (UChar)c2) return 1; \
761 return 0; \
764 #if defined(VGO_linux)
765 # if !defined(VGPV_arm_linux_android) \
766 && !defined(VGPV_x86_linux_android) \
767 && !defined(VGPV_mips32_linux_android) \
768 && !defined(VGPV_arm64_linux_android)
769 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
770 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
771 # endif
773 #elif defined(VGO_freebsd)
774 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
775 STRNCMP(VG_Z_LD_ELF_SO_1, strcasecmp)
776 STRNCMP(VG_Z_LD_ELF32_SO_1, strcasecmp)
778 #elif defined(VGO_darwin)
779 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
781 #elif defined(VGO_solaris)
782 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
784 #endif
787 /*---------------------- strncasecmp ----------------------*/
789 #define STRNCASECMP(soname, fnname) \
790 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
791 ( const char* s1, const char* s2, SizeT nmax ); \
792 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
793 ( const char* s1, const char* s2, SizeT nmax ) \
795 extern int tolower(int); \
796 SizeT n = 0; \
797 while (True) { \
798 if (n >= nmax) return 0; \
799 if (*s1 == 0 && *s2 == 0) return 0; \
800 if (*s1 == 0) return -1; \
801 if (*s2 == 0) return 1; \
803 if (tolower(*(const UChar *)s1) \
804 < tolower(*(const UChar*)s2)) return -1; \
805 if (tolower(*(const UChar *)s1) \
806 > tolower(*(const UChar *)s2)) return 1; \
808 s1++; s2++; n++; \
812 #if defined(VGO_linux)
813 # if !defined(VGPV_arm_linux_android) \
814 && !defined(VGPV_x86_linux_android) \
815 && !defined(VGPV_mips32_linux_android) \
816 && !defined(VGPV_arm64_linux_android)
817 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
818 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
819 # endif
821 #elif defined(VGO_freebsd)
822 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
823 STRNCASECMP(VG_Z_LD_ELF_SO_1, strncasecmp)
824 STRNCASECMP(VG_Z_LD_ELF32_SO_1, strncasecmp)
826 #elif defined(VGO_darwin)
827 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
828 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
830 #elif defined(VGO_solaris)
831 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
833 #endif
836 /*---------------------- strcasecmp_l ----------------------*/
838 #define STRCASECMP_L(soname, fnname) \
839 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
840 ( const char* s1, const char* s2, void* locale ); \
841 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
842 ( const char* s1, const char* s2, void* locale ) \
844 extern int tolower_l(int, void*) __attribute__((weak)); \
845 register UChar c1; \
846 register UChar c2; \
847 while (True) { \
848 c1 = tolower_l(*(const UChar *)s1, locale); \
849 c2 = tolower_l(*(const UChar *)s2, locale); \
850 if (c1 != c2) break; \
851 if (c1 == 0) break; \
852 s1++; s2++; \
854 if ((UChar)c1 < (UChar)c2) return -1; \
855 if ((UChar)c1 > (UChar)c2) return 1; \
856 return 0; \
859 #if defined(VGO_linux)
860 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
861 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
862 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
864 #elif defined(VGO_freebsd)
865 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
867 #elif defined(VGO_darwin)
868 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
870 #elif defined(VGO_solaris)
872 #endif
875 /*---------------------- strncasecmp_l ----------------------*/
877 #define STRNCASECMP_L(soname, fnname) \
878 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
879 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
880 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
881 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
883 extern int tolower_l(int, void*) __attribute__((weak)); \
884 SizeT n = 0; \
885 while (True) { \
886 if (n >= nmax) return 0; \
887 if (*s1 == 0 && *s2 == 0) return 0; \
888 if (*s1 == 0) return -1; \
889 if (*s2 == 0) return 1; \
891 if (tolower_l(*(const UChar *)s1, locale) \
892 < tolower_l(*(const UChar *)s2, locale)) return -1; \
893 if (tolower_l(*(const UChar *)s1, locale) \
894 > tolower_l(*(const UChar *)s2, locale)) return 1; \
896 s1++; s2++; n++; \
900 #if defined(VGO_linux)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
902 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
903 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
905 #elif defined(VGO_freebsd)
906 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
908 #elif defined(VGO_darwin)
909 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
910 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
912 #elif defined(VGO_solaris)
914 #endif
917 /*---------------------- strcmp ----------------------*/
919 #define STRCMP(soname, fnname) \
920 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
921 ( const char* s1, const char* s2 ); \
922 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
923 ( const char* s1, const char* s2 ) \
925 register UChar c1; \
926 register UChar c2; \
927 while (True) { \
928 c1 = *(const UChar *)s1; \
929 c2 = *(const UChar *)s2; \
930 if (c1 != c2) break; \
931 if (c1 == 0) break; \
932 s1++; s2++; \
934 if ((UChar)c1 < (UChar)c2) return -1; \
935 if ((UChar)c1 > (UChar)c2) return 1; \
936 return 0; \
939 #if defined(VGO_linux)
940 STRCMP(VG_Z_LIBC_SONAME, strcmp)
941 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
942 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
943 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
944 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
945 STRCMP(VG_Z_LD64_SO_1, strcmp)
946 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
947 || defined(VGPV_mips32_linux_android)
948 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
949 # endif
951 #elif defined(VGO_freebsd)
952 STRCMP(VG_Z_LIBC_SONAME, strcmp)
953 STRCMP(VG_Z_LD_ELF_SO_1, strcmp)
954 STRCMP(VG_Z_LD_ELF32_SO_1, strcmp)
956 #elif defined(VGO_darwin)
957 STRCMP(VG_Z_LIBC_SONAME, strcmp)
958 # if DARWIN_VERS >= DARWIN_10_9
959 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
960 # endif
962 #elif defined(VGO_solaris)
963 STRCMP(VG_Z_LIBC_SONAME, strcmp)
964 STRCMP(VG_Z_LD_SO_1, strcmp)
966 #endif
969 /*---------------------- memchr ----------------------*/
971 #define MEMCHR(soname, fnname) \
972 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
973 (const void *s, int c, SizeT n); \
974 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
975 (const void *s, int c, SizeT n) \
977 SizeT i; \
978 UChar c0 = (UChar)c; \
979 const UChar* p = s; \
980 for (i = 0; i < n; i++) \
981 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
982 return NULL; \
985 #if defined(VGO_linux)
986 MEMCHR(VG_Z_LIBC_SONAME, memchr)
987 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
989 #elif defined(VGO_freebsd)
990 MEMCHR(VG_Z_LIBC_SONAME, memchr)
992 #elif defined(VGO_darwin)
993 # if DARWIN_VERS == DARWIN_10_9
994 MEMCHR(VG_Z_DYLD, memchr)
995 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
996 # endif
997 # if DARWIN_VERS >= DARWIN_10_10
998 MEMCHR(VG_Z_DYLD, memchr)
999 /* _platform_memchr$VARIANT$Generic */
1000 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
1001 /* _platform_memchr$VARIANT$Haswell */
1002 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
1003 # endif
1005 #elif defined(VGO_solaris)
1006 MEMCHR(VG_Z_LIBC_SONAME, memchr)
1008 #endif
1011 /*---------------------- memrchr ----------------------*/
1013 #define MEMRCHR(soname, fnname) \
1014 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1015 (const void *s, int c, SizeT n); \
1016 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1017 (const void *s, int c, SizeT n) \
1019 SizeT i; \
1020 UChar c0 = (UChar)c; \
1021 const UChar* p = s; \
1022 for (i = 0; i < n; i++) \
1023 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1024 return NULL; \
1027 #if defined(VGO_linux)
1028 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1030 #elif defined(VGO_freebsd)
1031 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1033 #elif defined(VGO_darwin)
1034 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1035 //MEMRCHR(VG_Z_DYLD, memrchr)
1037 #elif defined(VGO_solaris)
1039 #endif
1042 /*---------------------- memcpy ----------------------*/
1044 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1045 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1046 ( void *dst, const void *src, SizeT len ); \
1047 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1048 ( void *dst, const void *src, SizeT len ) \
1050 RECORD_COPY(len); \
1051 if (do_ol_check && is_overlap(dst, src, len, len)) \
1052 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1054 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1055 const Addr WM = WS - 1; /* 7 or 3 */ \
1057 if (len > 0) { \
1058 if (dst < src || !is_overlap(dst, src, len, len)) { \
1060 /* Copying backwards. */ \
1061 SizeT n = len; \
1062 Addr d = (Addr)dst; \
1063 Addr s = (Addr)src; \
1065 if (((s^d) & WM) == 0) { \
1066 /* s and d have same UWord alignment. */ \
1067 /* Pull up to a UWord boundary. */ \
1068 while ((s & WM) != 0 && n >= 1) \
1069 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1070 /* Copy UWords. */ \
1071 while (n >= WS * 4) \
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 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1076 while (n >= WS) \
1077 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1078 if (n == 0) \
1079 return dst; \
1081 if (((s|d) & 1) == 0) { \
1082 /* Both are 16-aligned; copy what we can thusly. */ \
1083 while (n >= 2) \
1084 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1086 /* Copy leftovers, or everything if misaligned. */ \
1087 while (n >= 1) \
1088 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1090 } else if (dst > src) { \
1092 SizeT n = len; \
1093 Addr d = ((Addr)dst) + n; \
1094 Addr s = ((Addr)src) + n; \
1096 /* Copying forwards. */ \
1097 if (((s^d) & WM) == 0) { \
1098 /* s and d have same UWord alignment. */ \
1099 /* Back down to a UWord boundary. */ \
1100 while ((s & WM) != 0 && n >= 1) \
1101 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1102 /* Copy UWords. */ \
1103 while (n >= WS * 4) \
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 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1108 while (n >= WS) \
1109 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1110 if (n == 0) \
1111 return dst; \
1113 if (((s|d) & 1) == 0) { \
1114 /* Both are 16-aligned; copy what we can thusly. */ \
1115 while (n >= 2) \
1116 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1118 /* Copy leftovers, or everything if misaligned. */ \
1119 while (n >= 1) \
1120 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1125 return dst; \
1128 #define MEMMOVE(soname, fnname) \
1129 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1131 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1132 why we disable the overlap check on x86_64. */
1133 #if defined(VGP_amd64_linux)
1134 #define MEMCPY(soname, fnname) \
1135 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 0)
1136 #else
1137 #define MEMCPY(soname, fnname) \
1138 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1139 #endif
1141 #if defined(VGO_linux)
1142 /* For older memcpy we have to use memmove-like semantics and skip
1143 the overlap check; sigh; see #275284. */
1144 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1145 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1146 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1147 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1148 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1149 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_avx_unaligned_erms)
1150 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1151 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1152 /* icc9 blats these around all over the place. Not only in the main
1153 executable but various .so's. They are highly tuned and read
1154 memory beyond the source boundary (although work correctly and
1155 never go across page boundaries), so give errors when run
1156 natively, at least for misaligned source arg. Just intercepting
1157 in the exe only until we understand more about the problem. See
1158 http://bugs.kde.org/show_bug.cgi?id=139776
1160 MEMCPY(NONE, ZuintelZufastZumemcpy)
1162 #elif defined(VGO_freebsd)
1163 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1164 MEMCPY(VG_Z_LD_ELF_SO_1, memcpy)
1165 MEMCPY(VG_Z_LD_ELF32_SO_1, memcpy)
1167 #elif defined(VGO_darwin)
1168 # if DARWIN_VERS <= DARWIN_10_6
1169 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1170 # endif
1171 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1172 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1174 #elif defined(VGO_solaris)
1175 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1176 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
1177 MEMCPY(VG_Z_LD_SO_1, memcpy)
1179 #endif
1182 /*---------------------- memcmp ----------------------*/
1184 #define MEMCMP(soname, fnname) \
1185 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1186 ( const void *s1V, const void *s2V, SizeT n ); \
1187 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1188 ( const void *s1V, const void *s2V, SizeT n ) \
1190 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1191 const SizeT WM = WS - 1; /* 7 or 3 */ \
1192 Addr s1A = (Addr)s1V; \
1193 Addr s2A = (Addr)s2V; \
1195 if (((s1A | s2A) & WM) == 0) { \
1196 /* Both areas are word aligned. Skip over the */ \
1197 /* equal prefix as fast as possible. */ \
1198 while (n >= WS) { \
1199 UWord w1 = *(UWord*)s1A; \
1200 UWord w2 = *(UWord*)s2A; \
1201 if (w1 != w2) break; \
1202 s1A += WS; \
1203 s2A += WS; \
1204 n -= WS; \
1208 const UChar* s1 = (const UChar*) s1A; \
1209 const UChar* s2 = (const UChar*) s2A; \
1211 while (n != 0) { \
1212 UChar a0 = s1[0]; \
1213 UChar b0 = s2[0]; \
1214 s1 += 1; \
1215 s2 += 1; \
1216 int res = ((int)a0) - ((int)b0); \
1217 if (res != 0) \
1218 return res; \
1219 n -= 1; \
1221 return 0; \
1224 #if defined(VGO_linux)
1225 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1226 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1227 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1228 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1229 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1230 MEMCMP(VG_Z_LD_SO_1, bcmp)
1232 #elif defined(VGO_freebsd)
1233 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1234 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1235 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_memcmp)
1236 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_bcmp)
1238 #elif defined(VGO_darwin)
1239 # if DARWIN_VERS >= DARWIN_10_9
1240 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1241 # endif
1243 #elif defined(VGO_solaris)
1244 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1245 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1246 MEMCMP(VG_Z_LD_SO_1, memcmp)
1248 #endif
1251 /*---------------------- stpcpy ----------------------*/
1253 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1254 DEST. (minor variant of strcpy) */
1255 #define STPCPY(soname, fnname) \
1256 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1257 ( char* dst, const char* src ); \
1258 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1259 ( char* dst, const char* src ) \
1261 const HChar* src_orig = src; \
1262 HChar* dst_orig = dst; \
1264 while (*src) *dst++ = *src++; \
1265 *dst = 0; \
1267 /* This checks for overlap after copying, unavoidable without */ \
1268 /* pre-counting length... should be ok */ \
1269 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1270 RECORD_COPY(srclen); \
1271 if (is_overlap(dst_orig, \
1272 src_orig, \
1273 (Addr)dst-(Addr)dst_orig+1, \
1274 srclen)) \
1275 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1277 return dst; \
1280 #if defined(VGO_linux)
1281 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1282 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1283 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1284 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1285 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1286 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1287 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1289 #elif defined(VGO_freebsd)
1290 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1291 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1292 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1294 #elif defined(VGO_freebsd)
1295 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1296 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1297 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1299 #elif defined(VGO_darwin)
1300 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1301 //STPCPY(VG_Z_DYLD, stpcpy)
1303 #elif defined(VGO_solaris)
1304 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1306 #endif
1309 /*---------------------- stpncpy ----------------------*/
1311 #define STPNCPY(soname, fnname) \
1312 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1313 ( char* dst, const char* src, SizeT n ); \
1314 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1315 ( char* dst, const char* src, SizeT n ) \
1317 const HChar* src_orig = src; \
1318 HChar* dst_str = dst; \
1319 SizeT m = 0; \
1321 while (m < n && *src) { m++; *dst++ = *src++; } \
1322 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1323 /* but only m+1 bytes of src if terminator was found */ \
1324 SizeT srclen = (m < n) ? m+1 : n; \
1325 RECORD_COPY(srclen); \
1326 if (is_overlap(dst_str, src_orig, n, srclen)) \
1327 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1328 dst_str = dst; \
1329 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1331 return dst_str; \
1334 #if defined(VGO_linux) || defined(VGO_freebsd)
1335 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1336 #endif
1339 /*---------------------- memset ----------------------*/
1341 #define MEMSET(soname, fnname) \
1342 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1343 (void *s, Int c, SizeT n); \
1344 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1345 (void *s, Int c, SizeT n) \
1347 if (sizeof(void*) == 8) { \
1348 Addr a = (Addr)s; \
1349 ULong c8 = (c & 0xFF); \
1350 c8 = (c8 << 8) | c8; \
1351 c8 = (c8 << 16) | c8; \
1352 c8 = (c8 << 32) | c8; \
1353 while ((a & 7) != 0 && n >= 1) \
1354 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1355 while (n >= 32) \
1356 { *(ULong*)a = c8; a += 8; n -= 8; \
1357 *(ULong*)a = c8; a += 8; n -= 8; \
1358 *(ULong*)a = c8; a += 8; n -= 8; \
1359 *(ULong*)a = c8; a += 8; n -= 8; } \
1360 while (n >= 8) \
1361 { *(ULong*)a = c8; a += 8; n -= 8; } \
1362 while (n >= 1) \
1363 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1364 return s; \
1365 } else { \
1366 Addr a = (Addr)s; \
1367 UInt c4 = (c & 0xFF); \
1368 c4 = (c4 << 8) | c4; \
1369 c4 = (c4 << 16) | c4; \
1370 while ((a & 3) != 0 && n >= 1) \
1371 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1372 while (n >= 16) \
1373 { *(UInt*)a = c4; a += 4; n -= 4; \
1374 *(UInt*)a = c4; a += 4; n -= 4; \
1375 *(UInt*)a = c4; a += 4; n -= 4; \
1376 *(UInt*)a = c4; a += 4; n -= 4; } \
1377 while (n >= 4) \
1378 { *(UInt*)a = c4; a += 4; n -= 4; } \
1379 while (n >= 1) \
1380 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1381 return s; \
1385 #if defined(VGO_linux)
1386 MEMSET(VG_Z_LIBC_SONAME, memset)
1388 #elif defined(VGO_freebsd)
1389 MEMSET(VG_Z_LIBC_SONAME, memset)
1390 MEMSET(VG_Z_LD_ELF_SO_1, memset)
1391 MEMSET(VG_Z_LD_ELF32_SO_1, memset)
1393 #elif defined(VGO_darwin)
1394 //MEMSET(VG_Z_LIBC_SONAME, memset)
1395 //MEMSET(VG_Z_DYLD, memset)
1396 MEMSET(VG_Z_LIBC_SONAME, memset)
1398 #elif defined(VGO_solaris)
1399 MEMSET(VG_Z_LIBC_SONAME, memset)
1400 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1402 #endif
1405 /*---------------------- memmove ----------------------*/
1407 /* memmove -- use the MEMMOVE defn above. */
1409 #if defined(VGO_linux)
1410 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1411 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1412 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1413 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1414 to call memcpy. */
1415 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1417 #elif defined(VGO_freebsd)
1418 MEMMOVE(VG_Z_LD_ELF_SO_1, memmove)
1419 MEMMOVE(VG_Z_LD_ELF32_SO_1, memmove)
1420 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1422 #elif defined(VGO_darwin)
1423 # if DARWIN_VERS <= DARWIN_10_6
1424 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1425 # endif
1426 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1427 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1428 # if DARWIN_VERS >= DARWIN_10_9
1429 /* _platform_memmove$VARIANT$Ivybridge */
1430 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1431 # endif
1433 #elif defined(VGO_solaris)
1434 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1435 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1436 MEMMOVE(VG_Z_LD_SO_1, memmove)
1438 #endif
1441 /*---------------------- bcopy ----------------------*/
1443 #define BCOPY(soname, fnname) \
1444 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1445 (const void *srcV, void *dstV, SizeT n); \
1446 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1447 (const void *srcV, void *dstV, SizeT n) \
1449 RECORD_COPY(n); \
1450 SizeT i; \
1451 HChar* dst = dstV; \
1452 const HChar* src = srcV; \
1453 if (dst < src) { \
1454 for (i = 0; i < n; i++) \
1455 dst[i] = src[i]; \
1457 else \
1458 if (dst > src) { \
1459 for (i = 0; i < n; i++) \
1460 dst[n-i-1] = src[n-i-1]; \
1464 #if defined(VGO_linux)
1465 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1467 #elif defined(VGO_freebsd)
1468 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1469 BCOPY(VG_Z_LD_ELF_SO_1, bcopy)
1470 BCOPY(VG_Z_LD_ELF32_SO_1, bcopy)
1472 #elif defined(VGO_darwin)
1473 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1474 //BCOPY(VG_Z_DYLD, bcopy)
1476 #elif defined(VGO_darwin)
1477 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1479 #endif
1482 /*-------------------- memmove_chk --------------------*/
1484 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1485 There is no specific part of glibc that this is copied from. */
1486 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1487 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1488 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1489 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1490 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1492 RECORD_COPY(n); \
1493 SizeT i; \
1494 HChar* dst = dstV; \
1495 const HChar* src = srcV; \
1496 if (destlen < n) \
1497 goto badness; \
1498 if (dst < src) { \
1499 for (i = 0; i < n; i++) \
1500 dst[i] = src[i]; \
1502 else \
1503 if (dst > src) { \
1504 for (i = 0; i < n; i++) \
1505 dst[n-i-1] = src[n-i-1]; \
1507 return dst; \
1508 badness: \
1509 VALGRIND_PRINTF_BACKTRACE( \
1510 "*** memmove_chk: buffer overflow detected ***: " \
1511 "program terminated\n"); \
1512 my_exit(1); \
1513 /*NOTREACHED*/ \
1514 return NULL; \
1517 #if defined(VGO_linux)
1518 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1520 #elif defined(VGO_darwin)
1522 #elif defined(VGO_solaris)
1524 #endif
1527 /*-------------------- strchrnul --------------------*/
1529 /* Find the first occurrence of C in S or the final NUL byte. */
1530 #define GLIBC232_STRCHRNUL(soname, fnname) \
1531 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1532 (const char* s, int c_in); \
1533 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1534 (const char* s, int c_in) \
1536 HChar c = (HChar) c_in; \
1537 const HChar* char_ptr = s; \
1538 while (1) { \
1539 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1540 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1541 char_ptr++; \
1545 #if defined(VGO_linux)
1546 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1548 #elif defined(VGO_freebsd)
1549 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1551 #elif defined(VGO_darwin)
1553 #elif defined(VGO_solaris)
1555 #endif
1558 /*---------------------- rawmemchr ----------------------*/
1560 /* Find the first occurrence of C in S. */
1561 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1562 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1563 (const void* s, int c_in); \
1564 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1565 (const void* s, int c_in) \
1567 UChar c = (UChar) c_in; \
1568 const UChar* char_ptr = s; \
1569 while (1) { \
1570 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1571 char_ptr++; \
1575 #if defined (VGO_linux)
1576 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1577 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1579 #elif defined(VGO_darwin)
1581 #elif defined(VGO_solaris)
1583 #endif
1586 /*---------------------- strcpy_chk ----------------------*/
1588 /* glibc variant of strcpy that checks the dest is big enough.
1589 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1590 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1591 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1592 (char* dst, const char* src, SizeT len); \
1593 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1594 (char* dst, const char* src, SizeT len) \
1596 FOR_COPY(const HChar* src_orig = src); \
1597 HChar* ret = dst; \
1598 if (! len) \
1599 goto badness; \
1600 while ((*dst++ = *src++) != '\0') \
1601 if (--len == 0) \
1602 goto badness; \
1603 RECORD_COPY((Addr)src-(Addr)src_orig); \
1604 return ret; \
1605 badness: \
1606 VALGRIND_PRINTF_BACKTRACE( \
1607 "*** strcpy_chk: buffer overflow detected ***: " \
1608 "program terminated\n"); \
1609 my_exit(1); \
1610 /*NOTREACHED*/ \
1611 return NULL; \
1614 #if defined(VGO_linux)
1615 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1617 #elif defined(VGO_darwin)
1619 #elif defined(VGO_solaris)
1621 #endif
1624 /*---------------------- stpcpy_chk ----------------------*/
1626 /* glibc variant of stpcpy that checks the dest is big enough.
1627 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1628 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1629 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1630 (char* dst, const char* src, SizeT len); \
1631 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1632 (char* dst, const char* src, SizeT len) \
1634 FOR_COPY(const HChar* src_orig = src); \
1635 if (! len) \
1636 goto badness; \
1637 while ((*dst++ = *src++) != '\0') \
1638 if (--len == 0) \
1639 goto badness; \
1640 RECORD_COPY((Addr)src-(Addr)src_orig); \
1641 return dst - 1; \
1642 badness: \
1643 VALGRIND_PRINTF_BACKTRACE( \
1644 "*** stpcpy_chk: buffer overflow detected ***: " \
1645 "program terminated\n"); \
1646 my_exit(1); \
1647 /*NOTREACHED*/ \
1648 return NULL; \
1651 #if defined(VGO_linux)
1652 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1654 #elif defined(VGO_darwin)
1656 #elif defined(VGO_solaris)
1658 #endif
1661 /*---------------------- mempcpy ----------------------*/
1663 /* mempcpy */
1664 #define GLIBC25_MEMPCPY(soname, fnname) \
1665 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1666 ( void *dst, const void *src, SizeT len ); \
1667 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1668 ( void *dst, const void *src, SizeT len ) \
1670 RECORD_COPY(len); \
1671 SizeT len_saved = len; \
1673 if (len == 0) \
1674 return dst; \
1676 if (is_overlap(dst, src, len, len)) \
1677 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1679 if ( dst > src ) { \
1680 register HChar *d = (char *)dst + len - 1; \
1681 register const HChar *s = (const char *)src + len - 1; \
1682 while ( len-- ) { \
1683 *d-- = *s--; \
1685 } else if ( dst < src ) { \
1686 register HChar *d = dst; \
1687 register const HChar *s = src; \
1688 while ( len-- ) { \
1689 *d++ = *s++; \
1692 return (void*)( ((char*)dst) + len_saved ); \
1695 #if defined(VGO_linux)
1696 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1697 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1698 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1699 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1700 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1702 #elif defined(VGO_freebsd)
1703 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1704 #elif defined(VGO_darwin)
1705 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1707 #elif defined(VGO_solaris)
1709 #endif
1712 /*-------------------- memcpy_chk --------------------*/
1714 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1715 why we disable the overlap check on x86_64. */
1716 #if defined(VGP_amd64_linux)
1717 #define CHECK_OVERLAP 0
1718 #else
1719 #define CHECK_OVERLAP 1
1720 #endif
1722 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1723 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1724 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1725 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1726 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1728 register HChar *d; \
1729 register const HChar *s; \
1730 if (dstlen < len) \
1731 goto badness; \
1732 RECORD_COPY(len); \
1733 if (len == 0) \
1734 return dst; \
1735 if (CHECK_OVERLAP && is_overlap(dst, src, len, len)) \
1736 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1737 if ( dst > src ) { \
1738 d = (HChar *)dst + len - 1; \
1739 s = (const HChar *)src + len - 1; \
1740 while ( len-- ) { \
1741 *d-- = *s--; \
1743 } else if ( dst < src ) { \
1744 d = (HChar *)dst; \
1745 s = (const HChar *)src; \
1746 while ( len-- ) { \
1747 *d++ = *s++; \
1750 return dst; \
1751 badness: \
1752 VALGRIND_PRINTF_BACKTRACE( \
1753 "*** memcpy_chk: buffer overflow detected ***: " \
1754 "program terminated\n"); \
1755 my_exit(1); \
1756 /*NOTREACHED*/ \
1757 return NULL; \
1760 #if defined(VGO_linux)
1761 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1763 #elif defined(VGO_darwin)
1765 #elif defined(VGO_solaris)
1767 #endif
1770 /*---------------------- strstr ----------------------*/
1772 #define STRSTR(soname, fnname) \
1773 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1774 (const char* haystack, const char* needle); \
1775 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1776 (const char* haystack, const char* needle) \
1778 const HChar* h = haystack; \
1779 const HChar* n = needle; \
1781 /* find the length of n, not including terminating zero */ \
1782 UWord nlen = 0; \
1783 while (n[nlen]) nlen++; \
1785 /* if n is the empty string, match immediately. */ \
1786 if (nlen == 0) return CONST_CAST(HChar *,h); \
1788 /* assert(nlen >= 1); */ \
1789 HChar n0 = n[0]; \
1791 while (1) { \
1792 const HChar hh = *h; \
1793 if (hh == 0) return NULL; \
1794 if (hh != n0) { h++; continue; } \
1796 UWord i; \
1797 for (i = 0; i < nlen; i++) { \
1798 if (n[i] != h[i]) \
1799 break; \
1801 /* assert(i >= 0 && i <= nlen); */ \
1802 if (i == nlen) \
1803 return CONST_CAST(HChar *,h); \
1805 h++; \
1809 #if defined(VGO_linux)
1810 STRSTR(VG_Z_LIBC_SONAME, strstr)
1811 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1812 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1814 #elif defined(VGO_freebsd)
1815 STRSTR(VG_Z_LIBC_SONAME, strstr)
1817 #elif defined(VGO_darwin)
1819 #elif defined(VGO_solaris)
1820 STRSTR(VG_Z_LIBC_SONAME, strstr)
1822 #endif
1824 /*---------------------- memmem ----------------------*/
1826 #define MEMMEM(soname, fnname) \
1827 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1828 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1829 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1830 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1832 const HChar* h = haystack; \
1833 const HChar* n = needle; \
1835 /* If the needle is the empty string, match immediately. */ \
1836 if (nlen == 0) return CONST_CAST(void *,h); \
1838 HChar n0 = n[0]; \
1840 for (; hlen >= nlen; hlen--, h++) { \
1841 if (h[0] != n0) continue; \
1843 UWord i; \
1844 for (i = 1; i < nlen; i++) { \
1845 if (n[i] != h[i]) \
1846 break; \
1848 if (i == nlen) \
1849 return CONST_CAST(HChar *,h); \
1852 return NULL; \
1855 #if defined(VGP_s390x_linux)
1856 MEMMEM(VG_Z_LIBC_SONAME, memmem)
1857 #endif
1860 /*---------------------- strpbrk ----------------------*/
1862 #define STRPBRK(soname, fnname) \
1863 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1864 (const char* sV, const char* acceptV); \
1865 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1866 (const char* sV, const char* acceptV) \
1868 const HChar* s = sV; \
1869 const HChar* accept = acceptV; \
1871 /* find the length of 'accept', not including terminating zero */ \
1872 UWord nacc = 0; \
1873 while (accept[nacc]) nacc++; \
1875 /* if n is the empty string, fail immediately. */ \
1876 if (nacc == 0) return NULL; \
1878 /* assert(nacc >= 1); */ \
1879 while (1) { \
1880 UWord i; \
1881 HChar sc = *s; \
1882 if (sc == 0) \
1883 break; \
1884 for (i = 0; i < nacc; i++) { \
1885 if (sc == accept[i]) \
1886 return CONST_CAST(HChar *,s); \
1888 s++; \
1891 return NULL; \
1894 #if defined(VGO_linux)
1895 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1897 #elif defined(VGO_freebsd)
1898 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1900 #elif defined(VGO_darwin)
1902 #elif defined(VGO_solaris)
1903 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1905 #endif
1908 /*---------------------- strcspn ----------------------*/
1910 #define STRCSPN(soname, fnname) \
1911 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1912 (const char* sV, const char* rejectV); \
1913 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1914 (const char* sV, const char* rejectV) \
1916 const HChar* s = sV; \
1917 const HChar* reject = rejectV; \
1919 /* find the length of 'reject', not including terminating zero */ \
1920 UWord nrej = 0; \
1921 while (reject[nrej]) nrej++; \
1923 UWord len = 0; \
1924 while (1) { \
1925 UWord i; \
1926 HChar sc = *s; \
1927 if (sc == 0) \
1928 break; \
1929 for (i = 0; i < nrej; i++) { \
1930 if (sc == reject[i]) \
1931 break; \
1933 /* assert(i >= 0 && i <= nrej); */ \
1934 if (i < nrej) \
1935 break; \
1936 s++; \
1937 len++; \
1940 return len; \
1943 #if defined(VGO_linux)
1944 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1945 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1947 #elif defined(VGO_freebsd)
1948 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1950 #elif defined(VGO_darwin)
1952 #elif defined(VGO_solaris)
1953 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1955 #endif
1958 /*---------------------- strspn ----------------------*/
1960 #define STRSPN(soname, fnname) \
1961 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1962 (const char* sV, const char* acceptV); \
1963 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1964 (const char* sV, const char* acceptV) \
1966 const UChar* s = (const UChar *)sV; \
1967 const UChar* accept = (const UChar *)acceptV; \
1969 /* find the length of 'accept', not including terminating zero */ \
1970 UWord nacc = 0; \
1971 while (accept[nacc]) nacc++; \
1972 if (nacc == 0) return 0; \
1974 UWord len = 0; \
1975 while (1) { \
1976 UWord i; \
1977 UChar sc = *s; \
1978 if (sc == 0) \
1979 break; \
1980 for (i = 0; i < nacc; i++) { \
1981 if (sc == accept[i]) \
1982 break; \
1984 /* assert(i >= 0 && i <= nacc); */ \
1985 if (i == nacc) \
1986 break; \
1987 s++; \
1988 len++; \
1991 return len; \
1994 #if defined(VGO_linux)
1995 STRSPN(VG_Z_LIBC_SONAME, strspn)
1997 #elif defined(VGO_freebsd)
1998 STRSPN(VG_Z_LIBC_SONAME, strspn)
2000 #elif defined(VGO_darwin)
2002 #elif defined(VGO_solaris)
2003 STRSPN(VG_Z_LIBC_SONAME, strspn)
2005 #endif
2008 /*---------------------- strcasestr ----------------------*/
2010 #define STRCASESTR(soname, fnname) \
2011 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2012 (const char* haystack, const char* needle); \
2013 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2014 (const char* haystack, const char* needle) \
2016 extern int tolower(int); \
2017 const HChar* h = haystack; \
2018 const HChar* n = needle; \
2020 /* find the length of n, not including terminating zero */ \
2021 UWord nlen = 0; \
2022 while (n[nlen]) nlen++; \
2024 /* if n is the empty string, match immediately. */ \
2025 if (nlen == 0) return CONST_CAST(HChar *,h); \
2027 /* assert(nlen >= 1); */ \
2028 UChar n0 = tolower(n[0]); \
2030 while (1) { \
2031 UChar hh = tolower(*h); \
2032 if (hh == 0) return NULL; \
2033 if (hh != n0) { h++; continue; } \
2035 UWord i; \
2036 for (i = 0; i < nlen; i++) { \
2037 if (tolower(n[i]) != tolower(h[i])) \
2038 break; \
2040 /* assert(i >= 0 && i <= nlen); */ \
2041 if (i == nlen) \
2042 return CONST_CAST(HChar *,h); \
2044 h++; \
2048 #if defined(VGO_linux)
2049 # if !defined(VGPV_arm_linux_android) \
2050 && !defined(VGPV_x86_linux_android) \
2051 && !defined(VGPV_mips32_linux_android) \
2052 && !defined(VGPV_arm64_linux_android)
2053 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2054 # endif
2056 #elif defined(VGO_freebsd)
2057 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2059 #elif defined(VGO_darwin)
2061 #elif defined(VGO_solaris)
2062 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2064 #endif
2067 /*---------------------- wcslen ----------------------*/
2069 // This is a wchar_t equivalent to strlen. Unfortunately
2070 // we don't have wchar_t available here, but it looks like
2071 // a 32 bit int on Linux. I don't know if that is also
2072 // valid on MacOSX.
2074 #define WCSLEN(soname, fnname) \
2075 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2076 ( const Int* str ); \
2077 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2078 ( const Int* str ) \
2080 SizeT i = 0; \
2081 while (str[i] != 0) i++; \
2082 return i; \
2085 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2086 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
2088 #endif
2090 /*---------------------- wcsnlen ----------------------*/
2092 #define WCSNLEN(soname, fnname) \
2093 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2094 ( const Int *s, SizeT n ); \
2095 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2096 ( const Int *s, SizeT n ) \
2098 SizeT i = 0; \
2099 const Int* p = s; \
2100 while (i < n && *p != 0) { \
2101 i++; \
2102 p++; \
2104 return i; \
2107 #if defined(VGO_linux) || defined(VGO_freebsd)
2108 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
2109 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
2110 #endif
2112 /*---------------------- wcscmp ----------------------*/
2114 // This is a wchar_t equivalent to strcmp. We don't
2115 // have wchar_t available here, but in the GNU C Library
2116 // wchar_t is always 32 bits wide and wcscmp uses signed
2117 // comparison, not unsigned as in strcmp function.
2119 #define WCSCMP(soname, fnname) \
2120 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2121 ( const Int* s1, const Int* s2 ); \
2122 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2123 ( const Int* s1, const Int* s2 ) \
2125 register Int c1; \
2126 register Int c2; \
2127 while (True) { \
2128 c1 = *s1; \
2129 c2 = *s2; \
2130 if (c1 != c2) break; \
2131 if (c1 == 0) break; \
2132 s1++; s2++; \
2134 if (c1 < c2) return -1; \
2135 if (c1 > c2) return 1; \
2136 return 0; \
2139 #if defined(VGO_linux) || defined(VGO_freebsd)
2140 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
2141 #endif
2143 /*---------------------- wcsncmp ----------------------*/
2145 // This is a wchar_t equivalent to strncmp. We don't
2146 // have wchar_t available here, but in the GNU C Library
2147 // wchar_t is always 32 bits wide and wcsncmp uses signed
2148 // comparison, not unsigned as in strncmp function.
2150 #define WCSNCMP(soname, fnname) \
2151 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2152 ( const Int* s1, const Int* s2, SizeT nmax ); \
2153 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2154 ( const Int* s1, const Int* s2, SizeT nmax ) \
2156 SizeT n = 0; \
2157 while (True) { \
2158 if (n >= nmax) return 0; \
2159 if (*s1 == 0 && *s2 == 0) return 0; \
2160 if (*s1 == 0) return -1; \
2161 if (*s2 == 0) return 1; \
2163 if (*s1 < *s2) return -1; \
2164 if (*s1 > *s2) return 1; \
2166 s1++; s2++; n++; \
2169 #if defined(VGO_linux) || defined(VGO_freebsd)
2170 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
2171 #endif
2173 /*---------------------- wcscpy ----------------------*/
2175 // This is a wchar_t equivalent to strcpy. We don't
2176 // have wchar_t available here, but in the GNU C Library
2177 // wchar_t is always 32 bits wide.
2179 #define WCSCPY(soname, fnname) \
2180 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2181 ( Int* dst, const Int* src ); \
2182 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2183 ( Int* dst, const Int* src ) \
2185 const Int* src_orig = src; \
2186 Int* dst_orig = dst; \
2188 while (*src) *dst++ = *src++; \
2189 *dst = 0; \
2191 /* This checks for overlap after copying, unavoidable without */ \
2192 /* pre-counting length... should be ok */ \
2193 /* +4 because sizeof(wchar_t) == 4 */ \
2194 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2195 RECORD_COPY(srclen); \
2196 if (is_overlap(dst_orig, \
2197 src_orig, \
2198 /* +4 because sizeof(wchar_t) == 4 */ \
2199 (Addr)dst-(Addr)dst_orig+4, \
2200 srclen)) \
2201 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2203 return dst_orig; \
2206 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2207 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2208 #endif
2211 /*---------------------- wcschr ----------------------*/
2213 // This is a wchar_t equivalent to strchr. We don't
2214 // have wchar_t available here, but in the GNU C Library
2215 // wchar_t is always 32 bits wide.
2217 #define WCSCHR(soname, fnname) \
2218 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2219 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2221 const Int* p = s; \
2222 while (True) { \
2223 if (*p == c) return CONST_CAST(Int *,p); \
2224 if (*p == 0) return NULL; \
2225 p++; \
2229 #if defined(VGO_linux) || defined(VGO_freebsd)
2230 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2231 #endif
2232 /*---------------------- wcsrchr ----------------------*/
2234 // This is a wchar_t equivalent to strrchr. We don't
2235 // have wchar_t available here, but in the GNU C Library
2236 // wchar_t is always 32 bits wide.
2238 #define WCSRCHR(soname, fnname) \
2239 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2240 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2242 const Int* p = s; \
2243 const Int* last = NULL; \
2244 while (True) { \
2245 if (*p == c) last = p; \
2246 if (*p == 0) return CONST_CAST(Int *,last); \
2247 p++; \
2251 #if defined(VGO_linux) || defined(VGO_freebsd)
2252 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2253 #endif
2255 /*---------------------- wmemchr ----------------------*/
2257 // This is a wchar_t equivalent to memchr. We don't
2258 // have wchar_t available here, but in the GNU C Library
2259 // wchar_t is always 32 bits wide.
2261 #define WMEMCHR(soname, fnname) \
2262 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2263 (const Int *s, Int c, SizeT n); \
2264 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2265 (const Int *s, Int c, SizeT n) \
2267 SizeT i; \
2268 const Int* p = s; \
2269 for (i = 0; i < n; i++) { \
2270 if (*p == c) return CONST_CAST(Int *,p); \
2271 p++; \
2273 return NULL; \
2276 #if defined(VGO_linux)
2277 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2278 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2279 #endif
2281 #if defined(VGO_freebsd)
2282 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2283 #endif
2285 /*---------------------- wmemcmp ----------------------*/
2287 #define WMEMCMP(soname, fnname) \
2288 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2289 ( const Int *b1, const Int *b2, SizeT n ); \
2290 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2291 ( const Int *b1, const Int *b2, SizeT n ) \
2293 for (SizeT i = 0U; i < n; ++i) { \
2294 if (b1[i] != b2[i]) \
2295 return b1[i] > b2[i] ? 1 : -1; \
2297 return 0; \
2300 #if defined(VGO_linux) || defined(VGO_freebsd)
2301 WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
2302 #endif
2304 /*---------------------- wcsncpy ----------------------*/
2306 // This is a wchar_t equivalent to strncpy. We don't
2307 // have wchar_t available here, but in the GNU C Library
2308 // wchar_t is always 32 bits wide.
2310 #define WCSNCPY(soname, fnname) \
2311 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2312 ( Int* dst, const Int* src, SizeT n ); \
2313 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2314 ( Int* dst, const Int* src, SizeT n ) \
2316 const Int* src_orig = src; \
2317 Int* dst_orig = dst; \
2318 SizeT m = 0; \
2320 while (m < n && *src) { \
2321 m++; \
2322 *dst++ = *src++; \
2325 /* This checks for overlap after copying, unavoidable without */ \
2326 /* pre-counting length... should be ok */ \
2327 /* +4 because sizeof(wchar_t) == 4 */ \
2328 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2329 RECORD_COPY(srclen); \
2330 if (is_overlap(dst_orig, \
2331 src_orig, \
2332 n*4, \
2333 srclen)) \
2334 RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
2336 while (m++ < n) { \
2337 *dst++ = 0; \
2340 return dst_orig; \
2343 #if defined(VGO_linux) || defined(VGO_freebsd)
2344 WCSNCPY(VG_Z_LIBC_SONAME, wcsncpy)
2345 #endif
2347 /*------------------------------------------------------------*/
2348 /*--- Improve definedness checking of process environment ---*/
2349 /*------------------------------------------------------------*/
2351 #if defined(VGO_linux) || defined(VGO_freebsd)
2353 /* If these wind up getting generated via a macro, so that multiple
2354 versions of each function exist (as above), use the _EZU variants
2355 to assign equivalance class tags. */
2357 /*---------------------- putenv ----------------------*/
2359 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2360 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2362 OrigFn fn;
2363 Word result;
2364 const HChar* p = string;
2365 VALGRIND_GET_ORIG_FN(fn);
2366 /* Now by walking over the string we magically produce
2367 traces when hitting undefined memory. */
2368 if (p)
2369 while (*p++)
2370 __asm__ __volatile__("" ::: "memory");
2371 CALL_FN_W_W(result, fn, string);
2372 return result;
2376 /*---------------------- unsetenv ----------------------*/
2378 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2379 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2381 OrigFn fn;
2382 Word result;
2383 const HChar* p = name;
2384 VALGRIND_GET_ORIG_FN(fn);
2385 /* Now by walking over the string we magically produce
2386 traces when hitting undefined memory. */
2387 if (p)
2388 while (*p++)
2389 __asm__ __volatile__("" ::: "memory");
2390 CALL_FN_W_W(result, fn, name);
2391 return result;
2395 /*---------------------- setenv ----------------------*/
2397 /* setenv */
2398 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2399 (const char* name, const char* value, int overwrite);
2400 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2401 (const char* name, const char* value, int overwrite)
2403 OrigFn fn;
2404 Word result;
2405 const HChar* p;
2406 VALGRIND_GET_ORIG_FN(fn);
2407 /* Now by walking over the string we magically produce
2408 traces when hitting undefined memory. */
2409 if (name)
2410 for (p = name; *p; p++)
2411 __asm__ __volatile__("" ::: "memory");
2412 if (value)
2413 for (p = value; *p; p++)
2414 __asm__ __volatile__("" ::: "memory");
2415 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2416 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2417 return result;
2420 #endif /* defined(VGO_linux) */
2422 /*--------------------------------------------------------------------*/
2423 /*--- end ---*/
2424 /*--------------------------------------------------------------------*/