(really) Bug 477630 - Include ucontext.h rather than sys/ucontext.h in Solaris sources
[valgrind.git] / shared / vg_replace_strmem.c
blob16c1bd2f9b0c6304a6830a43c826f8e2cf690a61
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)
434 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
436 #elif defined(VGO_freebsd)
437 STRLCAT(VG_Z_LD_ELF_SO_1, strlcat)
438 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
439 STRLCAT(VG_Z_LD_ELF32_SO_1, strlcat)
441 #elif defined(VGO_darwin)
442 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
443 //STRLCAT(VG_Z_DYLD, strlcat)
444 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
446 #elif defined(VGO_solaris)
447 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
449 #endif
452 /*---------------------- strnlen ----------------------*/
454 #define STRNLEN(soname, fnname) \
455 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
456 ( const char* str, SizeT n ); \
457 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
458 ( const char* str, SizeT n ) \
460 SizeT i = 0; \
461 while (i < n && str[i] != 0) i++; \
462 return i; \
465 #if defined(VGO_linux)
466 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
467 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
469 #elif defined(VGO_freebsd)
471 STRNLEN(VG_Z_LIBC_SONAME, srtnlen)
473 #elif defined(VGO_darwin)
474 # if DARWIN_VERS == DARWIN_10_9
475 STRNLEN(libsystemZucZddylib, strnlen)
476 # endif
478 #elif defined(VGO_solaris)
479 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
481 #endif
484 /*---------------------- strlen ----------------------*/
486 // Note that this replacement often doesn't get used because gcc inlines
487 // calls to strlen() with its own built-in version. This can be very
488 // confusing if you aren't expecting it. Other small functions in
489 // this file may also be inline by gcc.
491 #define STRLEN(soname, fnname) \
492 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
493 ( const char* str ); \
494 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
495 ( const char* str ) \
497 SizeT i = 0; \
498 while (str[i] != 0) i++; \
499 return i; \
502 #if defined(VGO_linux)
503 STRLEN(VG_Z_LIBC_SONAME, strlen)
504 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
505 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
506 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
507 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
508 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
509 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
510 # if defined(VGPV_arm_linux_android) \
511 || defined(VGPV_x86_linux_android) \
512 || defined(VGPV_mips32_linux_android)
513 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
514 # endif
516 #elif defined(VGO_freebsd)
517 STRLEN(VG_Z_LIBC_SONAME, strlen)
518 STRLEN(VG_Z_LD_ELF_SO_1, strlen)
519 STRLEN(VG_Z_LD_ELF32_SO_1, strlen)
521 #elif defined(VGO_darwin)
522 STRLEN(VG_Z_LIBC_SONAME, strlen)
523 # if DARWIN_VERS >= DARWIN_10_9
524 STRLEN(libsystemZucZddylib, strlen)
525 # endif
527 #elif defined(VGO_solaris)
528 STRLEN(VG_Z_LIBC_SONAME, strlen)
529 STRLEN(VG_Z_LD_SO_1, strlen)
531 #endif
534 /*---------------------- strcpy ----------------------*/
536 #define STRCPY(soname, fnname) \
537 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
538 ( char* dst, const char* src ); \
539 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
540 ( char* dst, const char* src ) \
542 const HChar* src_orig = src; \
543 HChar* dst_orig = dst; \
545 while (*src) *dst++ = *src++; \
546 *dst = 0; \
548 /* This happens after copying, unavoidable without */ \
549 /* pre-counting length... should be ok */ \
550 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
551 RECORD_COPY(srclen); \
552 if (is_overlap(dst_orig, \
553 src_orig, \
554 (Addr)dst-(Addr)dst_orig+1, \
555 srclen)) \
556 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
558 return dst_orig; \
561 #if defined(VGO_linux)
562 STRCPY(VG_Z_LIBC_SONAME, strcpy)
563 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
565 #elif defined(VGO_freebsd)
566 STRCPY(VG_Z_LIBC_SONAME, strcpy)
567 STRCPY(VG_Z_LD_ELF_SO_1, strcpy)
568 STRCPY(VG_Z_LD_ELF32_SO_1, strcpy)
570 #elif defined(VGO_darwin)
571 STRCPY(VG_Z_LIBC_SONAME, strcpy)
572 # if DARWIN_VERS == DARWIN_10_9
573 STRCPY(libsystemZucZddylib, strcpy)
574 # endif
576 #elif defined(VGO_solaris)
577 STRCPY(VG_Z_LIBC_SONAME, strcpy)
578 STRCPY(VG_Z_LD_SO_1, strcpy)
580 #endif
583 /*---------------------- strncpy ----------------------*/
585 #define STRNCPY(soname, fnname) \
586 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
587 ( char* dst, const char* src, SizeT n ); \
588 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
589 ( char* dst, const char* src, SizeT n ) \
591 const HChar* src_orig = src; \
592 HChar* dst_orig = dst; \
593 SizeT m = 0; \
595 while (m < n && *src) { m++; *dst++ = *src++; } \
596 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
597 /* but only m+1 bytes of src if terminator was found */ \
598 SizeT srclen = (m < n) ? m+1 : n; \
599 RECORD_COPY(srclen); \
600 if (is_overlap(dst_orig, src_orig, n, srclen)) \
601 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
602 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
604 return dst_orig; \
607 #if defined(VGO_linux)
608 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
609 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
610 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
611 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
613 #elif defined(VGO_freebsd)
614 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
615 STRNCPY(VG_Z_LD_ELF_SO_1, strncpy)
616 STRNCPY(VG_Z_LD_ELF32_SO_1, strncpy)
618 #elif defined(VGO_darwin)
619 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
620 # if DARWIN_VERS >= DARWIN_10_9
621 STRNCPY(libsystemZucZddylib, strncpy)
622 # endif
624 #elif defined(VGO_solaris)
625 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
626 STRNCPY(VG_Z_LD_SO_1, strncpy)
628 #endif
631 /*---------------------- strlcpy ----------------------*/
633 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
634 Returns strlen(src). Does not zero-fill the remainder of dst. */
635 #define STRLCPY(soname, fnname) \
636 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
637 ( char* dst, const char* src, SizeT n ); \
638 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
639 ( char* dst, const char* src, SizeT n ) \
641 const HChar* src_orig = src; \
642 HChar* dst_orig = dst; \
643 SizeT m = 0; \
645 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
647 while (m+1 < n && *src) { m++; *dst++ = *src++; } \
648 /* m non-nul bytes have now been copied, and m <= n-1. */ \
649 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
650 /* but only m+1 bytes of src if terminator was found */ \
651 SizeT srclen = (m < n) ? m+1 : n; \
652 RECORD_COPY(srclen); \
653 if (is_overlap(dst_orig, src_orig, n, srclen)) \
654 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
655 /* Nul-terminate dst. */ \
656 if (n > 0) *dst = 0; \
657 /* Finish counting strlen(src). */ \
658 while (*src) src++; \
659 return src - src_orig; \
662 #if defined(VGO_linux)
664 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
665 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
667 #elif defined(VGO_freebsd)
668 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
669 STRLCPY(VG_Z_LD_ELF_SO_1, strlcpy)
670 STRLCPY(VG_Z_LD_ELF32_SO_1, strlcpy)
671 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
673 #elif defined(VGO_darwin)
674 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
675 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
676 //STRLCPY(VG_Z_DYLD, strlcpy)
677 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
679 #elif defined(VGO_solaris)
680 /* special case for n == 0 which is undocumented but heavily used */
681 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
682 if (n == 0) { \
683 while (*src) src++; \
684 return src - src_orig; \
687 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
689 #endif
692 /*---------------------- strncmp ----------------------*/
694 #define STRNCMP(soname, fnname) \
695 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
696 ( const char* s1, const char* s2, SizeT nmax ); \
697 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
698 ( const char* s1, const char* s2, SizeT nmax ) \
700 SizeT n = 0; \
701 while (True) { \
702 if (n >= nmax) return 0; \
703 if (*s1 == 0 && *s2 == 0) return 0; \
704 if (*s1 == 0) return -1; \
705 if (*s2 == 0) return 1; \
707 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
708 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
710 s1++; s2++; n++; \
714 #if defined(VGO_linux)
715 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
716 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
717 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
718 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
719 STRNCMP(VG_Z_LD_LINUX_SO_2, strncmp)
720 STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2, strncmp)
722 #elif defined(VGO_freebsd)
723 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
724 STRNCMP(VG_Z_LD_ELF_SO_1, strncmp)
725 STRNCMP(VG_Z_LD_ELF32_SO_1, strncmp)
727 #elif defined(VGO_darwin)
728 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
729 # if DARWIN_VERS >= DARWIN_10_9
730 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
731 # endif
733 #elif defined(VGO_solaris)
734 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
736 #endif
739 /*---------------------- strcasecmp ----------------------*/
741 #define STRCASECMP(soname, fnname) \
742 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
743 ( const char* s1, const char* s2 ); \
744 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
745 ( const char* s1, const char* s2 ) \
747 extern int tolower(int); \
748 register UChar c1; \
749 register UChar c2; \
750 while (True) { \
751 c1 = tolower(*(const UChar *)s1); \
752 c2 = tolower(*(const UChar *)s2); \
753 if (c1 != c2) break; \
754 if (c1 == 0) break; \
755 s1++; s2++; \
757 if ((UChar)c1 < (UChar)c2) return -1; \
758 if ((UChar)c1 > (UChar)c2) return 1; \
759 return 0; \
762 #if defined(VGO_linux)
763 # if !defined(VGPV_arm_linux_android) \
764 && !defined(VGPV_x86_linux_android) \
765 && !defined(VGPV_mips32_linux_android) \
766 && !defined(VGPV_arm64_linux_android)
767 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
768 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
769 # endif
771 #elif defined(VGO_freebsd)
772 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
773 STRNCMP(VG_Z_LD_ELF_SO_1, strcasecmp)
774 STRNCMP(VG_Z_LD_ELF32_SO_1, strcasecmp)
776 #elif defined(VGO_darwin)
777 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
779 #elif defined(VGO_solaris)
780 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
782 #endif
785 /*---------------------- strncasecmp ----------------------*/
787 #define STRNCASECMP(soname, fnname) \
788 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
789 ( const char* s1, const char* s2, SizeT nmax ); \
790 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
791 ( const char* s1, const char* s2, SizeT nmax ) \
793 extern int tolower(int); \
794 SizeT n = 0; \
795 while (True) { \
796 if (n >= nmax) return 0; \
797 if (*s1 == 0 && *s2 == 0) return 0; \
798 if (*s1 == 0) return -1; \
799 if (*s2 == 0) return 1; \
801 if (tolower(*(const UChar *)s1) \
802 < tolower(*(const UChar*)s2)) return -1; \
803 if (tolower(*(const UChar *)s1) \
804 > tolower(*(const UChar *)s2)) return 1; \
806 s1++; s2++; n++; \
810 #if defined(VGO_linux)
811 # if !defined(VGPV_arm_linux_android) \
812 && !defined(VGPV_x86_linux_android) \
813 && !defined(VGPV_mips32_linux_android) \
814 && !defined(VGPV_arm64_linux_android)
815 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
816 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
817 # endif
819 #elif defined(VGO_freebsd)
820 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
821 STRNCASECMP(VG_Z_LD_ELF_SO_1, strncasecmp)
822 STRNCASECMP(VG_Z_LD_ELF32_SO_1, strncasecmp)
824 #elif defined(VGO_darwin)
825 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
826 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
828 #elif defined(VGO_solaris)
829 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
831 #endif
834 /*---------------------- strcasecmp_l ----------------------*/
836 #define STRCASECMP_L(soname, fnname) \
837 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
838 ( const char* s1, const char* s2, void* locale ); \
839 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
840 ( const char* s1, const char* s2, void* locale ) \
842 extern int tolower_l(int, void*) __attribute__((weak)); \
843 register UChar c1; \
844 register UChar c2; \
845 while (True) { \
846 c1 = tolower_l(*(const UChar *)s1, locale); \
847 c2 = tolower_l(*(const UChar *)s2, locale); \
848 if (c1 != c2) break; \
849 if (c1 == 0) break; \
850 s1++; s2++; \
852 if ((UChar)c1 < (UChar)c2) return -1; \
853 if ((UChar)c1 > (UChar)c2) return 1; \
854 return 0; \
857 #if defined(VGO_linux)
858 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
859 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
860 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
862 #elif defined(VGO_freebsd)
863 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
865 #elif defined(VGO_darwin)
866 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
868 #elif defined(VGO_solaris)
870 #endif
873 /*---------------------- strncasecmp_l ----------------------*/
875 #define STRNCASECMP_L(soname, fnname) \
876 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
877 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
878 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
879 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
881 extern int tolower_l(int, void*) __attribute__((weak)); \
882 SizeT n = 0; \
883 while (True) { \
884 if (n >= nmax) return 0; \
885 if (*s1 == 0 && *s2 == 0) return 0; \
886 if (*s1 == 0) return -1; \
887 if (*s2 == 0) return 1; \
889 if (tolower_l(*(const UChar *)s1, locale) \
890 < tolower_l(*(const UChar *)s2, locale)) return -1; \
891 if (tolower_l(*(const UChar *)s1, locale) \
892 > tolower_l(*(const UChar *)s2, locale)) return 1; \
894 s1++; s2++; n++; \
898 #if defined(VGO_linux)
899 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
900 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
901 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
903 #elif defined(VGO_freebsd)
904 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
906 #elif defined(VGO_darwin)
907 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
908 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
910 #elif defined(VGO_solaris)
912 #endif
915 /*---------------------- strcmp ----------------------*/
917 #define STRCMP(soname, fnname) \
918 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
919 ( const char* s1, const char* s2 ); \
920 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
921 ( const char* s1, const char* s2 ) \
923 register UChar c1; \
924 register UChar c2; \
925 while (True) { \
926 c1 = *(const UChar *)s1; \
927 c2 = *(const UChar *)s2; \
928 if (c1 != c2) break; \
929 if (c1 == 0) break; \
930 s1++; s2++; \
932 if ((UChar)c1 < (UChar)c2) return -1; \
933 if ((UChar)c1 > (UChar)c2) return 1; \
934 return 0; \
937 #if defined(VGO_linux)
938 STRCMP(VG_Z_LIBC_SONAME, strcmp)
939 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
940 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
941 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
942 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
943 STRCMP(VG_Z_LD64_SO_1, strcmp)
944 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
945 || defined(VGPV_mips32_linux_android)
946 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
947 # endif
949 #elif defined(VGO_freebsd)
950 STRCMP(VG_Z_LIBC_SONAME, strcmp)
951 STRCMP(VG_Z_LD_ELF_SO_1, strcmp)
952 STRCMP(VG_Z_LD_ELF32_SO_1, strcmp)
954 #elif defined(VGO_darwin)
955 STRCMP(VG_Z_LIBC_SONAME, strcmp)
956 # if DARWIN_VERS >= DARWIN_10_9
957 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
958 # endif
960 #elif defined(VGO_solaris)
961 STRCMP(VG_Z_LIBC_SONAME, strcmp)
962 STRCMP(VG_Z_LD_SO_1, strcmp)
964 #endif
967 /*---------------------- memchr ----------------------*/
969 #define MEMCHR(soname, fnname) \
970 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
971 (const void *s, int c, SizeT n); \
972 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
973 (const void *s, int c, SizeT n) \
975 SizeT i; \
976 UChar c0 = (UChar)c; \
977 const UChar* p = s; \
978 for (i = 0; i < n; i++) \
979 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
980 return NULL; \
983 #if defined(VGO_linux)
984 MEMCHR(VG_Z_LIBC_SONAME, memchr)
985 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
987 #elif defined(VGO_freebsd)
988 MEMCHR(VG_Z_LIBC_SONAME, memchr)
990 #elif defined(VGO_darwin)
991 # if DARWIN_VERS == DARWIN_10_9
992 MEMCHR(VG_Z_DYLD, memchr)
993 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
994 # endif
995 # if DARWIN_VERS >= DARWIN_10_10
996 MEMCHR(VG_Z_DYLD, memchr)
997 /* _platform_memchr$VARIANT$Generic */
998 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
999 /* _platform_memchr$VARIANT$Haswell */
1000 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
1001 # endif
1002 # if DARWIN_VERS >= DARWIN_10_12
1003 /* _platform_memchr$VARIANT$Base */
1004 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Base)
1005 #endif
1007 #elif defined(VGO_solaris)
1008 MEMCHR(VG_Z_LIBC_SONAME, memchr)
1010 #endif
1013 /*---------------------- memrchr ----------------------*/
1015 #define MEMRCHR(soname, fnname) \
1016 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1017 (const void *s, int c, SizeT n); \
1018 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
1019 (const void *s, int c, SizeT n) \
1021 SizeT i; \
1022 UChar c0 = (UChar)c; \
1023 const UChar* p = s; \
1024 for (i = 0; i < n; i++) \
1025 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
1026 return NULL; \
1029 #if defined(VGO_linux)
1030 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1032 #elif defined(VGO_freebsd)
1033 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1035 #elif defined(VGO_darwin)
1036 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
1037 //MEMRCHR(VG_Z_DYLD, memrchr)
1039 #elif defined(VGO_solaris)
1041 #endif
1044 /*---------------------- memcpy ----------------------*/
1046 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
1047 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1048 ( void *dst, const void *src, SizeT len ); \
1049 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
1050 ( void *dst, const void *src, SizeT len ) \
1052 RECORD_COPY(len); \
1053 if (do_ol_check && is_overlap(dst, src, len, len)) \
1054 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
1056 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
1057 const Addr WM = WS - 1; /* 7 or 3 */ \
1059 if (len > 0) { \
1060 if (dst < src || !is_overlap(dst, src, len, len)) { \
1062 /* Copying backwards. */ \
1063 SizeT n = len; \
1064 Addr d = (Addr)dst; \
1065 Addr s = (Addr)src; \
1067 if (((s^d) & WM) == 0) { \
1068 /* s and d have same UWord alignment. */ \
1069 /* Pull up to a UWord boundary. */ \
1070 while ((s & WM) != 0 && n >= 1) \
1071 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1072 /* Copy UWords. */ \
1073 while (n >= WS * 4) \
1074 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; \
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 while (n >= WS) \
1079 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
1080 if (n == 0) \
1081 return dst; \
1083 if (((s|d) & 1) == 0) { \
1084 /* Both are 16-aligned; copy what we can thusly. */ \
1085 while (n >= 2) \
1086 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
1088 /* Copy leftovers, or everything if misaligned. */ \
1089 while (n >= 1) \
1090 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
1092 } else if (dst > src) { \
1094 SizeT n = len; \
1095 Addr d = ((Addr)dst) + n; \
1096 Addr s = ((Addr)src) + n; \
1098 /* Copying forwards. */ \
1099 if (((s^d) & WM) == 0) { \
1100 /* s and d have same UWord alignment. */ \
1101 /* Back down to a UWord boundary. */ \
1102 while ((s & WM) != 0 && n >= 1) \
1103 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1104 /* Copy UWords. */ \
1105 while (n >= WS * 4) \
1106 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; \
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 while (n >= WS) \
1111 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
1112 if (n == 0) \
1113 return dst; \
1115 if (((s|d) & 1) == 0) { \
1116 /* Both are 16-aligned; copy what we can thusly. */ \
1117 while (n >= 2) \
1118 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1120 /* Copy leftovers, or everything if misaligned. */ \
1121 while (n >= 1) \
1122 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1127 return dst; \
1130 #define MEMMOVE(soname, fnname) \
1131 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1133 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1134 why we disable the overlap check on x86_64. */
1135 #if defined(VGP_amd64_linux)
1136 #define MEMCPY(soname, fnname) \
1137 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 0)
1138 #else
1139 #define MEMCPY(soname, fnname) \
1140 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1141 #endif
1143 #if defined(VGO_linux)
1144 /* For older memcpy we have to use memmove-like semantics and skip
1145 the overlap check; sigh; see #275284. */
1146 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1147 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1148 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1149 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1150 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1151 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_avx_unaligned_erms)
1152 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1153 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1154 /* icc9 blats these around all over the place. Not only in the main
1155 executable but various .so's. They are highly tuned and read
1156 memory beyond the source boundary (although work correctly and
1157 never go across page boundaries), so give errors when run
1158 natively, at least for misaligned source arg. Just intercepting
1159 in the exe only until we understand more about the problem. See
1160 http://bugs.kde.org/show_bug.cgi?id=139776
1162 MEMCPY(NONE, ZuintelZufastZumemcpy)
1164 #elif defined(VGO_freebsd)
1165 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1166 MEMCPY(VG_Z_LD_ELF_SO_1, memcpy)
1167 MEMCPY(VG_Z_LD_ELF32_SO_1, memcpy)
1169 #elif defined(VGO_darwin)
1170 # if DARWIN_VERS <= DARWIN_10_6
1171 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1172 # endif
1173 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1174 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1176 #elif defined(VGO_solaris)
1177 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1178 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
1179 MEMCPY(VG_Z_LD_SO_1, memcpy)
1181 #endif
1184 /*---------------------- memcmp ----------------------*/
1186 #define MEMCMP(soname, fnname) \
1187 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1188 ( const void *s1V, const void *s2V, SizeT n ); \
1189 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1190 ( const void *s1V, const void *s2V, SizeT n ) \
1192 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1193 const SizeT WM = WS - 1; /* 7 or 3 */ \
1194 Addr s1A = (Addr)s1V; \
1195 Addr s2A = (Addr)s2V; \
1197 if (((s1A | s2A) & WM) == 0) { \
1198 /* Both areas are word aligned. Skip over the */ \
1199 /* equal prefix as fast as possible. */ \
1200 while (n >= WS) { \
1201 UWord w1 = *(UWord*)s1A; \
1202 UWord w2 = *(UWord*)s2A; \
1203 if (w1 != w2) break; \
1204 s1A += WS; \
1205 s2A += WS; \
1206 n -= WS; \
1210 const UChar* s1 = (const UChar*) s1A; \
1211 const UChar* s2 = (const UChar*) s2A; \
1213 while (n != 0) { \
1214 UChar a0 = s1[0]; \
1215 UChar b0 = s2[0]; \
1216 s1 += 1; \
1217 s2 += 1; \
1218 int res = ((int)a0) - ((int)b0); \
1219 if (res != 0) \
1220 return res; \
1221 n -= 1; \
1223 return 0; \
1226 #if defined(VGO_linux)
1227 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1228 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1229 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1230 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1231 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1232 MEMCMP(VG_Z_LD_SO_1, bcmp)
1234 #elif defined(VGO_freebsd)
1235 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1236 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1237 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_memcmp)
1238 MEMCMP(VG_Z_LIBC_SONAME, timingsafe_bcmp)
1240 #elif defined(VGO_darwin)
1241 # if DARWIN_VERS >= DARWIN_10_9
1242 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1243 # endif
1245 #elif defined(VGO_solaris)
1246 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1247 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1248 MEMCMP(VG_Z_LD_SO_1, memcmp)
1250 #endif
1253 /*---------------------- stpcpy ----------------------*/
1255 /* Copy SRC to DEST, returning the address of the terminating '\0' in
1256 DEST. (minor variant of strcpy) */
1257 #define STPCPY(soname, fnname) \
1258 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1259 ( char* dst, const char* src ); \
1260 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1261 ( char* dst, const char* src ) \
1263 const HChar* src_orig = src; \
1264 HChar* dst_orig = dst; \
1266 while (*src) *dst++ = *src++; \
1267 *dst = 0; \
1269 /* This checks for overlap after copying, unavoidable without */ \
1270 /* pre-counting length... should be ok */ \
1271 SizeT srclen = (Addr)src-(Addr)src_orig+1; \
1272 RECORD_COPY(srclen); \
1273 if (is_overlap(dst_orig, \
1274 src_orig, \
1275 (Addr)dst-(Addr)dst_orig+1, \
1276 srclen)) \
1277 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1279 return dst; \
1282 #if defined(VGO_linux)
1283 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1284 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1285 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1286 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1287 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1288 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1289 STPCPY(VG_Z_LD_LINUX_AARCH64_SO_1,stpcpy)
1291 #elif defined(VGO_freebsd)
1292 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1293 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1294 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1296 #elif defined(VGO_freebsd)
1297 STPCPY(VG_Z_LD_ELF_SO_1, stpcpy)
1298 STPCPY(VG_Z_LD_ELF32_SO_1, stpcpy)
1299 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1301 #elif defined(VGO_darwin)
1302 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1303 //STPCPY(VG_Z_DYLD, stpcpy)
1305 #elif defined(VGO_solaris)
1306 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1308 #endif
1311 /*---------------------- stpncpy ----------------------*/
1313 #define STPNCPY(soname, fnname) \
1314 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1315 ( char* dst, const char* src, SizeT n ); \
1316 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1317 ( char* dst, const char* src, SizeT n ) \
1319 const HChar* src_orig = src; \
1320 HChar* dst_str = dst; \
1321 SizeT m = 0; \
1323 while (m < n && *src) { m++; *dst++ = *src++; } \
1324 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1325 /* but only m+1 bytes of src if terminator was found */ \
1326 SizeT srclen = (m < n) ? m+1 : n; \
1327 RECORD_COPY(srclen); \
1328 if (is_overlap(dst_str, src_orig, n, srclen)) \
1329 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1330 dst_str = dst; \
1331 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1333 return dst_str; \
1336 #if defined(VGO_linux) || defined(VGO_freebsd)
1337 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1338 #endif
1341 /*---------------------- memset ----------------------*/
1343 #define MEMSET(soname, fnname) \
1344 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1345 (void *s, Int c, SizeT n); \
1346 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
1347 (void *s, Int c, SizeT n) \
1349 if (sizeof(void*) == 8) { \
1350 Addr a = (Addr)s; \
1351 ULong c8 = (c & 0xFF); \
1352 c8 = (c8 << 8) | c8; \
1353 c8 = (c8 << 16) | c8; \
1354 c8 = (c8 << 32) | c8; \
1355 while ((a & 7) != 0 && n >= 1) \
1356 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1357 while (n >= 32) \
1358 { *(ULong*)a = c8; a += 8; n -= 8; \
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 while (n >= 8) \
1363 { *(ULong*)a = c8; a += 8; n -= 8; } \
1364 while (n >= 1) \
1365 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1366 return s; \
1367 } else { \
1368 Addr a = (Addr)s; \
1369 UInt c4 = (c & 0xFF); \
1370 c4 = (c4 << 8) | c4; \
1371 c4 = (c4 << 16) | c4; \
1372 while ((a & 3) != 0 && n >= 1) \
1373 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1374 while (n >= 16) \
1375 { *(UInt*)a = c4; a += 4; n -= 4; \
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 while (n >= 4) \
1380 { *(UInt*)a = c4; a += 4; n -= 4; } \
1381 while (n >= 1) \
1382 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1383 return s; \
1387 #if defined(VGO_linux)
1388 MEMSET(VG_Z_LIBC_SONAME, memset)
1390 #elif defined(VGO_freebsd)
1391 MEMSET(VG_Z_LIBC_SONAME, memset)
1392 MEMSET(VG_Z_LD_ELF_SO_1, memset)
1393 MEMSET(VG_Z_LD_ELF32_SO_1, memset)
1395 #elif defined(VGO_darwin)
1396 //MEMSET(VG_Z_LIBC_SONAME, memset)
1397 //MEMSET(VG_Z_DYLD, memset)
1398 MEMSET(VG_Z_LIBC_SONAME, memset)
1400 #elif defined(VGO_solaris)
1401 MEMSET(VG_Z_LIBC_SONAME, memset)
1402 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
1404 #endif
1407 /*---------------------- memmove ----------------------*/
1409 /* memmove -- use the MEMMOVE defn above. */
1411 #if defined(VGO_linux)
1412 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1413 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1414 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1415 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1416 to call memcpy. */
1417 MEMMOVE(VG_Z_LD64_SO_1, memmove)
1419 #elif defined(VGO_freebsd)
1420 MEMMOVE(VG_Z_LD_ELF_SO_1, memmove)
1421 MEMMOVE(VG_Z_LD_ELF32_SO_1, memmove)
1422 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1424 #elif defined(VGO_darwin)
1425 # if DARWIN_VERS <= DARWIN_10_6
1426 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1427 # endif
1428 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1429 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1430 # if DARWIN_VERS >= DARWIN_10_9
1431 /* _platform_memmove$VARIANT$Ivybridge */
1432 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1433 # endif
1435 #elif defined(VGO_solaris)
1436 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1437 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
1438 MEMMOVE(VG_Z_LD_SO_1, memmove)
1440 #endif
1443 /*---------------------- bcopy ----------------------*/
1445 #define BCOPY(soname, fnname) \
1446 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1447 (const void *srcV, void *dstV, SizeT n); \
1448 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1449 (const void *srcV, void *dstV, SizeT n) \
1451 RECORD_COPY(n); \
1452 SizeT i; \
1453 HChar* dst = dstV; \
1454 const HChar* src = srcV; \
1455 if (dst < src) { \
1456 for (i = 0; i < n; i++) \
1457 dst[i] = src[i]; \
1459 else \
1460 if (dst > src) { \
1461 for (i = 0; i < n; i++) \
1462 dst[n-i-1] = src[n-i-1]; \
1466 #if defined(VGO_linux)
1467 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1469 #elif defined(VGO_freebsd)
1470 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1471 BCOPY(VG_Z_LD_ELF_SO_1, bcopy)
1472 BCOPY(VG_Z_LD_ELF32_SO_1, bcopy)
1474 #elif defined(VGO_darwin)
1475 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1476 //BCOPY(VG_Z_DYLD, bcopy)
1478 #elif defined(VGO_darwin)
1479 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1481 #endif
1484 /*-------------------- memmove_chk --------------------*/
1486 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1487 There is no specific part of glibc that this is copied from. */
1488 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1489 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1490 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1491 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1492 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1494 RECORD_COPY(n); \
1495 SizeT i; \
1496 HChar* dst = dstV; \
1497 const HChar* src = srcV; \
1498 if (destlen < n) \
1499 goto badness; \
1500 if (dst < src) { \
1501 for (i = 0; i < n; i++) \
1502 dst[i] = src[i]; \
1504 else \
1505 if (dst > src) { \
1506 for (i = 0; i < n; i++) \
1507 dst[n-i-1] = src[n-i-1]; \
1509 return dst; \
1510 badness: \
1511 VALGRIND_PRINTF_BACKTRACE( \
1512 "*** memmove_chk: buffer overflow detected ***: " \
1513 "program terminated\n"); \
1514 my_exit(1); \
1515 /*NOTREACHED*/ \
1516 return NULL; \
1519 #if defined(VGO_linux)
1520 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1522 #elif defined(VGO_darwin)
1524 #elif defined(VGO_solaris)
1526 #endif
1529 /*-------------------- strchrnul --------------------*/
1531 /* Find the first occurrence of C in S or the final NUL byte. */
1532 #define GLIBC232_STRCHRNUL(soname, fnname) \
1533 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1534 (const char* s, int c_in); \
1535 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1536 (const char* s, int c_in) \
1538 HChar c = (HChar) c_in; \
1539 const HChar* char_ptr = s; \
1540 while (1) { \
1541 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1542 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
1543 char_ptr++; \
1547 #if defined(VGO_linux)
1548 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1550 #elif defined(VGO_freebsd)
1551 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1553 #elif defined(VGO_darwin)
1555 #elif defined(VGO_solaris)
1557 #endif
1560 /*---------------------- rawmemchr ----------------------*/
1562 /* Find the first occurrence of C in S. */
1563 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1564 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1565 (const void* s, int c_in); \
1566 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1567 (const void* s, int c_in) \
1569 UChar c = (UChar) c_in; \
1570 const UChar* char_ptr = s; \
1571 while (1) { \
1572 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
1573 char_ptr++; \
1577 #if defined (VGO_linux)
1578 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1579 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1581 #elif defined(VGO_darwin)
1583 #elif defined(VGO_solaris)
1585 #endif
1588 /*---------------------- strcpy_chk ----------------------*/
1590 /* glibc variant of strcpy that checks the dest is big enough.
1591 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1592 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1593 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1594 (char* dst, const char* src, SizeT len); \
1595 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1596 (char* dst, const char* src, SizeT len) \
1598 FOR_COPY(const HChar* src_orig = src); \
1599 HChar* ret = dst; \
1600 if (! len) \
1601 goto badness; \
1602 while ((*dst++ = *src++) != '\0') \
1603 if (--len == 0) \
1604 goto badness; \
1605 RECORD_COPY((Addr)src-(Addr)src_orig); \
1606 return ret; \
1607 badness: \
1608 VALGRIND_PRINTF_BACKTRACE( \
1609 "*** strcpy_chk: buffer overflow detected ***: " \
1610 "program terminated\n"); \
1611 my_exit(1); \
1612 /*NOTREACHED*/ \
1613 return NULL; \
1616 #if defined(VGO_linux)
1617 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1619 #elif defined(VGO_darwin)
1621 #elif defined(VGO_solaris)
1623 #endif
1626 /*---------------------- stpcpy_chk ----------------------*/
1628 /* glibc variant of stpcpy that checks the dest is big enough.
1629 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1630 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1631 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1632 (char* dst, const char* src, SizeT len); \
1633 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1634 (char* dst, const char* src, SizeT len) \
1636 FOR_COPY(const HChar* src_orig = src); \
1637 if (! len) \
1638 goto badness; \
1639 while ((*dst++ = *src++) != '\0') \
1640 if (--len == 0) \
1641 goto badness; \
1642 RECORD_COPY((Addr)src-(Addr)src_orig); \
1643 return dst - 1; \
1644 badness: \
1645 VALGRIND_PRINTF_BACKTRACE( \
1646 "*** stpcpy_chk: buffer overflow detected ***: " \
1647 "program terminated\n"); \
1648 my_exit(1); \
1649 /*NOTREACHED*/ \
1650 return NULL; \
1653 #if defined(VGO_linux)
1654 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1656 #elif defined(VGO_darwin)
1658 #elif defined(VGO_solaris)
1660 #endif
1663 /*---------------------- mempcpy ----------------------*/
1665 /* mempcpy */
1666 #define GLIBC25_MEMPCPY(soname, fnname) \
1667 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1668 ( void *dst, const void *src, SizeT len ); \
1669 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1670 ( void *dst, const void *src, SizeT len ) \
1672 RECORD_COPY(len); \
1673 SizeT len_saved = len; \
1675 if (len == 0) \
1676 return dst; \
1678 if (is_overlap(dst, src, len, len)) \
1679 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1681 if ( dst > src ) { \
1682 register HChar *d = (char *)dst + len - 1; \
1683 register const HChar *s = (const char *)src + len - 1; \
1684 while ( len-- ) { \
1685 *d-- = *s--; \
1687 } else if ( dst < src ) { \
1688 register HChar *d = dst; \
1689 register const HChar *s = src; \
1690 while ( len-- ) { \
1691 *d++ = *s++; \
1694 return (void*)( ((char*)dst) + len_saved ); \
1697 #if defined(VGO_linux)
1698 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1699 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
1700 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1701 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1702 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
1704 #elif defined(VGO_freebsd)
1705 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1706 #elif defined(VGO_darwin)
1707 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1709 #elif defined(VGO_solaris)
1711 #endif
1714 /*-------------------- memcpy_chk --------------------*/
1716 /* See https://bugs.kde.org/show_bug.cgi?id=402833
1717 why we disable the overlap check on x86_64. */
1718 #if defined(VGP_amd64_linux)
1719 #define CHECK_OVERLAP 0
1720 #else
1721 #define CHECK_OVERLAP 1
1722 #endif
1724 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1725 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1726 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1727 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1728 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1730 register HChar *d; \
1731 register const HChar *s; \
1732 if (dstlen < len) \
1733 goto badness; \
1734 RECORD_COPY(len); \
1735 if (len == 0) \
1736 return dst; \
1737 if (CHECK_OVERLAP && is_overlap(dst, src, len, len)) \
1738 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1739 if ( dst > src ) { \
1740 d = (HChar *)dst + len - 1; \
1741 s = (const HChar *)src + len - 1; \
1742 while ( len-- ) { \
1743 *d-- = *s--; \
1745 } else if ( dst < src ) { \
1746 d = (HChar *)dst; \
1747 s = (const HChar *)src; \
1748 while ( len-- ) { \
1749 *d++ = *s++; \
1752 return dst; \
1753 badness: \
1754 VALGRIND_PRINTF_BACKTRACE( \
1755 "*** memcpy_chk: buffer overflow detected ***: " \
1756 "program terminated\n"); \
1757 my_exit(1); \
1758 /*NOTREACHED*/ \
1759 return NULL; \
1762 #if defined(VGO_linux)
1763 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1765 #elif defined(VGO_darwin)
1767 #elif defined(VGO_solaris)
1769 #endif
1772 /*---------------------- strstr ----------------------*/
1774 #define STRSTR(soname, fnname) \
1775 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1776 (const char* haystack, const char* needle); \
1777 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1778 (const char* haystack, const char* needle) \
1780 const HChar* h = haystack; \
1781 const HChar* n = needle; \
1783 /* find the length of n, not including terminating zero */ \
1784 UWord nlen = 0; \
1785 while (n[nlen]) nlen++; \
1787 /* if n is the empty string, match immediately. */ \
1788 if (nlen == 0) return CONST_CAST(HChar *,h); \
1790 /* assert(nlen >= 1); */ \
1791 HChar n0 = n[0]; \
1793 while (1) { \
1794 const HChar hh = *h; \
1795 if (hh == 0) return NULL; \
1796 if (hh != n0) { h++; continue; } \
1798 UWord i; \
1799 for (i = 0; i < nlen; i++) { \
1800 if (n[i] != h[i]) \
1801 break; \
1803 /* assert(i >= 0 && i <= nlen); */ \
1804 if (i == nlen) \
1805 return CONST_CAST(HChar *,h); \
1807 h++; \
1811 #if defined(VGO_linux)
1812 STRSTR(VG_Z_LIBC_SONAME, strstr)
1813 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1814 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1816 #elif defined(VGO_freebsd)
1817 STRSTR(VG_Z_LIBC_SONAME, strstr)
1819 #elif defined(VGO_darwin)
1821 #elif defined(VGO_solaris)
1822 STRSTR(VG_Z_LIBC_SONAME, strstr)
1824 #endif
1826 /*---------------------- memmem ----------------------*/
1828 #define MEMMEM(soname, fnname) \
1829 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1830 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \
1831 void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \
1832 (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \
1834 const HChar* h = haystack; \
1835 const HChar* n = needle; \
1837 /* If the needle is the empty string, match immediately. */ \
1838 if (nlen == 0) return CONST_CAST(void *,h); \
1840 HChar n0 = n[0]; \
1842 for (; hlen >= nlen; hlen--, h++) { \
1843 if (h[0] != n0) continue; \
1845 UWord i; \
1846 for (i = 1; i < nlen; i++) { \
1847 if (n[i] != h[i]) \
1848 break; \
1850 if (i == nlen) \
1851 return CONST_CAST(HChar *,h); \
1854 return NULL; \
1857 #if defined(VGP_s390x_linux)
1858 MEMMEM(VG_Z_LIBC_SONAME, memmem)
1859 #endif
1862 /*---------------------- strpbrk ----------------------*/
1864 #define STRPBRK(soname, fnname) \
1865 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1866 (const char* sV, const char* acceptV); \
1867 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1868 (const char* sV, const char* acceptV) \
1870 const HChar* s = sV; \
1871 const HChar* accept = acceptV; \
1873 /* find the length of 'accept', not including terminating zero */ \
1874 UWord nacc = 0; \
1875 while (accept[nacc]) nacc++; \
1877 /* if n is the empty string, fail immediately. */ \
1878 if (nacc == 0) return NULL; \
1880 /* assert(nacc >= 1); */ \
1881 while (1) { \
1882 UWord i; \
1883 HChar sc = *s; \
1884 if (sc == 0) \
1885 break; \
1886 for (i = 0; i < nacc; i++) { \
1887 if (sc == accept[i]) \
1888 return CONST_CAST(HChar *,s); \
1890 s++; \
1893 return NULL; \
1896 #if defined(VGO_linux)
1897 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1899 #elif defined(VGO_freebsd)
1900 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1902 #elif defined(VGO_darwin)
1904 #elif defined(VGO_solaris)
1905 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1907 #endif
1910 /*---------------------- strcspn ----------------------*/
1912 #define STRCSPN(soname, fnname) \
1913 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1914 (const char* sV, const char* rejectV); \
1915 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1916 (const char* sV, const char* rejectV) \
1918 const HChar* s = sV; \
1919 const HChar* reject = rejectV; \
1921 /* find the length of 'reject', not including terminating zero */ \
1922 UWord nrej = 0; \
1923 while (reject[nrej]) nrej++; \
1925 UWord len = 0; \
1926 while (1) { \
1927 UWord i; \
1928 HChar sc = *s; \
1929 if (sc == 0) \
1930 break; \
1931 for (i = 0; i < nrej; i++) { \
1932 if (sc == reject[i]) \
1933 break; \
1935 /* assert(i >= 0 && i <= nrej); */ \
1936 if (i < nrej) \
1937 break; \
1938 s++; \
1939 len++; \
1942 return len; \
1945 #if defined(VGO_linux)
1946 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1947 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
1949 #elif defined(VGO_freebsd)
1950 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1952 #elif defined(VGO_darwin)
1954 #elif defined(VGO_solaris)
1955 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1957 #endif
1960 /*---------------------- strspn ----------------------*/
1962 #define STRSPN(soname, fnname) \
1963 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1964 (const char* sV, const char* acceptV); \
1965 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1966 (const char* sV, const char* acceptV) \
1968 const UChar* s = (const UChar *)sV; \
1969 const UChar* accept = (const UChar *)acceptV; \
1971 /* find the length of 'accept', not including terminating zero */ \
1972 UWord nacc = 0; \
1973 while (accept[nacc]) nacc++; \
1974 if (nacc == 0) return 0; \
1976 UWord len = 0; \
1977 while (1) { \
1978 UWord i; \
1979 UChar sc = *s; \
1980 if (sc == 0) \
1981 break; \
1982 for (i = 0; i < nacc; i++) { \
1983 if (sc == accept[i]) \
1984 break; \
1986 /* assert(i >= 0 && i <= nacc); */ \
1987 if (i == nacc) \
1988 break; \
1989 s++; \
1990 len++; \
1993 return len; \
1996 #if defined(VGO_linux)
1997 STRSPN(VG_Z_LIBC_SONAME, strspn)
1999 #elif defined(VGO_freebsd)
2000 STRSPN(VG_Z_LIBC_SONAME, strspn)
2002 #elif defined(VGO_darwin)
2004 #elif defined(VGO_solaris)
2005 STRSPN(VG_Z_LIBC_SONAME, strspn)
2007 #endif
2010 /*---------------------- strcasestr ----------------------*/
2012 #define STRCASESTR(soname, fnname) \
2013 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2014 (const char* haystack, const char* needle); \
2015 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
2016 (const char* haystack, const char* needle) \
2018 extern int tolower(int); \
2019 const HChar* h = haystack; \
2020 const HChar* n = needle; \
2022 /* find the length of n, not including terminating zero */ \
2023 UWord nlen = 0; \
2024 while (n[nlen]) nlen++; \
2026 /* if n is the empty string, match immediately. */ \
2027 if (nlen == 0) return CONST_CAST(HChar *,h); \
2029 /* assert(nlen >= 1); */ \
2030 UChar n0 = tolower(n[0]); \
2032 while (1) { \
2033 UChar hh = tolower(*h); \
2034 if (hh == 0) return NULL; \
2035 if (hh != n0) { h++; continue; } \
2037 UWord i; \
2038 for (i = 0; i < nlen; i++) { \
2039 if (tolower(n[i]) != tolower(h[i])) \
2040 break; \
2042 /* assert(i >= 0 && i <= nlen); */ \
2043 if (i == nlen) \
2044 return CONST_CAST(HChar *,h); \
2046 h++; \
2050 #if defined(VGO_linux)
2051 # if !defined(VGPV_arm_linux_android) \
2052 && !defined(VGPV_x86_linux_android) \
2053 && !defined(VGPV_mips32_linux_android) \
2054 && !defined(VGPV_arm64_linux_android)
2055 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2056 # endif
2058 #elif defined(VGO_freebsd)
2059 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2061 #elif defined(VGO_darwin)
2063 #elif defined(VGO_solaris)
2064 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
2066 #endif
2069 /*---------------------- wcslen ----------------------*/
2071 // This is a wchar_t equivalent to strlen. Unfortunately
2072 // we don't have wchar_t available here, but it looks like
2073 // a 32 bit int on Linux. I don't know if that is also
2074 // valid on MacOSX.
2076 #define WCSLEN(soname, fnname) \
2077 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2078 ( const Int* str ); \
2079 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
2080 ( const Int* str ) \
2082 SizeT i = 0; \
2083 while (str[i] != 0) i++; \
2084 return i; \
2087 #if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_solaris)
2088 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
2090 #endif
2092 /*---------------------- wcsnlen ----------------------*/
2094 #define WCSNLEN(soname, fnname) \
2095 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2096 ( const Int *s, SizeT n ); \
2097 SizeT VG_REPLACE_FUNCTION_EZU(20440,soname,fnname) \
2098 ( const Int *s, SizeT n ) \
2100 SizeT i = 0; \
2101 const Int* p = s; \
2102 while (i < n && *p != 0) { \
2103 i++; \
2104 p++; \
2106 return i; \
2109 #if defined(VGO_linux) || defined(VGO_freebsd)
2110 WCSNLEN(VG_Z_LIBC_SONAME, wcsnlen)
2111 WCSNLEN(VG_Z_LIBC_SONAME, __GI_wcsnlen)
2112 #endif
2114 /*---------------------- wcscmp ----------------------*/
2116 // This is a wchar_t equivalent to strcmp. We don't
2117 // have wchar_t available here, but in the GNU C Library
2118 // wchar_t is always 32 bits wide and wcscmp uses signed
2119 // comparison, not unsigned as in strcmp function.
2121 #define WCSCMP(soname, fnname) \
2122 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2123 ( const Int* s1, const Int* s2 ); \
2124 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
2125 ( const Int* s1, const Int* s2 ) \
2127 register Int c1; \
2128 register Int c2; \
2129 while (True) { \
2130 c1 = *s1; \
2131 c2 = *s2; \
2132 if (c1 != c2) break; \
2133 if (c1 == 0) break; \
2134 s1++; s2++; \
2136 if (c1 < c2) return -1; \
2137 if (c1 > c2) return 1; \
2138 return 0; \
2141 #if defined(VGO_linux) || defined(VGO_freebsd)
2142 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
2143 #endif
2145 /*---------------------- wcsncmp ----------------------*/
2147 // This is a wchar_t equivalent to strncmp. We don't
2148 // have wchar_t available here, but in the GNU C Library
2149 // wchar_t is always 32 bits wide and wcsncmp uses signed
2150 // comparison, not unsigned as in strncmp function.
2152 #define WCSNCMP(soname, fnname) \
2153 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2154 ( const Int* s1, const Int* s2, SizeT nmax ); \
2155 int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
2156 ( const Int* s1, const Int* s2, SizeT nmax ) \
2158 SizeT n = 0; \
2159 while (True) { \
2160 if (n >= nmax) return 0; \
2161 if (*s1 == 0 && *s2 == 0) return 0; \
2162 if (*s1 == 0) return -1; \
2163 if (*s2 == 0) return 1; \
2165 if (*s1 < *s2) return -1; \
2166 if (*s1 > *s2) return 1; \
2168 s1++; s2++; n++; \
2171 #if defined(VGO_linux) || defined(VGO_freebsd)
2172 WCSNCMP(VG_Z_LIBC_SONAME, wcsncmp)
2173 #endif
2175 /*---------------------- wcscpy ----------------------*/
2177 // This is a wchar_t equivalent to strcpy. We don't
2178 // have wchar_t available here, but in the GNU C Library
2179 // wchar_t is always 32 bits wide.
2181 #define WCSCPY(soname, fnname) \
2182 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2183 ( Int* dst, const Int* src ); \
2184 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
2185 ( Int* dst, const Int* src ) \
2187 const Int* src_orig = src; \
2188 Int* dst_orig = dst; \
2190 while (*src) *dst++ = *src++; \
2191 *dst = 0; \
2193 /* This checks for overlap after copying, unavoidable without */ \
2194 /* pre-counting length... should be ok */ \
2195 /* +4 because sizeof(wchar_t) == 4 */ \
2196 SizeT srclen = (Addr)src-(Addr)src_orig+4; \
2197 RECORD_COPY(srclen); \
2198 if (is_overlap(dst_orig, \
2199 src_orig, \
2200 /* +4 because sizeof(wchar_t) == 4 */ \
2201 (Addr)dst-(Addr)dst_orig+4, \
2202 srclen)) \
2203 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
2205 return dst_orig; \
2208 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2209 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
2210 #endif
2213 /*---------------------- wcschr ----------------------*/
2215 // This is a wchar_t equivalent to strchr. We don't
2216 // have wchar_t available here, but in the GNU C Library
2217 // wchar_t is always 32 bits wide.
2219 #define WCSCHR(soname, fnname) \
2220 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
2221 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
2223 const Int* p = s; \
2224 while (True) { \
2225 if (*p == c) return CONST_CAST(Int *,p); \
2226 if (*p == 0) return NULL; \
2227 p++; \
2231 #if defined(VGO_linux) || defined(VGO_freebsd)
2232 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
2233 #endif
2234 /*---------------------- wcsrchr ----------------------*/
2236 // This is a wchar_t equivalent to strrchr. We don't
2237 // have wchar_t available here, but in the GNU C Library
2238 // wchar_t is always 32 bits wide.
2240 #define WCSRCHR(soname, fnname) \
2241 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
2242 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
2244 const Int* p = s; \
2245 const Int* last = NULL; \
2246 while (True) { \
2247 if (*p == c) last = p; \
2248 if (*p == 0) return CONST_CAST(Int *,last); \
2249 p++; \
2253 #if defined(VGO_linux) || defined(VGO_freebsd)
2254 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
2255 #endif
2257 /*---------------------- wmemchr ----------------------*/
2259 // This is a wchar_t equivalent to memchr. We don't
2260 // have wchar_t available here, but in the GNU C Library
2261 // wchar_t is always 32 bits wide.
2263 #define WMEMCHR(soname, fnname) \
2264 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2265 (const Int *s, Int c, SizeT n); \
2266 Int* VG_REPLACE_FUNCTION_EZU(20430,soname,fnname) \
2267 (const Int *s, Int c, SizeT n) \
2269 SizeT i; \
2270 const Int* p = s; \
2271 for (i = 0; i < n; i++) { \
2272 if (*p == c) return CONST_CAST(Int *,p); \
2273 p++; \
2275 return NULL; \
2278 #if defined(VGO_linux)
2279 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2280 WMEMCHR(VG_Z_LIBC_SONAME, __GI_wmemchr)
2281 #endif
2283 #if defined(VGO_freebsd)
2284 WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
2285 #endif
2287 /*---------------------- wmemcmp ----------------------*/
2289 #define WMEMCMP(soname, fnname) \
2290 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2291 ( const Int *b1, const Int *b2, SizeT n ); \
2292 int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
2293 ( const Int *b1, const Int *b2, SizeT n ) \
2295 for (SizeT i = 0U; i < n; ++i) { \
2296 if (b1[i] != b2[i]) \
2297 return b1[i] > b2[i] ? 1 : -1; \
2299 return 0; \
2302 #if defined(VGO_linux) || defined(VGO_freebsd)
2303 WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
2304 #endif
2306 /*---------------------- wcsncpy ----------------------*/
2308 // This is a wchar_t equivalent to strncpy. We don't
2309 // have wchar_t available here, but in the GNU C Library
2310 // wchar_t is always 32 bits wide.
2312 #define WCSNCPY(soname, fnname) \
2313 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2314 ( Int* dst, const Int* src, SizeT n ); \
2315 Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
2316 ( Int* dst, const Int* src, SizeT n ) \
2318 const Int* src_orig = src; \
2319 Int* dst_orig = dst; \
2320 SizeT m = 0; \
2322 while (m < n && *src) { \
2323 m++; \
2324 *dst++ = *src++; \
2327 /* This checks for overlap after copying, unavoidable without */ \
2328 /* pre-counting length... should be ok */ \
2329 /* +4 because sizeof(wchar_t) == 4 */ \
2330 SizeT srclen = ((m < n) ? m+1 : n)*4; \
2331 RECORD_COPY(srclen); \
2332 if (is_overlap(dst_orig, \
2333 src_orig, \
2334 n*4, \
2335 srclen)) \
2336 RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
2338 while (m++ < n) { \
2339 *dst++ = 0; \
2342 return dst_orig; \
2345 #if defined(VGO_linux) || defined(VGO_freebsd)
2346 WCSNCPY(VG_Z_LIBC_SONAME, wcsncpy)
2347 #endif
2349 /*------------------------------------------------------------*/
2350 /*--- Improve definedness checking of process environment ---*/
2351 /*------------------------------------------------------------*/
2353 #if defined(VGO_linux) || defined(VGO_freebsd)
2355 /* If these wind up getting generated via a macro, so that multiple
2356 versions of each function exist (as above), use the _EZU variants
2357 to assign equivalance class tags. */
2359 /*---------------------- putenv ----------------------*/
2361 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
2362 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
2364 OrigFn fn;
2365 Word result;
2366 const HChar* p = string;
2367 VALGRIND_GET_ORIG_FN(fn);
2368 /* Now by walking over the string we magically produce
2369 traces when hitting undefined memory. */
2370 if (p)
2371 while (*p++)
2372 __asm__ __volatile__("" ::: "memory");
2373 CALL_FN_W_W(result, fn, string);
2374 return result;
2378 /*---------------------- unsetenv ----------------------*/
2380 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2381 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2383 OrigFn fn;
2384 Word result;
2385 const HChar* p = name;
2386 VALGRIND_GET_ORIG_FN(fn);
2387 /* Now by walking over the string we magically produce
2388 traces when hitting undefined memory. */
2389 if (p)
2390 while (*p++)
2391 __asm__ __volatile__("" ::: "memory");
2392 CALL_FN_W_W(result, fn, name);
2393 return result;
2397 /*---------------------- setenv ----------------------*/
2399 /* setenv */
2400 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2401 (const char* name, const char* value, int overwrite);
2402 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2403 (const char* name, const char* value, int overwrite)
2405 OrigFn fn;
2406 Word result;
2407 const HChar* p;
2408 VALGRIND_GET_ORIG_FN(fn);
2409 /* Now by walking over the string we magically produce
2410 traces when hitting undefined memory. */
2411 if (name)
2412 for (p = name; *p; p++)
2413 __asm__ __volatile__("" ::: "memory");
2414 if (value)
2415 for (p = value; *p; p++)
2416 __asm__ __volatile__("" ::: "memory");
2417 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2418 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2419 return result;
2422 #endif /* defined(VGO_linux) */
2424 /*--------------------------------------------------------------------*/
2425 /*--- end ---*/
2426 /*--------------------------------------------------------------------*/