Helgrind: add suppression for libnss from getaddrinfo
[valgrind.git] / shared / vg_replace_strmem.c
blob781dd784bfe6588ffb4e8401ba9161fa1fc16e1d
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
109 20490 MEMCCPY
112 #if defined(VGO_solaris)
114 Detour functions in the libc and the runtime linker. If a function isn't
115 much optimized (and no overlap checking is necessary) then redir the
116 function only in the libc. This way we can keep stacktraces in the tests
117 consistent.
119 #endif
122 /* Figure out if [dst .. dst+dstlen-1] overlaps with
123 [src .. src+srclen-1].
124 We assume that the address ranges do not wrap around
125 (which is safe since on Linux addresses >= 0xC0000000
126 are not accessible and the program will segfault in this
127 circumstance, presumably).
129 static inline
130 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
132 Addr loS, hiS, loD, hiD;
134 if (dstlen == 0 || srclen == 0)
135 return False;
137 loS = (Addr)src;
138 loD = (Addr)dst;
139 hiS = loS + srclen - 1;
140 hiD = loD + dstlen - 1;
142 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
143 if (loS < loD) {
144 return !(hiS < loD);
146 else if (loD < loS) {
147 return !(hiD < loS);
149 else {
150 /* They start at same place. Since we know neither of them has
151 zero length, they must overlap. */
152 return True;
156 #if defined(VGO_linux)
157 /* Call here to exit if we can't continue. On Android we can't call
158 _exit for some reason, so we have to blunt-instrument it. */
159 __attribute__ ((__noreturn__))
160 static inline void my_exit ( int x )
162 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
163 || defined(VGPV_arm64_linux_android)
164 __asm__ __volatile__(".word 0xFFFFFFFF");
165 while (1) {}
166 # elif defined(VGPV_x86_linux_android)
167 __asm__ __volatile__("ud2");
168 while (1) {}
169 # else
170 extern __attribute__ ((__noreturn__)) void _exit(int status);
171 _exit(x);
172 # endif
174 #endif
176 // This is a macro rather than a function because we don't want to have an
177 // extra function in the stack trace.
178 #ifndef RECORD_OVERLAP_ERROR
179 #define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
180 #endif
182 // Used for tools that record bulk copies: memcpy, strcpy, etc.
183 #ifndef RECORD_COPY
184 #define RECORD_COPY(len) do { } while (0)
185 #define FOR_COPY(x)
186 #else
187 #define FOR_COPY(x) x
188 #endif
190 #ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
191 #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
192 #endif
195 /*---------------------- strrchr ----------------------*/
197 #define STRRCHR(soname, fnname) \
198 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
199 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
201 HChar ch = (HChar)c; \
202 const HChar* p = s; \
203 const HChar* last = NULL; \
204 while (True) { \
205 if (*p == ch) last = p; \
206 if (*p == 0) return CONST_CAST(HChar *,last); \
207 p++; \
211 // Apparently rindex() is the same thing as strrchr()
212 #if defined(VGO_linux)
213 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
214 STRRCHR(VG_Z_LIBC_SONAME, rindex)
215 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
216 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
217 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
218 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
219 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
220 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
221 || defined(VGPV_mips32_linux_android)
222 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
223 #endif
225 #elif defined(VGO_freebsd)
226 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
227 STRRCHR(VG_Z_LIBC_SONAME, rindex)
228 STRRCHR(VG_Z_LD_ELF_SO_1, strrchr)
229 STRRCHR(VG_Z_LD_ELF32_SO_1, strrchr)
231 #elif defined(VGO_darwin)
232 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
233 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
234 //STRRCHR(VG_Z_DYLD, strrchr)
235 //STRRCHR(VG_Z_DYLD, rindex)
236 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
237 # if DARWIN_VERS >= DARWIN_10_9
238 STRRCHR(libsystemZucZddylib, strrchr)
239 # endif
241 #elif defined(VGO_solaris)
242 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
243 STRRCHR(VG_Z_LIBC_SONAME, rindex)
244 STRRCHR(VG_Z_LD_SO_1, strrchr)
246 #endif
249 /*---------------------- strchr ----------------------*/
251 #define STRCHR(soname, fnname) \
252 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
253 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
255 HChar ch = (HChar)c ; \
256 const HChar* p = s; \
257 while (True) { \
258 if (*p == ch) return CONST_CAST(HChar *,p); \
259 if (*p == 0) return NULL; \
260 p++; \
264 // Apparently index() is the same thing as strchr()
265 #if defined(VGO_linux)
266 STRCHR(VG_Z_LIBC_SONAME, strchr)
267 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
268 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
269 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
270 STRCHR(VG_Z_LIBC_SONAME, index)
271 # if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
272 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
273 STRCHR(VG_Z_LD_LINUX_SO_2, index)
274 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
275 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
276 # endif
278 #if defined(VGPV_mips32_linux_android)
279 STRCHR(NONE, __dl_strchr)
280 #endif
282 #elif defined(VGO_freebsd)
283 STRCHR(VG_Z_LIBC_SONAME, strchr)
284 STRCHR(VG_Z_LIBC_SONAME, index)
285 STRCHR(VG_Z_LD_ELF_SO_1, strchr)
286 STRCHR(VG_Z_LD_ELF32_SO_1, strchr)
288 #elif defined(VGO_darwin)
289 STRCHR(VG_Z_LIBC_SONAME, strchr)
290 # if DARWIN_VERS == DARWIN_10_9
291 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
292 # endif
293 # if DARWIN_VERS >= DARWIN_10_10
294 /* _platform_strchr$VARIANT$Generic */
295 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
296 /* _platform_strchr$VARIANT$Haswell */
297 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
298 # endif
299 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Base)
301 #elif defined(VGO_solaris)
302 STRCHR(VG_Z_LIBC_SONAME, strchr)
303 STRCHR(VG_Z_LIBC_SONAME, index)
304 STRCHR(VG_Z_LD_SO_1, strchr)
306 #endif
309 /*---------------------- strcat ----------------------*/
311 #define STRCAT(soname, fnname) \
312 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
313 ( char* dst, const char* src ); \
314 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
315 ( char* dst, const char* src ) \
317 const HChar* src_orig = src; \
318 HChar* dst_orig = dst; \
319 while (*dst) dst++; \
320 while (*src) *dst++ = *src++; \
321 *dst = 0; \
323 /* This is a bit redundant, I think; any overlap and the strcat will */ \
324 /* go forever... or until a seg fault occurs. */ \
325 if (is_overlap(dst_orig, \
326 src_orig, \
327 (Addr)dst-(Addr)dst_orig+1, \
328 (Addr)src-(Addr)src_orig+1)) \
329 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
331 return dst_orig; \
334 #if defined(VGO_linux)
335 STRCAT(VG_Z_LIBC_SONAME, strcat)
336 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
338 #elif defined(VGO_freebsd)
339 STRCAT(VG_Z_LIBC_SONAME, strcat)
340 STRCAT(VG_Z_LD_ELF_SO_1, strcat)
341 STRCAT(VG_Z_LD_ELF32_SO_1, strcat)
343 #elif defined(VGO_darwin)
344 //STRCAT(VG_Z_LIBC_SONAME, strcat)
346 #elif defined(VGO_solaris)
347 STRCAT(VG_Z_LIBC_SONAME, strcat)
348 STRCAT(VG_Z_LD_SO_1, strcat)
350 #endif
353 /*---------------------- strncat ----------------------*/
355 #define STRNCAT(soname, fnname) \
356 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
357 ( char* dst, const char* src, SizeT n ); \
358 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
359 ( char* dst, const char* src, SizeT n ) \
361 const HChar* src_orig = src; \
362 HChar* dst_orig = dst; \
363 SizeT m = 0; \
365 while (*dst) dst++; \
366 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
367 *dst = 0; /* always add null */ \
369 /* This checks for overlap after copying, unavoidable without */ \
370 /* pre-counting lengths... should be ok */ \
371 if (is_overlap(dst_orig, \
372 src_orig, \
373 (Addr)dst-(Addr)dst_orig+1, \
374 (Addr)src-(Addr)src_orig)) \
375 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
377 return dst_orig; \
380 #if defined(VGO_linux)
381 STRNCAT(VG_Z_LIBC_SONAME, strncat)
383 #elif defined(VGO_freebsd)
384 STRNCAT(VG_Z_LIBC_SONAME, strncat)
386 #elif defined(VGO_darwin)
387 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
388 //STRNCAT(VG_Z_DYLD, strncat)
390 #elif defined(VGO_solaris)
391 STRNCAT(VG_Z_LIBC_SONAME, strncat)
393 #endif
396 /*---------------------- strlcat ----------------------*/
398 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
399 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
400 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
401 Truncation occurred if retval >= n.
403 #define STRLCAT(soname, fnname) \
404 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
405 ( char* dst, const char* src, SizeT n ); \
406 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
407 ( char* dst, const char* src, SizeT n ) \
409 const HChar* src_orig = src; \
410 HChar* dst_orig = dst; \
411 SizeT m = 0; \
413 while (m < n && *dst) { m++; dst++; } \
414 if (m < n) { \
415 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
416 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
417 *dst = 0; \
418 } else { \
419 /* No space to copy anything to dst. m == n */ \
421 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
422 while (*src) { m++; src++; } \
423 /* This checks for overlap after copying, unavoidable without */ \
424 /* pre-counting lengths... should be ok */ \
425 if (is_overlap(dst_orig, \
426 src_orig, \
427 (Addr)dst-(Addr)dst_orig+1, \
428 (Addr)src-(Addr)src_orig+1)) \
429 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
431 return m; \
434 #if defined(VGO_linux)
435 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
437 #elif defined(VGO_freebsd)
438 STRLCAT(VG_Z_LD_ELF_SO_1, strlcat)
439 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
440 STRLCAT(VG_Z_LD_ELF32_SO_1, strlcat)
442 #elif defined(VGO_darwin)
443 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
444 //STRLCAT(VG_Z_DYLD, strlcat)
445 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
447 #elif defined(VGO_solaris)
448 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
450 #endif
453 /*---------------------- strnlen ----------------------*/
455 #define STRNLEN(soname, fnname) \
456 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
457 ( const char* str, SizeT n ); \
458 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
459 ( const char* str, SizeT n ) \
461 SizeT i = 0; \
462 while (i < n && str[i] != 0) i++; \
463 return i; \
466 #if defined(VGO_linux)
467 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
468 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
470 #elif defined(VGO_freebsd)
472 STRNLEN(VG_Z_LIBC_SONAME, srtnlen)
474 #elif defined(VGO_darwin)
475 # if DARWIN_VERS == DARWIN_10_9
476 STRNLEN(libsystemZucZddylib, strnlen)
477 # endif
479 #elif defined(VGO_solaris)
480 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
482 #endif
485 /*---------------------- strlen ----------------------*/
487 // Note that this replacement often doesn't get used because gcc inlines
488 // calls to strlen() with its own built-in version. This can be very
489 // confusing if you aren't expecting it. Other small functions in
490 // this file may also be inline by gcc.
492 #define STRLEN(soname, fnname) \
493 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
494 ( const char* str ); \
495 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
496 ( const char* str ) \
498 SizeT i = 0; \
499 while (str[i] != 0) i++; \
500 return i; \
503 #if defined(VGO_linux)
504 STRLEN(VG_Z_LIBC_SONAME, strlen)
505 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
506 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
507 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
508 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
509 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
510 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
511 # if defined(VGPV_arm_linux_android) \
512 || defined(VGPV_x86_linux_android) \
513 || defined(VGPV_mips32_linux_android)
514 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
515 # endif
517 #elif defined(VGO_freebsd)
518 STRLEN(VG_Z_LIBC_SONAME, strlen)
519 STRLEN(VG_Z_LD_ELF_SO_1, strlen)
520 STRLEN(VG_Z_LD_ELF32_SO_1, strlen)
522 #elif defined(VGO_darwin)
523 STRLEN(VG_Z_LIBC_SONAME, strlen)
524 # if DARWIN_VERS >= DARWIN_10_9
525 STRLEN(libsystemZucZddylib, strlen)
526 # endif
528 #elif defined(VGO_solaris)
529 STRLEN(VG_Z_LIBC_SONAME, strlen)
530 STRLEN(VG_Z_LD_SO_1, strlen)
532 #endif
535 /*---------------------- strcpy ----------------------*/
537 #define STRCPY(soname, fnname) \
538 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
539 ( char* dst, const char* src ); \
540 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
541 ( char* dst, const char* src ) \
543 const HChar* src_orig = src; \
544 HChar* dst_orig = dst; \
546 while (*src) *dst++ = *src++; \
547 *dst = 0; \
549 /* This happens after copying, unavoidable without */ \
550 /* pre-counting length... should be ok */ \
551 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
552 RECORD_COPY(srclen); \
553 if (is_overlap(dst_orig, \
554 src_orig, \
555 (Addr)dst-(Addr)dst_orig+1, \
556 srclen)) \
557 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
559 return dst_orig; \
562 #if defined(VGO_linux)
563 STRCPY(VG_Z_LIBC_SONAME, strcpy)
564 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
566 #elif defined(VGO_freebsd)
567 STRCPY(VG_Z_LIBC_SONAME, strcpy)
568 STRCPY(VG_Z_LD_ELF_SO_1, strcpy)
569 STRCPY(VG_Z_LD_ELF32_SO_1, strcpy)
571 #elif defined(VGO_darwin)
572 STRCPY(VG_Z_LIBC_SONAME, strcpy)
573 # if DARWIN_VERS == DARWIN_10_9
574 STRCPY(libsystemZucZddylib, strcpy)
575 # endif
577 #elif defined(VGO_solaris)
578 STRCPY(VG_Z_LIBC_SONAME, strcpy)
579 STRCPY(VG_Z_LD_SO_1, strcpy)
581 #endif
584 /*---------------------- strncpy ----------------------*/
586 #define STRNCPY(soname, fnname) \
587 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
588 ( char* dst, const char* src, SizeT n ); \
589 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
590 ( char* dst, const char* src, SizeT n ) \
592 const HChar* src_orig = src; \
593 HChar* dst_orig = dst; \
594 SizeT m = 0; \
596 while (m < n && *src) { m++; *dst++ = *src++; } \
597 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
598 /* but only m+1 bytes of src if terminator was found */ \
599 SizeT srclen = (m < n) ? m+1 : n; \
600 RECORD_COPY(srclen); \
601 if (is_overlap(dst_orig, src_orig, n, srclen)) \
602 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
603 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
605 return dst_orig; \
608 #if defined(VGO_linux)
609 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
610 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
611 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
612 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
614 #elif defined(VGO_freebsd)
615 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
616 STRNCPY(VG_Z_LD_ELF_SO_1, strncpy)
617 STRNCPY(VG_Z_LD_ELF32_SO_1, strncpy)
619 #elif defined(VGO_darwin)
620 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
621 # if DARWIN_VERS >= DARWIN_10_9
622 STRNCPY(libsystemZucZddylib, strncpy)
623 # endif
625 #elif defined(VGO_solaris)
626 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
627 STRNCPY(VG_Z_LD_SO_1, strncpy)
629 #endif
632 /*---------------------- strlcpy ----------------------*/
634 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
635 Returns strlen(src). Does not zero-fill the remainder of dst. */
636 #define STRLCPY(soname, fnname) \
637 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
638 ( char* dst, const char* src, SizeT n ); \
639 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
640 ( char* dst, const char* src, SizeT n ) \
642 const HChar* src_orig = src; \
643 HChar* dst_orig = dst; \
644 SizeT m = 0; \
646 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
648 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
649 /* m non-nul bytes have now been copied, and m <= n-1. */ \
650 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
651 /* but only m+1 bytes of src if terminator was found */ \
652 SizeT srclen = (m < n) ? m+1 : n; \
653 RECORD_COPY(srclen); \
654 if (is_overlap(dst_orig, src_orig, n, srclen)) \
655 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
656 /* Nul-terminate dst. */ \
657 if (n > 0) *dst = 0; \
658 /* Finish counting strlen(src). */ \
659 while (*src) src++; \
660 return src - src_orig; \
663 #if defined(VGO_linux)
665 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
666 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
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
1003 # if DARWIN_VERS >= DARWIN_10_12
1004 /* _platform_memchr$VARIANT$Base */
1005 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Base)
1006 #endif
1008 #elif defined(VGO_solaris)
1009 MEMCHR(VG_Z_LIBC_SONAME, memchr)
1011 #endif
1014 /*---------------------- memrchr ----------------------*/
1016 #define MEMRCHR(soname, fnname) \
1017 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1018 (const void *s, int c, SizeT n); \
1019 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1020 (const void *s, int c, SizeT n) \
1022 SizeT i; \
1023 UChar c0 = (UChar)c; \
1024 const UChar* p = s; \
1025 for (i = 0; i < n; i++) \
1026 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1027 return NULL; \
1030 #if defined(VGO_linux)
1031 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1033 #elif defined(VGO_freebsd)
1034 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1036 #elif defined(VGO_darwin)
1037 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1038 //MEMRCHR(VG_Z_DYLD, memrchr)
1040 #elif defined(VGO_solaris)
1042 #endif
1045 /*---------------------- memcpy ----------------------*/
1047 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1048 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1049 ( void *dst, const void *src, SizeT len ); \
1050 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1051 ( void *dst, const void *src, SizeT len ) \
1053 RECORD_COPY(len); \
1054 if (do_ol_check && is_overlap(dst, src, len, len)) \
1055 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1057 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1058 const Addr WM = WS - 1; /* 7 or 3 */ \
1060 if (len > 0) { \
1061 if (dst < src || !is_overlap(dst, src, len, len)) { \
1063 /* Copying backwards. */ \
1064 SizeT n = len; \
1065 Addr d = (Addr)dst; \
1066 Addr s = (Addr)src; \
1068 if (((s^d) & WM) == 0) { \
1069 /* s and d have same UWord alignment. */ \
1070 /* Pull up to a UWord boundary. */ \
1071 while ((s & WM) != 0 && n >= 1) \
1072 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1073 /* Copy UWords. */ \
1074 while (n >= WS * 4) \
1075 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1076 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1077 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
1078 *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1079 while (n >= WS) \
1080 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1081 if (n == 0) \
1082 return dst; \
1084 if (((s|d) & 1) == 0) { \
1085 /* Both are 16-aligned; copy what we can thusly. */ \
1086 while (n >= 2) \
1087 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1089 /* Copy leftovers, or everything if misaligned. */ \
1090 while (n >= 1) \
1091 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1093 } else if (dst > src) { \
1095 SizeT n = len; \
1096 Addr d = ((Addr)dst) + n; \
1097 Addr s = ((Addr)src) + n; \
1099 /* Copying forwards. */ \
1100 if (((s^d) & WM) == 0) { \
1101 /* s and d have same UWord alignment. */ \
1102 /* Back down to a UWord boundary. */ \
1103 while ((s & WM) != 0 && n >= 1) \
1104 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1105 /* Copy UWords. */ \
1106 while (n >= WS * 4) \
1107 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1108 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1109 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
1110 s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1111 while (n >= WS) \
1112 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1113 if (n == 0) \
1114 return dst; \
1116 if (((s|d) & 1) == 0) { \
1117 /* Both are 16-aligned; copy what we can thusly. */ \
1118 while (n >= 2) \
1119 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1121 /* Copy leftovers, or everything if misaligned. */ \
1122 while (n >= 1) \
1123 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1128 return dst; \
1131 #define MEMMOVE(soname, fnname) \
1132 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1134 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1135 why we disable the overlap check on x86_64. */
1136 #if defined(VGP_amd64_linux)
1137 #define MEMCPY(soname, fnname) \
1138 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 0)
1139 #else
1140 #define MEMCPY(soname, fnname) \
1141 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1142 #endif
1144 #if defined(VGO_linux)
1145 /* For older memcpy we have to use memmove-like semantics and skip
1146 the overlap check; sigh; see #275284. */
1147 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1148 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1149 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1150 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1151 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1152 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_avx_unaligned_erms)
1153 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1154 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1155 /* icc9 blats these around all over the place. Not only in the main
1156 executable but various .so's. They are highly tuned and read
1157 memory beyond the source boundary (although work correctly and
1158 never go across page boundaries), so give errors when run
1159 natively, at least for misaligned source arg. Just intercepting
1160 in the exe only until we understand more about the problem. See
1161 http://bugs.kde.org/show_bug.cgi?id=139776
1163 MEMCPY(NONE, ZuintelZufastZumemcpy)
1165 #elif defined(VGO_freebsd)
1166 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1167 MEMCPY(VG_Z_LD_ELF_SO_1, memcpy)
1168 MEMCPY(VG_Z_LD_ELF32_SO_1, memcpy)
1170 #elif defined(VGO_darwin)
1171 # if DARWIN_VERS <= DARWIN_10_6
1172 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1173 # endif
1174 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1175 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1177 #elif defined(VGO_solaris)
1178 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1179 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
1180 MEMCPY(VG_Z_LD_SO_1, memcpy)
1182 #endif
1185 /*---------------------- memcmp ----------------------*/
1187 #define MEMCMP(soname, fnname) \
1188 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1189 ( const void *s1V, const void *s2V, SizeT n ); \
1190 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1191 ( const void *s1V, const void *s2V, SizeT n ) \
1193 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1194 const SizeT WM = WS - 1; /* 7 or 3 */ \
1195 Addr s1A = (Addr)s1V; \
1196 Addr s2A = (Addr)s2V; \
1198 if (((s1A | s2A) & WM) == 0) { \
1199 /* Both areas are word aligned. Skip over the */ \
1200 /* equal prefix as fast as possible. */ \
1201 while (n >= WS) { \
1202 UWord w1 = *(UWord*)s1A; \
1203 UWord w2 = *(UWord*)s2A; \
1204 if (w1 != w2) break; \
1205 s1A += WS; \
1206 s2A += WS; \
1207 n -= WS; \
1211 const UChar* s1 = (const UChar*) s1A; \
1212 const UChar* s2 = (const UChar*) s2A; \
1214 while (n != 0) { \
1215 UChar a0 = s1[0]; \
1216 UChar b0 = s2[0]; \
1217 s1 += 1; \
1218 s2 += 1; \
1219 int res = ((int)a0) - ((int)b0); \
1220 if (res != 0) \
1221 return res; \
1222 n -= 1; \
1224 return 0; \
1227 #if defined(VGO_linux)
1228 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1229 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1230 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1231 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1232 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1233 MEMCMP(VG_Z_LD_SO_1, bcmp)
1235 #elif defined(VGO_freebsd)
1236 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1237 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1238 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_memcmp)
1239 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_bcmp)
1241 #elif defined(VGO_darwin)
1242 # if DARWIN_VERS >= DARWIN_10_9
1243 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1244 # endif
1246 #elif defined(VGO_solaris)
1247 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1248 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1249 MEMCMP(VG_Z_LD_SO_1, memcmp)
1251 #endif
1254 /*---------------------- stpcpy ----------------------*/
1256 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1257 DEST. (minor variant of strcpy) */
1258 #define STPCPY(soname, fnname) \
1259 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1260 ( char* dst, const char* src ); \
1261 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1262 ( char* dst, const char* src ) \
1264 const HChar* src_orig = src; \
1265 HChar* dst_orig = dst; \
1267 while (*src) *dst++ = *src++; \
1268 *dst = 0; \
1270 /* This checks for overlap after copying, unavoidable without */ \
1271 /* pre-counting length... should be ok */ \
1272 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1273 RECORD_COPY(srclen); \
1274 if (is_overlap(dst_orig, \
1275 src_orig, \
1276 (Addr)dst-(Addr)dst_orig+1, \
1277 srclen)) \
1278 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1280 return dst; \
1283 #if defined(VGO_linux)
1284 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1285 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1286 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1287 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1288 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1289 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1290 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1292 #elif defined(VGO_freebsd)
1293 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1294 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1295 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1297 #elif defined(VGO_freebsd)
1298 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1299 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1300 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1302 #elif defined(VGO_darwin)
1303 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1304 //STPCPY(VG_Z_DYLD, stpcpy)
1306 #elif defined(VGO_solaris)
1307 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1309 #endif
1312 /*---------------------- stpncpy ----------------------*/
1314 #define STPNCPY(soname, fnname) \
1315 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1316 ( char* dst, const char* src, SizeT n ); \
1317 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1318 ( char* dst, const char* src, SizeT n ) \
1320 const HChar* src_orig = src; \
1321 HChar* dst_str = dst; \
1322 SizeT m = 0; \
1324 while (m < n && *src) { m++; *dst++ = *src++; } \
1325 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1326 /* but only m+1 bytes of src if terminator was found */ \
1327 SizeT srclen = (m < n) ? m+1 : n; \
1328 RECORD_COPY(srclen); \
1329 if (is_overlap(dst_str, src_orig, n, srclen)) \
1330 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1331 dst_str = dst; \
1332 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1334 return dst_str; \
1337 #if defined(VGO_linux) || defined(VGO_freebsd)
1338 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1339 #endif
1342 /*---------------------- memset ----------------------*/
1344 #define MEMSET(soname, fnname) \
1345 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1346 (void *s, Int c, SizeT n); \
1347 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1348 (void *s, Int c, SizeT n) \
1350 if (sizeof(void*) == 8) { \
1351 Addr a = (Addr)s; \
1352 ULong c8 = (c & 0xFF); \
1353 c8 = (c8 << 8) | c8; \
1354 c8 = (c8 << 16) | c8; \
1355 c8 = (c8 << 32) | c8; \
1356 while ((a & 7) != 0 && n >= 1) \
1357 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1358 while (n >= 32) \
1359 { *(ULong*)a = c8; a += 8; n -= 8; \
1360 *(ULong*)a = c8; a += 8; n -= 8; \
1361 *(ULong*)a = c8; a += 8; n -= 8; \
1362 *(ULong*)a = c8; a += 8; n -= 8; } \
1363 while (n >= 8) \
1364 { *(ULong*)a = c8; a += 8; n -= 8; } \
1365 while (n >= 1) \
1366 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1367 return s; \
1368 } else { \
1369 Addr a = (Addr)s; \
1370 UInt c4 = (c & 0xFF); \
1371 c4 = (c4 << 8) | c4; \
1372 c4 = (c4 << 16) | c4; \
1373 while ((a & 3) != 0 && n >= 1) \
1374 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1375 while (n >= 16) \
1376 { *(UInt*)a = c4; a += 4; n -= 4; \
1377 *(UInt*)a = c4; a += 4; n -= 4; \
1378 *(UInt*)a = c4; a += 4; n -= 4; \
1379 *(UInt*)a = c4; a += 4; n -= 4; } \
1380 while (n >= 4) \
1381 { *(UInt*)a = c4; a += 4; n -= 4; } \
1382 while (n >= 1) \
1383 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1384 return s; \
1388 #if defined(VGO_linux)
1389 MEMSET(VG_Z_LIBC_SONAME, memset)
1391 #elif defined(VGO_freebsd)
1392 MEMSET(VG_Z_LIBC_SONAME, memset)
1393 MEMSET(VG_Z_LD_ELF_SO_1, memset)
1394 MEMSET(VG_Z_LD_ELF32_SO_1, memset)
1396 #elif defined(VGO_darwin)
1397 //MEMSET(VG_Z_LIBC_SONAME, memset)
1398 //MEMSET(VG_Z_DYLD, memset)
1399 MEMSET(VG_Z_LIBC_SONAME, memset)
1401 #elif defined(VGO_solaris)
1402 MEMSET(VG_Z_LIBC_SONAME, memset)
1403 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1405 #endif
1408 /*---------------------- memmove ----------------------*/
1410 /* memmove -- use the MEMMOVE defn above. */
1412 #if defined(VGO_linux)
1413 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1414 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1415 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1416 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1417 to call memcpy. */
1418 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1420 #elif defined(VGO_freebsd)
1421 MEMMOVE(VG_Z_LD_ELF_SO_1, memmove)
1422 MEMMOVE(VG_Z_LD_ELF32_SO_1, memmove)
1423 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1425 #elif defined(VGO_darwin)
1426 # if DARWIN_VERS <= DARWIN_10_6
1427 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1428 # endif
1429 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1430 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1431 # if DARWIN_VERS >= DARWIN_10_9
1432 /* _platform_memmove$VARIANT$Ivybridge */
1433 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1434 # endif
1436 #elif defined(VGO_solaris)
1437 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1438 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1439 MEMMOVE(VG_Z_LD_SO_1, memmove)
1441 #endif
1444 /*---------------------- bcopy ----------------------*/
1446 #define BCOPY(soname, fnname) \
1447 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1448 (const void *srcV, void *dstV, SizeT n); \
1449 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1450 (const void *srcV, void *dstV, SizeT n) \
1452 RECORD_COPY(n); \
1453 SizeT i; \
1454 HChar* dst = dstV; \
1455 const HChar* src = srcV; \
1456 if (dst < src) { \
1457 for (i = 0; i < n; i++) \
1458 dst[i] = src[i]; \
1460 else \
1461 if (dst > src) { \
1462 for (i = 0; i < n; i++) \
1463 dst[n-i-1] = src[n-i-1]; \
1467 #if defined(VGO_linux)
1468 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1470 #elif defined(VGO_freebsd)
1471 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1472 BCOPY(VG_Z_LD_ELF_SO_1, bcopy)
1473 BCOPY(VG_Z_LD_ELF32_SO_1, bcopy)
1475 #elif defined(VGO_darwin)
1476 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1477 //BCOPY(VG_Z_DYLD, bcopy)
1479 #elif defined(VGO_darwin)
1480 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1482 #endif
1485 /*-------------------- memmove_chk --------------------*/
1487 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1488 There is no specific part of glibc that this is copied from. */
1489 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1490 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1491 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1492 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1493 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1495 RECORD_COPY(n); \
1496 SizeT i; \
1497 HChar* dst = dstV; \
1498 const HChar* src = srcV; \
1499 if (destlen < n) \
1500 goto badness; \
1501 if (dst < src) { \
1502 for (i = 0; i < n; i++) \
1503 dst[i] = src[i]; \
1505 else \
1506 if (dst > src) { \
1507 for (i = 0; i < n; i++) \
1508 dst[n-i-1] = src[n-i-1]; \
1510 return dst; \
1511 badness: \
1512 VALGRIND_PRINTF_BACKTRACE( \
1513 "*** memmove_chk: buffer overflow detected ***: " \
1514 "program terminated\n"); \
1515 my_exit(1); \
1516 /*NOTREACHED*/ \
1517 return NULL; \
1520 #if defined(VGO_linux)
1521 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1523 #elif defined(VGO_darwin)
1525 #elif defined(VGO_solaris)
1527 #endif
1530 /*-------------------- strchrnul --------------------*/
1532 /* Find the first occurrence of C in S or the final NUL byte. */
1533 #define GLIBC232_STRCHRNUL(soname, fnname) \
1534 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1535 (const char* s, int c_in); \
1536 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1537 (const char* s, int c_in) \
1539 HChar c = (HChar) c_in; \
1540 const HChar* char_ptr = s; \
1541 while (1) { \
1542 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1543 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1544 char_ptr++; \
1548 #if defined(VGO_linux)
1549 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1551 #elif defined(VGO_freebsd)
1552 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1554 #elif defined(VGO_darwin)
1556 #elif defined(VGO_solaris)
1558 #endif
1561 /*---------------------- rawmemchr ----------------------*/
1563 /* Find the first occurrence of C in S. */
1564 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1565 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1566 (const void* s, int c_in); \
1567 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1568 (const void* s, int c_in) \
1570 UChar c = (UChar) c_in; \
1571 const UChar* char_ptr = s; \
1572 while (1) { \
1573 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1574 char_ptr++; \
1578 #if defined (VGO_linux)
1579 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1580 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1582 #elif defined(VGO_darwin)
1584 #elif defined(VGO_solaris)
1586 #endif
1589 /*---------------------- strcpy_chk ----------------------*/
1591 /* glibc variant of strcpy that checks the dest is big enough.
1592 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1593 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1594 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1595 (char* dst, const char* src, SizeT len); \
1596 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1597 (char* dst, const char* src, SizeT len) \
1599 FOR_COPY(const HChar* src_orig = src); \
1600 HChar* ret = dst; \
1601 if (! len) \
1602 goto badness; \
1603 while ((*dst++ = *src++) != '\0') \
1604 if (--len == 0) \
1605 goto badness; \
1606 RECORD_COPY((Addr)src-(Addr)src_orig); \
1607 return ret; \
1608 badness: \
1609 VALGRIND_PRINTF_BACKTRACE( \
1610 "*** strcpy_chk: buffer overflow detected ***: " \
1611 "program terminated\n"); \
1612 my_exit(1); \
1613 /*NOTREACHED*/ \
1614 return NULL; \
1617 #if defined(VGO_linux)
1618 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1620 #elif defined(VGO_darwin)
1622 #elif defined(VGO_solaris)
1624 #endif
1627 /*---------------------- stpcpy_chk ----------------------*/
1629 /* glibc variant of stpcpy that checks the dest is big enough.
1630 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1631 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1632 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1633 (char* dst, const char* src, SizeT len); \
1634 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1635 (char* dst, const char* src, SizeT len) \
1637 FOR_COPY(const HChar* src_orig = src); \
1638 if (! len) \
1639 goto badness; \
1640 while ((*dst++ = *src++) != '\0') \
1641 if (--len == 0) \
1642 goto badness; \
1643 RECORD_COPY((Addr)src-(Addr)src_orig); \
1644 return dst - 1; \
1645 badness: \
1646 VALGRIND_PRINTF_BACKTRACE( \
1647 "*** stpcpy_chk: buffer overflow detected ***: " \
1648 "program terminated\n"); \
1649 my_exit(1); \
1650 /*NOTREACHED*/ \
1651 return NULL; \
1654 #if defined(VGO_linux)
1655 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1657 #elif defined(VGO_darwin)
1659 #elif defined(VGO_solaris)
1661 #endif
1664 /*---------------------- mempcpy ----------------------*/
1666 /* mempcpy */
1667 #define GLIBC25_MEMPCPY(soname, fnname) \
1668 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1669 ( void *dst, const void *src, SizeT len ); \
1670 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1671 ( void *dst, const void *src, SizeT len ) \
1673 RECORD_COPY(len); \
1674 SizeT len_saved = len; \
1676 if (len == 0) \
1677 return dst; \
1679 if (is_overlap(dst, src, len, len)) \
1680 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1682 if ( dst > src ) { \
1683 register HChar *d = (char *)dst + len - 1; \
1684 register const HChar *s = (const char *)src + len - 1; \
1685 while ( len-- ) { \
1686 *d-- = *s--; \
1688 } else if ( dst < src ) { \
1689 register HChar *d = dst; \
1690 register const HChar *s = src; \
1691 while ( len-- ) { \
1692 *d++ = *s++; \
1695 return (void*)( ((char*)dst) + len_saved ); \
1698 #if defined(VGO_linux)
1699 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1700 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1701 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1702 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1703 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1705 #elif defined(VGO_freebsd)
1706 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1707 #elif defined(VGO_darwin)
1708 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1710 #elif defined(VGO_solaris)
1712 #endif
1715 /*-------------------- memcpy_chk --------------------*/
1717 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1718 why we disable the overlap check on x86_64. */
1719 #if defined(VGP_amd64_linux)
1720 #define CHECK_OVERLAP 0
1721 #else
1722 #define CHECK_OVERLAP 1
1723 #endif
1725 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1726 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1727 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1728 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1729 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1731 register HChar *d; \
1732 register const HChar *s; \
1733 if (dstlen < len) \
1734 goto badness; \
1735 RECORD_COPY(len); \
1736 if (len == 0) \
1737 return dst; \
1738 if (CHECK_OVERLAP && is_overlap(dst, src, len, len)) \
1739 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1740 if ( dst > src ) { \
1741 d = (HChar *)dst + len - 1; \
1742 s = (const HChar *)src + len - 1; \
1743 while ( len-- ) { \
1744 *d-- = *s--; \
1746 } else if ( dst < src ) { \
1747 d = (HChar *)dst; \
1748 s = (const HChar *)src; \
1749 while ( len-- ) { \
1750 *d++ = *s++; \
1753 return dst; \
1754 badness: \
1755 VALGRIND_PRINTF_BACKTRACE( \
1756 "*** memcpy_chk: buffer overflow detected ***: " \
1757 "program terminated\n"); \
1758 my_exit(1); \
1759 /*NOTREACHED*/ \
1760 return NULL; \
1763 #if defined(VGO_linux)
1764 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1766 #elif defined(VGO_darwin)
1768 #elif defined(VGO_solaris)
1770 #endif
1773 /*---------------------- strstr ----------------------*/
1775 #define STRSTR(soname, fnname) \
1776 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1777 (const char* haystack, const char* needle); \
1778 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1779 (const char* haystack, const char* needle) \
1781 const HChar* h = haystack; \
1782 const HChar* n = needle; \
1784 /* find the length of n, not including terminating zero */ \
1785 UWord nlen = 0; \
1786 while (n[nlen]) nlen++; \
1788 /* if n is the empty string, match immediately. */ \
1789 if (nlen == 0) return CONST_CAST(HChar *,h); \
1791 /* assert(nlen >= 1); */ \
1792 HChar n0 = n[0]; \
1794 while (1) { \
1795 const HChar hh = *h; \
1796 if (hh == 0) return NULL; \
1797 if (hh != n0) { h++; continue; } \
1799 UWord i; \
1800 for (i = 0; i < nlen; i++) { \
1801 if (n[i] != h[i]) \
1802 break; \
1804 /* assert(i >= 0 && i <= nlen); */ \
1805 if (i == nlen) \
1806 return CONST_CAST(HChar *,h); \
1808 h++; \
1812 #if defined(VGO_linux)
1813 STRSTR(VG_Z_LIBC_SONAME, strstr)
1814 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1815 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1817 #elif defined(VGO_freebsd)
1818 STRSTR(VG_Z_LIBC_SONAME, strstr)
1820 #elif defined(VGO_darwin)
1822 #elif defined(VGO_solaris)
1823 STRSTR(VG_Z_LIBC_SONAME, strstr)
1825 #endif
1827 /*---------------------- memmem ----------------------*/
1829 #define MEMMEM(soname, fnname) \
1830 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1831 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1832 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1833 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1835 const HChar* h = haystack; \
1836 const HChar* n = needle; \
1838 /* If the needle is the empty string, match immediately. */ \
1839 if (nlen == 0) return CONST_CAST(void *,h); \
1841 HChar n0 = n[0]; \
1843 for (; hlen >= nlen; hlen--, h++) { \
1844 if (h[0] != n0) continue; \
1846 UWord i; \
1847 for (i = 1; i < nlen; i++) { \
1848 if (n[i] != h[i]) \
1849 break; \
1851 if (i == nlen) \
1852 return CONST_CAST(HChar *,h); \
1855 return NULL; \
1858 #if defined(VGP_s390x_linux)
1859 MEMMEM(VG_Z_LIBC_SONAME, memmem)
1860 #endif
1863 /*---------------------- strpbrk ----------------------*/
1865 #define STRPBRK(soname, fnname) \
1866 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1867 (const char* sV, const char* acceptV); \
1868 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1869 (const char* sV, const char* acceptV) \
1871 const HChar* s = sV; \
1872 const HChar* accept = acceptV; \
1874 /* find the length of 'accept', not including terminating zero */ \
1875 UWord nacc = 0; \
1876 while (accept[nacc]) nacc++; \
1878 /* if n is the empty string, fail immediately. */ \
1879 if (nacc == 0) return NULL; \
1881 /* assert(nacc >= 1); */ \
1882 while (1) { \
1883 UWord i; \
1884 HChar sc = *s; \
1885 if (sc == 0) \
1886 break; \
1887 for (i = 0; i < nacc; i++) { \
1888 if (sc == accept[i]) \
1889 return CONST_CAST(HChar *,s); \
1891 s++; \
1894 return NULL; \
1897 #if defined(VGO_linux)
1898 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1900 #elif defined(VGO_freebsd)
1901 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1903 #elif defined(VGO_darwin)
1905 #elif defined(VGO_solaris)
1906 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1908 #endif
1911 /*---------------------- strcspn ----------------------*/
1913 #define STRCSPN(soname, fnname) \
1914 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1915 (const char* sV, const char* rejectV); \
1916 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1917 (const char* sV, const char* rejectV) \
1919 const HChar* s = sV; \
1920 const HChar* reject = rejectV; \
1922 /* find the length of 'reject', not including terminating zero */ \
1923 UWord nrej = 0; \
1924 while (reject[nrej]) nrej++; \
1926 UWord len = 0; \
1927 while (1) { \
1928 UWord i; \
1929 HChar sc = *s; \
1930 if (sc == 0) \
1931 break; \
1932 for (i = 0; i < nrej; i++) { \
1933 if (sc == reject[i]) \
1934 break; \
1936 /* assert(i >= 0 && i <= nrej); */ \
1937 if (i < nrej) \
1938 break; \
1939 s++; \
1940 len++; \
1943 return len; \
1946 #if defined(VGO_linux)
1947 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1948 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1950 #elif defined(VGO_freebsd)
1951 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1953 #elif defined(VGO_darwin)
1955 #elif defined(VGO_solaris)
1956 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1958 #endif
1961 /*---------------------- strspn ----------------------*/
1963 #define STRSPN(soname, fnname) \
1964 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1965 (const char* sV, const char* acceptV); \
1966 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1967 (const char* sV, const char* acceptV) \
1969 const UChar* s = (const UChar *)sV; \
1970 const UChar* accept = (const UChar *)acceptV; \
1972 /* find the length of 'accept', not including terminating zero */ \
1973 UWord nacc = 0; \
1974 while (accept[nacc]) nacc++; \
1975 if (nacc == 0) return 0; \
1977 UWord len = 0; \
1978 while (1) { \
1979 UWord i; \
1980 UChar sc = *s; \
1981 if (sc == 0) \
1982 break; \
1983 for (i = 0; i < nacc; i++) { \
1984 if (sc == accept[i]) \
1985 break; \
1987 /* assert(i >= 0 && i <= nacc); */ \
1988 if (i == nacc) \
1989 break; \
1990 s++; \
1991 len++; \
1994 return len; \
1997 #if defined(VGO_linux)
1998 STRSPN(VG_Z_LIBC_SONAME, strspn)
2000 #elif defined(VGO_freebsd)
2001 STRSPN(VG_Z_LIBC_SONAME, strspn)
2003 #elif defined(VGO_darwin)
2005 #elif defined(VGO_solaris)
2006 STRSPN(VG_Z_LIBC_SONAME, strspn)
2008 #endif
2011 /*---------------------- strcasestr ----------------------*/
2013 #define STRCASESTR(soname, fnname) \
2014 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2015 (const char* haystack, const char* needle); \
2016 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2017 (const char* haystack, const char* needle) \
2019 extern int tolower(int); \
2020 const HChar* h = haystack; \
2021 const HChar* n = needle; \
2023 /* find the length of n, not including terminating zero */ \
2024 UWord nlen = 0; \
2025 while (n[nlen]) nlen++; \
2027 /* if n is the empty string, match immediately. */ \
2028 if (nlen == 0) return CONST_CAST(HChar *,h); \
2030 /* assert(nlen >= 1); */ \
2031 UChar n0 = tolower(n[0]); \
2033 while (1) { \
2034 UChar hh = tolower(*h); \
2035 if (hh == 0) return NULL; \
2036 if (hh != n0) { h++; continue; } \
2038 UWord i; \
2039 for (i = 0; i < nlen; i++) { \
2040 if (tolower(n[i]) != tolower(h[i])) \
2041 break; \
2043 /* assert(i >= 0 && i <= nlen); */ \
2044 if (i == nlen) \
2045 return CONST_CAST(HChar *,h); \
2047 h++; \
2051 #if defined(VGO_linux)
2052 # if !defined(VGPV_arm_linux_android) \
2053 && !defined(VGPV_x86_linux_android) \
2054 && !defined(VGPV_mips32_linux_android) \
2055 && !defined(VGPV_arm64_linux_android)
2056 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2057 # endif
2059 #elif defined(VGO_freebsd)
2060 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2062 #elif defined(VGO_darwin)
2064 #elif defined(VGO_solaris)
2065 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2067 #endif
2070 /*---------------------- wcslen ----------------------*/
2072 // This is a wchar_t equivalent to strlen. Unfortunately
2073 // we don't have wchar_t available here, but it looks like
2074 // a 32 bit int on Linux. I don't know if that is also
2075 // valid on MacOSX.
2077 #define WCSLEN(soname, fnname) \
2078 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2079 ( const Int* str ); \
2080 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2081 ( const Int* str ) \
2083 SizeT i = 0; \
2084 while (str[i] != 0) i++; \
2085 return i; \
2088 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2089 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
2091 #endif
2093 /*---------------------- wcsnlen ----------------------*/
2095 #define WCSNLEN(soname, fnname) \
2096 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2097 ( const Int *s, SizeT n ); \
2098 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2099 ( const Int *s, SizeT n ) \
2101 SizeT i = 0; \
2102 const Int* p = s; \
2103 while (i < n && *p != 0) { \
2104 i++; \
2105 p++; \
2107 return i; \
2110 #if defined(VGO_linux) || defined(VGO_freebsd)
2111 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
2112 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
2113 #endif
2115 /*---------------------- wcscmp ----------------------*/
2117 // This is a wchar_t equivalent to strcmp. We don't
2118 // have wchar_t available here, but in the GNU C Library
2119 // wchar_t is always 32 bits wide and wcscmp uses signed
2120 // comparison, not unsigned as in strcmp function.
2122 #define WCSCMP(soname, fnname) \
2123 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2124 ( const Int* s1, const Int* s2 ); \
2125 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2126 ( const Int* s1, const Int* s2 ) \
2128 register Int c1; \
2129 register Int c2; \
2130 while (True) { \
2131 c1 = *s1; \
2132 c2 = *s2; \
2133 if (c1 != c2) break; \
2134 if (c1 == 0) break; \
2135 s1++; s2++; \
2137 if (c1 < c2) return -1; \
2138 if (c1 > c2) return 1; \
2139 return 0; \
2142 #if defined(VGO_linux) || defined(VGO_freebsd)
2143 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
2144 #endif
2146 /*---------------------- wcsncmp ----------------------*/
2148 // This is a wchar_t equivalent to strncmp. We don't
2149 // have wchar_t available here, but in the GNU C Library
2150 // wchar_t is always 32 bits wide and wcsncmp uses signed
2151 // comparison, not unsigned as in strncmp function.
2153 #define WCSNCMP(soname, fnname) \
2154 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2155 ( const Int* s1, const Int* s2, SizeT nmax ); \
2156 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2157 ( const Int* s1, const Int* s2, SizeT nmax ) \
2159 SizeT n = 0; \
2160 while (True) { \
2161 if (n >= nmax) return 0; \
2162 if (*s1 == 0 && *s2 == 0) return 0; \
2163 if (*s1 == 0) return -1; \
2164 if (*s2 == 0) return 1; \
2166 if (*s1 < *s2) return -1; \
2167 if (*s1 > *s2) return 1; \
2169 s1++; s2++; n++; \
2172 #if defined(VGO_linux) || defined(VGO_freebsd)
2173 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
2174 #endif
2176 /*---------------------- wcscpy ----------------------*/
2178 // This is a wchar_t equivalent to strcpy. We don't
2179 // have wchar_t available here, but in the GNU C Library
2180 // wchar_t is always 32 bits wide.
2182 #define WCSCPY(soname, fnname) \
2183 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2184 ( Int* dst, const Int* src ); \
2185 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2186 ( Int* dst, const Int* src ) \
2188 const Int* src_orig = src; \
2189 Int* dst_orig = dst; \
2191 while (*src) *dst++ = *src++; \
2192 *dst = 0; \
2194 /* This checks for overlap after copying, unavoidable without */ \
2195 /* pre-counting length... should be ok */ \
2196 /* +4 because sizeof(wchar_t) == 4 */ \
2197 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2198 RECORD_COPY(srclen); \
2199 if (is_overlap(dst_orig, \
2200 src_orig, \
2201 /* +4 because sizeof(wchar_t) == 4 */ \
2202 (Addr)dst-(Addr)dst_orig+4, \
2203 srclen)) \
2204 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2206 return dst_orig; \
2209 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2210 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2211 #endif
2214 /*---------------------- wcschr ----------------------*/
2216 // This is a wchar_t equivalent to strchr. 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 WCSCHR(soname, fnname) \
2221 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2222 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2224 const Int* p = s; \
2225 while (True) { \
2226 if (*p == c) return CONST_CAST(Int *,p); \
2227 if (*p == 0) return NULL; \
2228 p++; \
2232 #if defined(VGO_linux) || defined(VGO_freebsd)
2233 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2234 #endif
2235 /*---------------------- wcsrchr ----------------------*/
2237 // This is a wchar_t equivalent to strrchr. We don't
2238 // have wchar_t available here, but in the GNU C Library
2239 // wchar_t is always 32 bits wide.
2241 #define WCSRCHR(soname, fnname) \
2242 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2243 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2245 const Int* p = s; \
2246 const Int* last = NULL; \
2247 while (True) { \
2248 if (*p == c) last = p; \
2249 if (*p == 0) return CONST_CAST(Int *,last); \
2250 p++; \
2254 #if defined(VGO_linux) || defined(VGO_freebsd)
2255 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2256 #endif
2258 /*---------------------- wmemchr ----------------------*/
2260 // This is a wchar_t equivalent to memchr. We don't
2261 // have wchar_t available here, but in the GNU C Library
2262 // wchar_t is always 32 bits wide.
2264 #define WMEMCHR(soname, fnname) \
2265 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2266 (const Int *s, Int c, SizeT n); \
2267 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2268 (const Int *s, Int c, SizeT n) \
2270 SizeT i; \
2271 const Int* p = s; \
2272 for (i = 0; i < n; i++) { \
2273 if (*p == c) return CONST_CAST(Int *,p); \
2274 p++; \
2276 return NULL; \
2279 #if defined(VGO_linux)
2280 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2281 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2282 #endif
2284 #if defined(VGO_freebsd)
2285 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2286 #endif
2288 /*---------------------- wmemcmp ----------------------*/
2290 #define WMEMCMP(soname, fnname) \
2291 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2292 ( const Int *b1, const Int *b2, SizeT n ); \
2293 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2294 ( const Int *b1, const Int *b2, SizeT n ) \
2296 for (SizeT i = 0U; i < n; ++i) { \
2297 if (b1[i] != b2[i]) \
2298 return b1[i] > b2[i] ? 1 : -1; \
2300 return 0; \
2303 #if defined(VGO_linux) || defined(VGO_freebsd)
2304 WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
2305 #endif
2307 /*---------------------- wcsncpy ----------------------*/
2309 // This is a wchar_t equivalent to strncpy. We don't
2310 // have wchar_t available here, but in the GNU C Library
2311 // wchar_t is always 32 bits wide.
2313 #define WCSNCPY(soname, fnname) \
2314 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2315 ( Int* dst, const Int* src, SizeT n ); \
2316 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2317 ( Int* dst, const Int* src, SizeT n ) \
2319 const Int* src_orig = src; \
2320 Int* dst_orig = dst; \
2321 SizeT m = 0; \
2323 while (m < n && *src) { \
2324 m++; \
2325 *dst++ = *src++; \
2328 /* This checks for overlap after copying, unavoidable without */ \
2329 /* pre-counting length... should be ok */ \
2330 /* +4 because sizeof(wchar_t) == 4 */ \
2331 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2332 RECORD_COPY(srclen); \
2333 if (is_overlap(dst_orig, \
2334 src_orig, \
2335 n*4, \
2336 srclen)) \
2337 RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
2339 while (m++ < n) { \
2340 *dst++ = 0; \
2343 return dst_orig; \
2346 #if defined(VGO_linux) || defined(VGO_freebsd)
2347 WCSNCPY(VG_Z_LIBC_SONAME, wcsncpy)
2348 #endif
2350 /*---------------------- memccpy ----------------------*/
2352 /* memccpy, mostly based on GNU libc source */
2353 #define MEMCCPY(soname, fnname) \
2354 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2355 ( void *dst, const void *src, Int c, SizeT len ); \
2356 void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
2357 ( void *dst, const void *src, Int c, SizeT len ) \
2359 const char *s = src; \
2360 char *d = dst; \
2361 const char x = c; \
2362 SizeT i = len; \
2364 while (i-- > 0) \
2365 if ((*d++ = *s++) == x) { \
2366 SizeT srclen = (i < len) ? i : len; \
2367 RECORD_COPY(srclen); \
2368 if (is_overlap(dst, src, srclen, srclen)) \
2369 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2370 return d; \
2373 if (len) { \
2374 RECORD_COPY(len); \
2375 if (is_overlap(dst, src, len, len)) \
2376 RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
2378 return NULL; \
2381 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_darwin) || defined(VGO_solaris)
2382 MEMCCPY(VG_Z_LIBC_SONAME, memccpy)
2383 #endif
2385 /*------------------------------------------------------------*/
2386 /*--- Improve definedness checking of process environment ---*/
2387 /*------------------------------------------------------------*/
2389 #if defined(VGO_linux) || defined(VGO_freebsd)
2391 /* If these wind up getting generated via a macro, so that multiple
2392 versions of each function exist (as above), use the _EZU variants
2393 to assign equivalance class tags. */
2395 /*---------------------- putenv ----------------------*/
2397 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2398 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2400 OrigFn fn;
2401 Word result;
2402 const HChar* p = string;
2403 VALGRIND_GET_ORIG_FN(fn);
2404 /* Now by walking over the string we magically produce
2405 traces when hitting undefined memory. */
2406 if (p)
2407 while (*p++)
2408 __asm__ __volatile__("" ::: "memory");
2409 CALL_FN_W_W(result, fn, string);
2410 return result;
2414 /*---------------------- unsetenv ----------------------*/
2416 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2417 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2419 OrigFn fn;
2420 Word result;
2421 const HChar* p = name;
2422 VALGRIND_GET_ORIG_FN(fn);
2423 /* Now by walking over the string we magically produce
2424 traces when hitting undefined memory. */
2425 if (p)
2426 while (*p++)
2427 __asm__ __volatile__("" ::: "memory");
2428 CALL_FN_W_W(result, fn, name);
2429 return result;
2433 /*---------------------- setenv ----------------------*/
2435 /* setenv */
2436 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2437 (const char* name, const char* value, int overwrite);
2438 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2439 (const char* name, const char* value, int overwrite)
2441 OrigFn fn;
2442 Word result;
2443 const HChar* p;
2444 VALGRIND_GET_ORIG_FN(fn);
2445 /* Now by walking over the string we magically produce
2446 traces when hitting undefined memory. */
2447 if (name)
2448 for (p = name; *p; p++)
2449 __asm__ __volatile__("" ::: "memory");
2450 if (value)
2451 for (p = value; *p; p++)
2452 __asm__ __volatile__("" ::: "memory");
2453 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2454 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2455 return result;
2458 #endif /* defined(VGO_linux) */
2460 /*--------------------------------------------------------------------*/
2461 /*--- end ---*/
2462 /*--------------------------------------------------------------------*/