blob: 005b6795a1839aef7dd2b313e3d54bc34c96f27c [file] [log] [blame]
bart9c7779b2013-11-24 17:48:13 +00001
2/*--------------------------------------------------------------------*/
3/*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/
4/*--- simulated CPU. ---*/
philippef2a68aa2014-07-16 21:16:10 +00005/*--- vg_replace_strmem.c ---*/
bart9c7779b2013-11-24 17:48:13 +00006/*--------------------------------------------------------------------*/
7
8/*
9 This file is part of Valgrind.
10
sewardjb3a1e4b2015-08-21 11:32:26 +000011 Copyright (C) 2000-2015 Julian Seward
bart9c7779b2013-11-24 17:48:13 +000012 jseward@acm.org
13
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.
18
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.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#include "pub_tool_basics.h"
33#include "pub_tool_poolalloc.h"
34#include "pub_tool_hashtable.h"
35#include "pub_tool_redir.h"
36#include "pub_tool_tooliface.h"
37#include "pub_tool_clreq.h"
38
39/* ---------------------------------------------------------------------
40 We have our own versions of these functions for two reasons:
41 (a) it allows us to do overlap checking
42 (b) some of the normal versions are hyper-optimised, which fools
43 Memcheck and cause spurious value warnings. Our versions are
44 simpler.
45 (c) the glibc SSE-variants can read past the end of the input data
46 ranges. This can cause false-positive Memcheck / Helgrind / DRD
47 reports.
48
49 Note that overenthusiastic use of PLT bypassing by the glibc people also
50 means that we need to patch multiple versions of some of the functions to
51 our own implementations.
52
53 THEY RUN ON THE SIMD CPU!
54 ------------------------------------------------------------------ */
55
56/* Assignment of behavioural equivalence class tags: 2NNNP is intended
57 to be reserved for str/mem intercepts. Current usage:
58
59 20010 STRRCHR
60 20020 STRCHR
61 20030 STRCAT
62 20040 STRNCAT
63 20050 STRLCAT
64 20060 STRNLEN
65 20070 STRLEN
66 20080 STRCPY
67 20090 STRNCPY
68 20100 STRLCPY
69 20110 STRNCMP
70 20120 STRCASECMP
71 20130 STRNCASECMP
72 20140 STRCASECMP_L
73 20150 STRNCASECMP_L
74 20160 STRCMP
75 20170 MEMCHR
76
77 20180 MEMCPY if there's a conflict between memcpy and
78 20181 MEMMOVE memmove, prefer memmove
79
80 20190 MEMCMP
81 20200 STPCPY
82 20210 MEMSET
83 2022P unused (was previously MEMMOVE)
84 20230 BCOPY
85 20240 GLIBC25___MEMMOVE_CHK
86 20250 GLIBC232_STRCHRNUL
87 20260 GLIBC232_RAWMEMCHR
88 20270 GLIBC25___STRCPY_CHK
89 20280 GLIBC25___STPCPY_CHK
90 20290 GLIBC25_MEMPCPY
91 20300 GLIBC26___MEMCPY_CHK
92 20310 STRSTR
93 20320 STRPBRK
94 20330 STRCSPN
95 20340 STRSPN
96 20350 STRCASESTR
97 20360 MEMRCHR
98 20370 WCSLEN
99 20380 WCSCMP
100 20390 WCSCPY
101 20400 WCSCHR
102 20410 WCSRCHR
103 20420 STPNCPY
104*/
105
sewardj8eb8bab2015-07-21 14:44:28 +0000106#if defined(VGO_solaris)
107/*
108 Detour functions in the libc and the runtime linker. If a function isn't
109 much optimized (and no overlap checking is necessary) then redir the
110 function only in the libc. This way we can keep stacktraces in the tests
111 consistent.
112*/
113#endif
114
bart9c7779b2013-11-24 17:48:13 +0000115
116/* Figure out if [dst .. dst+dstlen-1] overlaps with
117 [src .. src+srclen-1].
118 We assume that the address ranges do not wrap around
119 (which is safe since on Linux addresses >= 0xC0000000
120 are not accessible and the program will segfault in this
121 circumstance, presumably).
122*/
123static inline
124Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
125{
126 Addr loS, hiS, loD, hiD;
127
128 if (dstlen == 0 || srclen == 0)
129 return False;
130
131 loS = (Addr)src;
132 loD = (Addr)dst;
133 hiS = loS + srclen - 1;
134 hiD = loD + dstlen - 1;
135
136 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
137 if (loS < loD) {
138 return !(hiS < loD);
139 }
140 else if (loD < loS) {
141 return !(hiD < loS);
142 }
143 else {
144 /* They start at same place. Since we know neither of them has
145 zero length, they must overlap. */
146 return True;
147 }
148}
149
150
151/* Call here to exit if we can't continue. On Android we can't call
152 _exit for some reason, so we have to blunt-instrument it. */
153__attribute__ ((__noreturn__))
154static inline void my_exit ( int x )
155{
dejanj9c6b05d2013-12-27 09:06:55 +0000156# if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
sewardj26ed4192014-11-04 17:44:21 +0000157 || defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000158 __asm__ __volatile__(".word 0xFFFFFFFF");
159 while (1) {}
160# elif defined(VGPV_x86_linux_android)
161 __asm__ __volatile__("ud2");
162 while (1) {}
163# else
164 extern __attribute__ ((__noreturn__)) void _exit(int status);
165 _exit(x);
166# endif
167}
168
169
170// This is a macro rather than a function because we don't want to have an
171// extra function in the stack trace.
172#ifndef RECORD_OVERLAP_ERROR
173#define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
174#endif
175#ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
176#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
177#endif
178
179
180/*---------------------- strrchr ----------------------*/
181
182#define STRRCHR(soname, fnname) \
183 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
184 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
185 { \
186 HChar ch = (HChar)c; \
187 const HChar* p = s; \
188 const HChar* last = NULL; \
189 while (True) { \
190 if (*p == ch) last = p; \
florian70a5de12014-10-22 12:53:16 +0000191 if (*p == 0) return CONST_CAST(HChar *,last); \
bart9c7779b2013-11-24 17:48:13 +0000192 p++; \
193 } \
194 }
195
196// Apparently rindex() is the same thing as strrchr()
197#if defined(VGO_linux)
198 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
199 STRRCHR(VG_Z_LIBC_SONAME, rindex)
200 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
201 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
202 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
203 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
204 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
dejanj9c6b05d2013-12-27 09:06:55 +0000205#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
206 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000207 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
208#endif
209
210#elif defined(VGO_darwin)
211 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
212 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
213 //STRRCHR(VG_Z_DYLD, strrchr)
214 //STRRCHR(VG_Z_DYLD, rindex)
215 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
rhyskidd9090d2f2015-07-08 13:46:57 +0000216# if DARWIN_VERS >= DARWIN_10_9
sewardjeb86dda2014-10-17 15:07:37 +0000217 STRRCHR(libsystemZucZddylib, strrchr)
218# endif
bart9c7779b2013-11-24 17:48:13 +0000219
sewardj8eb8bab2015-07-21 14:44:28 +0000220#elif defined(VGO_solaris)
221 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
222 STRRCHR(VG_Z_LIBC_SONAME, rindex)
223 STRRCHR(VG_Z_LD_SO_1, strrchr)
224
bart9c7779b2013-11-24 17:48:13 +0000225#endif
226
227
228/*---------------------- strchr ----------------------*/
229
230#define STRCHR(soname, fnname) \
231 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
232 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
233 { \
234 HChar ch = (HChar)c ; \
235 const HChar* p = s; \
236 while (True) { \
florian70a5de12014-10-22 12:53:16 +0000237 if (*p == ch) return CONST_CAST(HChar *,p); \
bart9c7779b2013-11-24 17:48:13 +0000238 if (*p == 0) return NULL; \
239 p++; \
240 } \
241 }
242
243// Apparently index() is the same thing as strchr()
244#if defined(VGO_linux)
245 STRCHR(VG_Z_LIBC_SONAME, strchr)
246 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
247 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
248 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
249 STRCHR(VG_Z_LIBC_SONAME, index)
250# if !defined(VGP_x86_linux)
251 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
252 STRCHR(VG_Z_LD_LINUX_SO_2, index)
253 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
254 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
255# endif
256
257#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000258 STRCHR(VG_Z_LIBC_SONAME, strchr)
sewardjc3e09f62014-06-21 09:40:19 +0000259# if DARWIN_VERS == DARWIN_10_9
260 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
261# endif
rhyskidd9090d2f2015-07-08 13:46:57 +0000262# if DARWIN_VERS >= DARWIN_10_10
rhyskidd99513232015-03-26 10:14:25 +0000263 /* _platform_strchr$VARIANT$Generic */
264 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
rhyskidde4fcda32015-08-29 07:42:40 +0000265 /* _platform_strchr$VARIANT$Haswell */
rhyskidd366cefb2015-05-14 13:03:08 +0000266 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
rhyskidd99513232015-03-26 10:14:25 +0000267# endif
sewardj8eb8bab2015-07-21 14:44:28 +0000268
269#elif defined(VGO_solaris)
270 STRCHR(VG_Z_LIBC_SONAME, strchr)
271 STRCHR(VG_Z_LIBC_SONAME, index)
272 STRCHR(VG_Z_LD_SO_1, strchr)
273
bart9c7779b2013-11-24 17:48:13 +0000274#endif
275
276
277/*---------------------- strcat ----------------------*/
278
279#define STRCAT(soname, fnname) \
280 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
281 ( char* dst, const char* src ); \
282 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
283 ( char* dst, const char* src ) \
284 { \
285 const HChar* src_orig = src; \
286 HChar* dst_orig = dst; \
287 while (*dst) dst++; \
288 while (*src) *dst++ = *src++; \
289 *dst = 0; \
290 \
291 /* This is a bit redundant, I think; any overlap and the strcat will */ \
292 /* go forever... or until a seg fault occurs. */ \
293 if (is_overlap(dst_orig, \
294 src_orig, \
295 (Addr)dst-(Addr)dst_orig+1, \
296 (Addr)src-(Addr)src_orig+1)) \
297 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
298 \
299 return dst_orig; \
300 }
301
302#if defined(VGO_linux)
303 STRCAT(VG_Z_LIBC_SONAME, strcat)
304 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
305
306#elif defined(VGO_darwin)
307 //STRCAT(VG_Z_LIBC_SONAME, strcat)
308
sewardj8eb8bab2015-07-21 14:44:28 +0000309#elif defined(VGO_solaris)
310 STRCAT(VG_Z_LIBC_SONAME, strcat)
311 STRCAT(VG_Z_LD_SO_1, strcat)
312
bart9c7779b2013-11-24 17:48:13 +0000313#endif
314
315
316/*---------------------- strncat ----------------------*/
317
318#define STRNCAT(soname, fnname) \
319 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
320 ( char* dst, const char* src, SizeT n ); \
321 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
322 ( char* dst, const char* src, SizeT n ) \
323 { \
324 const HChar* src_orig = src; \
325 HChar* dst_orig = dst; \
326 SizeT m = 0; \
327 \
328 while (*dst) dst++; \
329 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
330 *dst = 0; /* always add null */ \
331 \
332 /* This checks for overlap after copying, unavoidable without */ \
333 /* pre-counting lengths... should be ok */ \
334 if (is_overlap(dst_orig, \
335 src_orig, \
336 (Addr)dst-(Addr)dst_orig+1, \
337 (Addr)src-(Addr)src_orig+1)) \
338 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
339 \
340 return dst_orig; \
341 }
342
343#if defined(VGO_linux)
344 STRNCAT(VG_Z_LIBC_SONAME, strncat)
345
346#elif defined(VGO_darwin)
347 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
348 //STRNCAT(VG_Z_DYLD, strncat)
349
sewardj8eb8bab2015-07-21 14:44:28 +0000350#elif defined(VGO_solaris)
351 STRNCAT(VG_Z_LIBC_SONAME, strncat)
352
bart9c7779b2013-11-24 17:48:13 +0000353#endif
354
355
356/*---------------------- strlcat ----------------------*/
357
358/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
359 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
360 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
361 Truncation occurred if retval >= n.
362*/
363#define STRLCAT(soname, fnname) \
364 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
365 ( char* dst, const char* src, SizeT n ); \
366 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
367 ( char* dst, const char* src, SizeT n ) \
368 { \
369 const HChar* src_orig = src; \
370 HChar* dst_orig = dst; \
371 SizeT m = 0; \
372 \
373 while (m < n && *dst) { m++; dst++; } \
374 if (m < n) { \
375 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
376 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
377 *dst = 0; \
378 } else { \
379 /* No space to copy anything to dst. m == n */ \
380 } \
381 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
382 while (*src) { m++; src++; } \
383 /* This checks for overlap after copying, unavoidable without */ \
384 /* pre-counting lengths... should be ok */ \
385 if (is_overlap(dst_orig, \
386 src_orig, \
387 (Addr)dst-(Addr)dst_orig+1, \
388 (Addr)src-(Addr)src_orig+1)) \
389 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
390 \
391 return m; \
392 }
393
394#if defined(VGO_linux)
395
396#elif defined(VGO_darwin)
397 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
398 //STRLCAT(VG_Z_DYLD, strlcat)
399 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
400
sewardj8eb8bab2015-07-21 14:44:28 +0000401#elif defined(VGO_solaris)
402 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
403
bart9c7779b2013-11-24 17:48:13 +0000404#endif
405
406
407/*---------------------- strnlen ----------------------*/
408
409#define STRNLEN(soname, fnname) \
410 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
411 ( const char* str, SizeT n ); \
412 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
413 ( const char* str, SizeT n ) \
414 { \
415 SizeT i = 0; \
416 while (i < n && str[i] != 0) i++; \
417 return i; \
418 }
419
420#if defined(VGO_linux)
421 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
422 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
423
424#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000425# if DARWIN_VERS == DARWIN_10_9
426 STRNLEN(libsystemZucZddylib, strnlen)
427# endif
bart9c7779b2013-11-24 17:48:13 +0000428
sewardj8eb8bab2015-07-21 14:44:28 +0000429#elif defined(VGO_solaris)
430 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
431
bart9c7779b2013-11-24 17:48:13 +0000432#endif
433
434
435/*---------------------- strlen ----------------------*/
436
437// Note that this replacement often doesn't get used because gcc inlines
438// calls to strlen() with its own built-in version. This can be very
439// confusing if you aren't expecting it. Other small functions in
440// this file may also be inline by gcc.
441
442#define STRLEN(soname, fnname) \
443 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
444 ( const char* str ); \
445 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
446 ( const char* str ) \
447 { \
448 SizeT i = 0; \
449 while (str[i] != 0) i++; \
450 return i; \
451 }
452
453#if defined(VGO_linux)
454 STRLEN(VG_Z_LIBC_SONAME, strlen)
455 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
456 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
457 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
458 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
459 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
460 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
sewardj26ed4192014-11-04 17:44:21 +0000461# if defined(VGPV_arm_linux_android) \
462 || defined(VGPV_x86_linux_android) \
dejanj9c6b05d2013-12-27 09:06:55 +0000463 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000464 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
465# endif
466
467#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000468 STRLEN(VG_Z_LIBC_SONAME, strlen)
rhyskidd9090d2f2015-07-08 13:46:57 +0000469# if DARWIN_VERS >= DARWIN_10_9
sewardjc3e09f62014-06-21 09:40:19 +0000470 STRLEN(libsystemZucZddylib, strlen)
471# endif
sewardj8eb8bab2015-07-21 14:44:28 +0000472
473#elif defined(VGO_solaris)
474 STRLEN(VG_Z_LIBC_SONAME, strlen)
475 STRLEN(VG_Z_LD_SO_1, strlen)
476
bart9c7779b2013-11-24 17:48:13 +0000477#endif
478
479
480/*---------------------- strcpy ----------------------*/
481
482#define STRCPY(soname, fnname) \
483 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
484 ( char* dst, const char* src ); \
485 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
486 ( char* dst, const char* src ) \
487 { \
488 const HChar* src_orig = src; \
489 HChar* dst_orig = dst; \
490 \
491 while (*src) *dst++ = *src++; \
492 *dst = 0; \
493 \
494 /* This checks for overlap after copying, unavoidable without */ \
495 /* pre-counting length... should be ok */ \
496 if (is_overlap(dst_orig, \
497 src_orig, \
498 (Addr)dst-(Addr)dst_orig+1, \
499 (Addr)src-(Addr)src_orig+1)) \
500 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
501 \
502 return dst_orig; \
503 }
504
505#if defined(VGO_linux)
506 STRCPY(VG_Z_LIBC_SONAME, strcpy)
507 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
508
509#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000510 STRCPY(VG_Z_LIBC_SONAME, strcpy)
sewardjaec49a42014-06-23 16:03:45 +0000511# if DARWIN_VERS == DARWIN_10_9
512 STRCPY(libsystemZucZddylib, strcpy)
513# endif
bart9c7779b2013-11-24 17:48:13 +0000514
sewardj8eb8bab2015-07-21 14:44:28 +0000515#elif defined(VGO_solaris)
516 STRCPY(VG_Z_LIBC_SONAME, strcpy)
517 STRCPY(VG_Z_LD_SO_1, strcpy)
518
bart9c7779b2013-11-24 17:48:13 +0000519#endif
520
521
522/*---------------------- strncpy ----------------------*/
523
524#define STRNCPY(soname, fnname) \
525 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
526 ( char* dst, const char* src, SizeT n ); \
527 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
528 ( char* dst, const char* src, SizeT n ) \
529 { \
530 const HChar* src_orig = src; \
531 HChar* dst_orig = dst; \
532 SizeT m = 0; \
533 \
534 while (m < n && *src) { m++; *dst++ = *src++; } \
535 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
536 /* but only m+1 bytes of src if terminator was found */ \
537 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
538 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
539 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
540 \
541 return dst_orig; \
542 }
543
544#if defined(VGO_linux)
545 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
546 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
547 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
548 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
549
550#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000551 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
rhyskidd9090d2f2015-07-08 13:46:57 +0000552# if DARWIN_VERS >= DARWIN_10_9
sewardjaec49a42014-06-23 16:03:45 +0000553 STRNCPY(libsystemZucZddylib, strncpy)
554# endif
bart9c7779b2013-11-24 17:48:13 +0000555
sewardj8eb8bab2015-07-21 14:44:28 +0000556#elif defined(VGO_solaris)
557 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
558 STRNCPY(VG_Z_LD_SO_1, strncpy)
559
bart9c7779b2013-11-24 17:48:13 +0000560#endif
561
562
563/*---------------------- strlcpy ----------------------*/
564
565/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
566 Returns strlen(src). Does not zero-fill the remainder of dst. */
567#define STRLCPY(soname, fnname) \
568 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
569 ( char* dst, const char* src, SizeT n ); \
570 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
571 ( char* dst, const char* src, SizeT n ) \
572 { \
573 const HChar* src_orig = src; \
574 HChar* dst_orig = dst; \
575 SizeT m = 0; \
576 \
sewardj8eb8bab2015-07-21 14:44:28 +0000577 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
578 \
bart9c7779b2013-11-24 17:48:13 +0000579 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
580 /* m non-nul bytes have now been copied, and m <= n-1. */ \
581 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
582 /* but only m+1 bytes of src if terminator was found */ \
583 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
584 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
585 /* Nul-terminate dst. */ \
586 if (n > 0) *dst = 0; \
587 /* Finish counting strlen(src). */ \
588 while (*src) src++; \
589 return src - src_orig; \
590 }
591
592#if defined(VGO_linux)
593
dejanj9c6b05d2013-12-27 09:06:55 +0000594#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
595 || defined(VGPV_mips32_linux_android)
sewardj8eb8bab2015-07-21 14:44:28 +0000596 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
bart9c7779b2013-11-24 17:48:13 +0000597 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
598#endif
599
600#elif defined(VGO_darwin)
sewardj8eb8bab2015-07-21 14:44:28 +0000601 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
bart9c7779b2013-11-24 17:48:13 +0000602 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
603 //STRLCPY(VG_Z_DYLD, strlcpy)
604 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
605
sewardj8eb8bab2015-07-21 14:44:28 +0000606#elif defined(VGO_solaris)
607 /* special case for n == 0 which is undocumented but heavily used */
608 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
609 if (n == 0) { \
610 while (*src) src++; \
611 return src - src_orig; \
612 }
613
614 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
615
bart9c7779b2013-11-24 17:48:13 +0000616#endif
617
618
619/*---------------------- strncmp ----------------------*/
620
621#define STRNCMP(soname, fnname) \
622 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
623 ( const char* s1, const char* s2, SizeT nmax ); \
624 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
625 ( const char* s1, const char* s2, SizeT nmax ) \
626 { \
627 SizeT n = 0; \
628 while (True) { \
629 if (n >= nmax) return 0; \
630 if (*s1 == 0 && *s2 == 0) return 0; \
631 if (*s1 == 0) return -1; \
632 if (*s2 == 0) return 1; \
633 \
634 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
635 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
636 \
637 s1++; s2++; n++; \
638 } \
639 }
640
641#if defined(VGO_linux)
642 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
643 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
644 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
645 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
646
647#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000648 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
rhyskidd9090d2f2015-07-08 13:46:57 +0000649# if DARWIN_VERS >= DARWIN_10_9
sewardj798e95b2014-06-25 11:17:46 +0000650 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
651# endif
bart9c7779b2013-11-24 17:48:13 +0000652
sewardj8eb8bab2015-07-21 14:44:28 +0000653#elif defined(VGO_solaris)
654 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
655
bart9c7779b2013-11-24 17:48:13 +0000656#endif
657
658
659/*---------------------- strcasecmp ----------------------*/
660
661#define STRCASECMP(soname, fnname) \
662 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
663 ( const char* s1, const char* s2 ); \
664 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
665 ( const char* s1, const char* s2 ) \
666 { \
667 extern int tolower(int); \
668 register UChar c1; \
669 register UChar c2; \
670 while (True) { \
671 c1 = tolower(*(const UChar *)s1); \
672 c2 = tolower(*(const UChar *)s2); \
673 if (c1 != c2) break; \
674 if (c1 == 0) break; \
675 s1++; s2++; \
676 } \
677 if ((UChar)c1 < (UChar)c2) return -1; \
678 if ((UChar)c1 > (UChar)c2) return 1; \
679 return 0; \
680 }
681
682#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000683# if !defined(VGPV_arm_linux_android) \
684 && !defined(VGPV_x86_linux_android) \
685 && !defined(VGPV_mips32_linux_android) \
686 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000687 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
688 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
689# endif
690
691#elif defined(VGO_darwin)
692 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
693
sewardj8eb8bab2015-07-21 14:44:28 +0000694#elif defined(VGO_solaris)
695 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
696
bart9c7779b2013-11-24 17:48:13 +0000697#endif
698
699
700/*---------------------- strncasecmp ----------------------*/
701
702#define STRNCASECMP(soname, fnname) \
703 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
704 ( const char* s1, const char* s2, SizeT nmax ); \
705 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
706 ( const char* s1, const char* s2, SizeT nmax ) \
707 { \
708 extern int tolower(int); \
709 SizeT n = 0; \
710 while (True) { \
711 if (n >= nmax) return 0; \
712 if (*s1 == 0 && *s2 == 0) return 0; \
713 if (*s1 == 0) return -1; \
714 if (*s2 == 0) return 1; \
715 \
716 if (tolower(*(const UChar *)s1) \
717 < tolower(*(const UChar*)s2)) return -1; \
718 if (tolower(*(const UChar *)s1) \
719 > tolower(*(const UChar *)s2)) return 1; \
720 \
721 s1++; s2++; n++; \
722 } \
723 }
724
725#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000726# if !defined(VGPV_arm_linux_android) \
727 && !defined(VGPV_x86_linux_android) \
728 && !defined(VGPV_mips32_linux_android) \
729 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000730 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
731 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
732# endif
733
734#elif defined(VGO_darwin)
735 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
736 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
737
sewardj8eb8bab2015-07-21 14:44:28 +0000738#elif defined(VGO_solaris)
739 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
740
bart9c7779b2013-11-24 17:48:13 +0000741#endif
742
743
744/*---------------------- strcasecmp_l ----------------------*/
745
746#define STRCASECMP_L(soname, fnname) \
747 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
748 ( const char* s1, const char* s2, void* locale ); \
749 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
750 ( const char* s1, const char* s2, void* locale ) \
751 { \
752 extern int tolower_l(int, void*) __attribute__((weak)); \
753 register UChar c1; \
754 register UChar c2; \
755 while (True) { \
756 c1 = tolower_l(*(const UChar *)s1, locale); \
757 c2 = tolower_l(*(const UChar *)s2, locale); \
758 if (c1 != c2) break; \
759 if (c1 == 0) break; \
760 s1++; s2++; \
761 } \
762 if ((UChar)c1 < (UChar)c2) return -1; \
763 if ((UChar)c1 > (UChar)c2) return 1; \
764 return 0; \
765 }
766
767#if defined(VGO_linux)
768 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
769 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
770 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
771
772#elif defined(VGO_darwin)
773 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
774
sewardj8eb8bab2015-07-21 14:44:28 +0000775#elif defined(VGO_solaris)
776
bart9c7779b2013-11-24 17:48:13 +0000777#endif
778
779
780/*---------------------- strncasecmp_l ----------------------*/
781
782#define STRNCASECMP_L(soname, fnname) \
783 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
784 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
785 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
786 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
787 { \
788 extern int tolower_l(int, void*) __attribute__((weak)); \
789 SizeT n = 0; \
790 while (True) { \
791 if (n >= nmax) return 0; \
792 if (*s1 == 0 && *s2 == 0) return 0; \
793 if (*s1 == 0) return -1; \
794 if (*s2 == 0) return 1; \
795 \
796 if (tolower_l(*(const UChar *)s1, locale) \
797 < tolower_l(*(const UChar *)s2, locale)) return -1; \
798 if (tolower_l(*(const UChar *)s1, locale) \
799 > tolower_l(*(const UChar *)s2, locale)) return 1; \
800 \
801 s1++; s2++; n++; \
802 } \
803 }
804
805#if defined(VGO_linux)
806 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
807 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
808 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
809
810#elif defined(VGO_darwin)
811 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
812 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
813
sewardj8eb8bab2015-07-21 14:44:28 +0000814#elif defined(VGO_solaris)
815
bart9c7779b2013-11-24 17:48:13 +0000816#endif
817
818
819/*---------------------- strcmp ----------------------*/
820
821#define STRCMP(soname, fnname) \
822 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
823 ( const char* s1, const char* s2 ); \
824 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
825 ( const char* s1, const char* s2 ) \
826 { \
827 register UChar c1; \
828 register UChar c2; \
829 while (True) { \
830 c1 = *(const UChar *)s1; \
831 c2 = *(const UChar *)s2; \
832 if (c1 != c2) break; \
833 if (c1 == 0) break; \
834 s1++; s2++; \
835 } \
836 if ((UChar)c1 < (UChar)c2) return -1; \
837 if ((UChar)c1 > (UChar)c2) return 1; \
838 return 0; \
839 }
840
841#if defined(VGO_linux)
842 STRCMP(VG_Z_LIBC_SONAME, strcmp)
843 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
844 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
845 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
846 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
847 STRCMP(VG_Z_LD64_SO_1, strcmp)
dejanj9c6b05d2013-12-27 09:06:55 +0000848# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
849 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000850 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
851# endif
852
853#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000854 STRCMP(VG_Z_LIBC_SONAME, strcmp)
rhyskidd9090d2f2015-07-08 13:46:57 +0000855# if DARWIN_VERS >= DARWIN_10_9
sewardjc3e09f62014-06-21 09:40:19 +0000856 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
857# endif
bart9c7779b2013-11-24 17:48:13 +0000858
sewardj8eb8bab2015-07-21 14:44:28 +0000859#elif defined(VGO_solaris)
860 STRCMP(VG_Z_LIBC_SONAME, strcmp)
861 STRCMP(VG_Z_LD_SO_1, strcmp)
862
bart9c7779b2013-11-24 17:48:13 +0000863#endif
864
865
866/*---------------------- memchr ----------------------*/
867
868#define MEMCHR(soname, fnname) \
869 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
870 (const void *s, int c, SizeT n); \
871 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
872 (const void *s, int c, SizeT n) \
873 { \
874 SizeT i; \
875 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000876 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000877 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000878 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
bart9c7779b2013-11-24 17:48:13 +0000879 return NULL; \
880 }
881
882#if defined(VGO_linux)
883 MEMCHR(VG_Z_LIBC_SONAME, memchr)
884 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
885
886#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000887# if DARWIN_VERS == DARWIN_10_9
sewardj798e95b2014-06-25 11:17:46 +0000888 MEMCHR(VG_Z_DYLD, memchr)
sewardjaec49a42014-06-23 16:03:45 +0000889 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
890# endif
rhyskidd9090d2f2015-07-08 13:46:57 +0000891# if DARWIN_VERS >= DARWIN_10_10
sewardja95abea2014-11-19 09:14:07 +0000892 MEMCHR(VG_Z_DYLD, memchr)
sewardj312bcb12014-11-07 00:08:13 +0000893 /* _platform_memchr$VARIANT$Generic */
894 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
rhyskidde4fcda32015-08-29 07:42:40 +0000895 /* _platform_memchr$VARIANT$Haswell */
896 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
sewardj312bcb12014-11-07 00:08:13 +0000897# endif
bart9c7779b2013-11-24 17:48:13 +0000898
sewardj8eb8bab2015-07-21 14:44:28 +0000899#elif defined(VGO_solaris)
900 MEMCHR(VG_Z_LIBC_SONAME, memchr)
901
bart9c7779b2013-11-24 17:48:13 +0000902#endif
903
904
905/*---------------------- memrchr ----------------------*/
906
907#define MEMRCHR(soname, fnname) \
908 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
909 (const void *s, int c, SizeT n); \
910 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
911 (const void *s, int c, SizeT n) \
912 { \
913 SizeT i; \
914 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000915 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000916 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000917 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
bart9c7779b2013-11-24 17:48:13 +0000918 return NULL; \
919 }
920
921#if defined(VGO_linux)
922 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
923
924#elif defined(VGO_darwin)
925 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
926 //MEMRCHR(VG_Z_DYLD, memrchr)
927
sewardj8eb8bab2015-07-21 14:44:28 +0000928#elif defined(VGO_solaris)
929
bart9c7779b2013-11-24 17:48:13 +0000930#endif
931
932
933/*---------------------- memcpy ----------------------*/
934
935#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
936 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
937 ( void *dst, const void *src, SizeT len ); \
938 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
939 ( void *dst, const void *src, SizeT len ) \
940 { \
941 if (do_ol_check && is_overlap(dst, src, len, len)) \
942 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
943 \
944 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
945 const Addr WM = WS - 1; /* 7 or 3 */ \
946 \
947 if (len > 0) { \
948 if (dst < src || !is_overlap(dst, src, len, len)) { \
949 \
950 /* Copying backwards. */ \
951 SizeT n = len; \
952 Addr d = (Addr)dst; \
953 Addr s = (Addr)src; \
954 \
955 if (((s^d) & WM) == 0) { \
956 /* s and d have same UWord alignment. */ \
957 /* Pull up to a UWord boundary. */ \
958 while ((s & WM) != 0 && n >= 1) \
959 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
960 /* Copy UWords. */ \
961 while (n >= WS) \
962 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
963 if (n == 0) \
964 return dst; \
965 } \
966 if (((s|d) & 1) == 0) { \
967 /* Both are 16-aligned; copy what we can thusly. */ \
968 while (n >= 2) \
969 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
970 } \
971 /* Copy leftovers, or everything if misaligned. */ \
972 while (n >= 1) \
973 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
974 \
975 } else if (dst > src) { \
976 \
977 SizeT n = len; \
978 Addr d = ((Addr)dst) + n; \
979 Addr s = ((Addr)src) + n; \
980 \
981 /* Copying forwards. */ \
982 if (((s^d) & WM) == 0) { \
983 /* s and d have same UWord alignment. */ \
984 /* Back down to a UWord boundary. */ \
985 while ((s & WM) != 0 && n >= 1) \
986 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
987 /* Copy UWords. */ \
988 while (n >= WS) \
989 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
990 if (n == 0) \
991 return dst; \
992 } \
993 if (((s|d) & 1) == 0) { \
994 /* Both are 16-aligned; copy what we can thusly. */ \
995 while (n >= 2) \
996 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
997 } \
998 /* Copy leftovers, or everything if misaligned. */ \
999 while (n >= 1) \
1000 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1001 \
1002 } \
1003 } \
1004 \
1005 return dst; \
1006 }
1007
1008#define MEMMOVE(soname, fnname) \
1009 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1010
1011#define MEMCPY(soname, fnname) \
1012 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1013
1014#if defined(VGO_linux)
1015 /* For older memcpy we have to use memmove-like semantics and skip
1016 the overlap check; sigh; see #275284. */
1017 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1018 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1019 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1020 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1021 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1022 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1023 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1024 /* icc9 blats these around all over the place. Not only in the main
1025 executable but various .so's. They are highly tuned and read
1026 memory beyond the source boundary (although work correctly and
1027 never go across page boundaries), so give errors when run
1028 natively, at least for misaligned source arg. Just intercepting
1029 in the exe only until we understand more about the problem. See
1030 http://bugs.kde.org/show_bug.cgi?id=139776
1031 */
1032 MEMCPY(NONE, ZuintelZufastZumemcpy)
1033
1034#elif defined(VGO_darwin)
1035# if DARWIN_VERS <= DARWIN_10_6
1036 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1037# endif
1038 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1039 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1040
sewardj8eb8bab2015-07-21 14:44:28 +00001041#elif defined(VGO_solaris)
1042 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1043 MEMCPY(VG_Z_LD_SO_1, memcpy)
1044
bart9c7779b2013-11-24 17:48:13 +00001045#endif
1046
1047
1048/*---------------------- memcmp ----------------------*/
1049
1050#define MEMCMP(soname, fnname) \
1051 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1052 ( const void *s1V, const void *s2V, SizeT n ); \
1053 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1054 ( const void *s1V, const void *s2V, SizeT n ) \
1055 { \
sewardj094b9912015-02-04 18:46:11 +00001056 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1057 const SizeT WM = WS - 1; /* 7 or 3 */ \
sewardj11e20f72015-02-04 17:52:42 +00001058 Addr s1A = (Addr)s1V; \
1059 Addr s2A = (Addr)s2V; \
1060 \
1061 if (((s1A | s2A) & WM) == 0) { \
1062 /* Both areas are word aligned. Skip over the */ \
1063 /* equal prefix as fast as possible. */ \
1064 while (n >= WS) { \
1065 UWord w1 = *(UWord*)s1A; \
1066 UWord w2 = *(UWord*)s2A; \
1067 if (w1 != w2) break; \
1068 s1A += WS; \
1069 s2A += WS; \
1070 n -= WS; \
1071 } \
1072 } \
1073 \
1074 const UChar* s1 = (const UChar*) s1A; \
1075 const UChar* s2 = (const UChar*) s2A; \
bart9c7779b2013-11-24 17:48:13 +00001076 \
1077 while (n != 0) { \
sewardj11e20f72015-02-04 17:52:42 +00001078 UChar a0 = s1[0]; \
1079 UChar b0 = s2[0]; \
bart9c7779b2013-11-24 17:48:13 +00001080 s1 += 1; \
1081 s2 += 1; \
sewardj11e20f72015-02-04 17:52:42 +00001082 int res = ((int)a0) - ((int)b0); \
bart9c7779b2013-11-24 17:48:13 +00001083 if (res != 0) \
1084 return res; \
1085 n -= 1; \
1086 } \
1087 return 0; \
1088 }
1089
1090#if defined(VGO_linux)
1091 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1092 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1093 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1094 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1095 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1096 MEMCMP(VG_Z_LD_SO_1, bcmp)
1097
1098#elif defined(VGO_darwin)
rhyskidd9090d2f2015-07-08 13:46:57 +00001099# if DARWIN_VERS >= DARWIN_10_9
sewardjaec49a42014-06-23 16:03:45 +00001100 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1101# endif
bart9c7779b2013-11-24 17:48:13 +00001102
sewardj8eb8bab2015-07-21 14:44:28 +00001103#elif defined(VGO_solaris)
1104 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1105 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1106 MEMCMP(VG_Z_LD_SO_1, memcmp)
1107
bart9c7779b2013-11-24 17:48:13 +00001108#endif
1109
1110
1111/*---------------------- stpcpy ----------------------*/
1112
1113/* Copy SRC to DEST, returning the address of the terminating '\0' in
1114 DEST. (minor variant of strcpy) */
1115#define STPCPY(soname, fnname) \
1116 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1117 ( char* dst, const char* src ); \
1118 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1119 ( char* dst, const char* src ) \
1120 { \
1121 const HChar* src_orig = src; \
1122 HChar* dst_orig = dst; \
1123 \
1124 while (*src) *dst++ = *src++; \
1125 *dst = 0; \
1126 \
1127 /* This checks for overlap after copying, unavoidable without */ \
1128 /* pre-counting length... should be ok */ \
1129 if (is_overlap(dst_orig, \
1130 src_orig, \
1131 (Addr)dst-(Addr)dst_orig+1, \
1132 (Addr)src-(Addr)src_orig+1)) \
1133 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1134 \
1135 return dst; \
1136 }
1137
1138#if defined(VGO_linux)
1139 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1140 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1141 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1142 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1143 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1144 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1145
1146#elif defined(VGO_darwin)
1147 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1148 //STPCPY(VG_Z_DYLD, stpcpy)
1149
sewardj8eb8bab2015-07-21 14:44:28 +00001150#elif defined(VGO_solaris)
1151 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1152
bart9c7779b2013-11-24 17:48:13 +00001153#endif
1154
1155
1156/*---------------------- stpncpy ----------------------*/
1157
1158#define STPNCPY(soname, fnname) \
1159 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1160 ( char* dst, const char* src, SizeT n ); \
1161 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1162 ( char* dst, const char* src, SizeT n ) \
1163 { \
1164 const HChar* src_orig = src; \
1165 HChar* dst_str = dst; \
1166 SizeT m = 0; \
1167 \
1168 while (m < n && *src) { m++; *dst++ = *src++; } \
1169 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1170 /* but only m+1 bytes of src if terminator was found */ \
1171 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1172 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1173 dst_str = dst; \
1174 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1175 \
1176 return dst_str; \
1177 }
1178
1179#if defined(VGO_linux)
1180 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1181#endif
1182
1183
1184/*---------------------- memset ----------------------*/
1185
1186/* Why are we bothering to intercept this? It seems entirely
1187 pointless. */
1188
1189#define MEMSET(soname, fnname) \
1190 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1191 (void *s, Int c, SizeT n); \
1192 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1193 (void *s, Int c, SizeT n) \
1194 { \
1195 if (sizeof(void*) == 8) { \
1196 Addr a = (Addr)s; \
1197 ULong c8 = (c & 0xFF); \
1198 c8 = (c8 << 8) | c8; \
1199 c8 = (c8 << 16) | c8; \
1200 c8 = (c8 << 32) | c8; \
1201 while ((a & 7) != 0 && n >= 1) \
1202 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1203 while (n >= 8) \
1204 { *(ULong*)a = c8; a += 8; n -= 8; } \
1205 while (n >= 1) \
1206 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1207 return s; \
1208 } else { \
1209 Addr a = (Addr)s; \
1210 UInt c4 = (c & 0xFF); \
1211 c4 = (c4 << 8) | c4; \
1212 c4 = (c4 << 16) | c4; \
1213 while ((a & 3) != 0 && n >= 1) \
1214 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1215 while (n >= 4) \
1216 { *(UInt*)a = c4; a += 4; n -= 4; } \
1217 while (n >= 1) \
1218 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1219 return s; \
1220 } \
1221 }
1222
1223#if defined(VGO_linux)
1224 MEMSET(VG_Z_LIBC_SONAME, memset)
1225
1226#elif defined(VGO_darwin)
1227 //MEMSET(VG_Z_LIBC_SONAME, memset)
1228 //MEMSET(VG_Z_DYLD, memset)
1229 MEMSET(VG_Z_LIBC_SONAME, memset)
1230
sewardj8eb8bab2015-07-21 14:44:28 +00001231#elif defined(VGO_solaris)
1232 MEMSET(VG_Z_LIBC_SONAME, memset)
1233
bart9c7779b2013-11-24 17:48:13 +00001234#endif
1235
1236
1237/*---------------------- memmove ----------------------*/
1238
1239/* memmove -- use the MEMMOVE defn above. */
1240
1241#if defined(VGO_linux)
1242 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1243 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
mjwb97cf8e2015-07-07 13:01:39 +00001244 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1245 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1246 to call memcpy. */
1247 MEMMOVE(VG_Z_LD64_SO_1, memmove)
bart9c7779b2013-11-24 17:48:13 +00001248
1249#elif defined(VGO_darwin)
1250# if DARWIN_VERS <= DARWIN_10_6
1251 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1252# endif
1253 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1254 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
rhyskidd9090d2f2015-07-08 13:46:57 +00001255# if DARWIN_VERS >= DARWIN_10_9
sewardj312bcb12014-11-07 00:08:13 +00001256 /* _platform_memmove$VARIANT$Ivybridge */
sewardjeb86dda2014-10-17 15:07:37 +00001257 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1258# endif
sewardj8eb8bab2015-07-21 14:44:28 +00001259
1260#elif defined(VGO_solaris)
1261 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1262 MEMMOVE(VG_Z_LD_SO_1, memmove)
1263
bart9c7779b2013-11-24 17:48:13 +00001264#endif
1265
1266
1267/*---------------------- bcopy ----------------------*/
1268
1269#define BCOPY(soname, fnname) \
1270 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1271 (const void *srcV, void *dstV, SizeT n); \
1272 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1273 (const void *srcV, void *dstV, SizeT n) \
1274 { \
1275 SizeT i; \
1276 HChar* dst = dstV; \
1277 const HChar* src = srcV; \
1278 if (dst < src) { \
1279 for (i = 0; i < n; i++) \
1280 dst[i] = src[i]; \
1281 } \
1282 else \
1283 if (dst > src) { \
1284 for (i = 0; i < n; i++) \
1285 dst[n-i-1] = src[n-i-1]; \
1286 } \
1287 }
1288
1289#if defined(VGO_linux)
1290 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1291
1292#elif defined(VGO_darwin)
1293 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1294 //BCOPY(VG_Z_DYLD, bcopy)
1295
sewardj8eb8bab2015-07-21 14:44:28 +00001296#elif defined(VGO_darwin)
1297 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1298
bart9c7779b2013-11-24 17:48:13 +00001299#endif
1300
1301
1302/*-------------------- memmove_chk --------------------*/
1303
1304/* glibc 2.5 variant of memmove which checks the dest is big enough.
1305 There is no specific part of glibc that this is copied from. */
1306#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1307 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1308 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1309 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1310 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1311 { \
1312 SizeT i; \
1313 HChar* dst = dstV; \
1314 const HChar* src = srcV; \
1315 if (destlen < n) \
1316 goto badness; \
1317 if (dst < src) { \
1318 for (i = 0; i < n; i++) \
1319 dst[i] = src[i]; \
1320 } \
1321 else \
1322 if (dst > src) { \
1323 for (i = 0; i < n; i++) \
1324 dst[n-i-1] = src[n-i-1]; \
1325 } \
1326 return dst; \
1327 badness: \
1328 VALGRIND_PRINTF_BACKTRACE( \
1329 "*** memmove_chk: buffer overflow detected ***: " \
1330 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001331 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001332 /*NOTREACHED*/ \
1333 return NULL; \
1334 }
1335
1336#if defined(VGO_linux)
1337 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1338
1339#elif defined(VGO_darwin)
1340
sewardj8eb8bab2015-07-21 14:44:28 +00001341#elif defined(VGO_solaris)
1342
bart9c7779b2013-11-24 17:48:13 +00001343#endif
1344
1345
1346/*-------------------- strchrnul --------------------*/
1347
1348/* Find the first occurrence of C in S or the final NUL byte. */
1349#define GLIBC232_STRCHRNUL(soname, fnname) \
1350 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1351 (const char* s, int c_in); \
1352 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1353 (const char* s, int c_in) \
1354 { \
florian70a5de12014-10-22 12:53:16 +00001355 HChar c = (HChar) c_in; \
1356 const HChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001357 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001358 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1359 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001360 char_ptr++; \
1361 } \
1362 }
1363
1364#if defined(VGO_linux)
1365 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1366
1367#elif defined(VGO_darwin)
1368
sewardj8eb8bab2015-07-21 14:44:28 +00001369#elif defined(VGO_solaris)
1370
bart9c7779b2013-11-24 17:48:13 +00001371#endif
1372
1373
1374/*---------------------- rawmemchr ----------------------*/
1375
1376/* Find the first occurrence of C in S. */
1377#define GLIBC232_RAWMEMCHR(soname, fnname) \
florian1ef205b2014-10-22 12:06:22 +00001378 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1379 (const void* s, int c_in); \
1380 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1381 (const void* s, int c_in) \
bart9c7779b2013-11-24 17:48:13 +00001382 { \
florian1ef205b2014-10-22 12:06:22 +00001383 UChar c = (UChar) c_in; \
1384 const UChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001385 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001386 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001387 char_ptr++; \
1388 } \
1389 }
1390
1391#if defined (VGO_linux)
1392 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1393 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1394
1395#elif defined(VGO_darwin)
1396
sewardj8eb8bab2015-07-21 14:44:28 +00001397#elif defined(VGO_solaris)
1398
bart9c7779b2013-11-24 17:48:13 +00001399#endif
1400
1401
1402/*---------------------- strcpy_chk ----------------------*/
1403
1404/* glibc variant of strcpy that checks the dest is big enough.
1405 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1406#define GLIBC25___STRCPY_CHK(soname,fnname) \
1407 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1408 (char* dst, const char* src, SizeT len); \
1409 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1410 (char* dst, const char* src, SizeT len) \
1411 { \
1412 HChar* ret = dst; \
1413 if (! len) \
1414 goto badness; \
1415 while ((*dst++ = *src++) != '\0') \
1416 if (--len == 0) \
1417 goto badness; \
1418 return ret; \
1419 badness: \
1420 VALGRIND_PRINTF_BACKTRACE( \
1421 "*** strcpy_chk: buffer overflow detected ***: " \
1422 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001423 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001424 /*NOTREACHED*/ \
1425 return NULL; \
1426 }
1427
1428#if defined(VGO_linux)
1429 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1430
1431#elif defined(VGO_darwin)
1432
sewardj8eb8bab2015-07-21 14:44:28 +00001433#elif defined(VGO_solaris)
1434
bart9c7779b2013-11-24 17:48:13 +00001435#endif
1436
1437
1438/*---------------------- stpcpy_chk ----------------------*/
1439
1440/* glibc variant of stpcpy that checks the dest is big enough.
1441 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1442#define GLIBC25___STPCPY_CHK(soname,fnname) \
1443 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1444 (char* dst, const char* src, SizeT len); \
1445 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1446 (char* dst, const char* src, SizeT len) \
1447 { \
1448 if (! len) \
1449 goto badness; \
1450 while ((*dst++ = *src++) != '\0') \
1451 if (--len == 0) \
1452 goto badness; \
1453 return dst - 1; \
1454 badness: \
1455 VALGRIND_PRINTF_BACKTRACE( \
1456 "*** stpcpy_chk: buffer overflow detected ***: " \
1457 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001458 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001459 /*NOTREACHED*/ \
1460 return NULL; \
1461 }
1462
1463#if defined(VGO_linux)
1464 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1465
1466#elif defined(VGO_darwin)
1467
sewardj8eb8bab2015-07-21 14:44:28 +00001468#elif defined(VGO_solaris)
1469
bart9c7779b2013-11-24 17:48:13 +00001470#endif
1471
1472
1473/*---------------------- mempcpy ----------------------*/
1474
1475/* mempcpy */
1476#define GLIBC25_MEMPCPY(soname, fnname) \
1477 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1478 ( void *dst, const void *src, SizeT len ); \
1479 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1480 ( void *dst, const void *src, SizeT len ) \
1481 { \
bart9c7779b2013-11-24 17:48:13 +00001482 SizeT len_saved = len; \
1483 \
1484 if (len == 0) \
1485 return dst; \
1486 \
1487 if (is_overlap(dst, src, len, len)) \
1488 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1489 \
1490 if ( dst > src ) { \
florian09041e42014-10-21 17:15:14 +00001491 register HChar *d = (char *)dst + len - 1; \
1492 register const HChar *s = (const char *)src + len - 1; \
bart9c7779b2013-11-24 17:48:13 +00001493 while ( len-- ) { \
1494 *d-- = *s--; \
1495 } \
1496 } else if ( dst < src ) { \
florian09041e42014-10-21 17:15:14 +00001497 register HChar *d = dst; \
1498 register const HChar *s = src; \
bart9c7779b2013-11-24 17:48:13 +00001499 while ( len-- ) { \
1500 *d++ = *s++; \
1501 } \
1502 } \
1503 return (void*)( ((char*)dst) + len_saved ); \
1504 }
1505
1506#if defined(VGO_linux)
1507 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
mjwa9176d92015-01-13 16:10:20 +00001508 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
bart9c7779b2013-11-24 17:48:13 +00001509 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
bartf2d86632014-03-15 12:47:28 +00001510 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1511 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
bart9c7779b2013-11-24 17:48:13 +00001512
1513#elif defined(VGO_darwin)
1514 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1515
sewardj8eb8bab2015-07-21 14:44:28 +00001516#elif defined(VGO_solaris)
1517
bart9c7779b2013-11-24 17:48:13 +00001518#endif
1519
1520
1521/*-------------------- memcpy_chk --------------------*/
1522
1523#define GLIBC26___MEMCPY_CHK(soname, fnname) \
1524 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1525 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1526 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1527 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1528 { \
1529 register HChar *d; \
1530 register const HChar *s; \
1531 \
1532 if (dstlen < len) goto badness; \
1533 \
1534 if (len == 0) \
1535 return dst; \
1536 \
1537 if (is_overlap(dst, src, len, len)) \
1538 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1539 \
1540 if ( dst > src ) { \
1541 d = (HChar *)dst + len - 1; \
1542 s = (const HChar *)src + len - 1; \
1543 while ( len-- ) { \
1544 *d-- = *s--; \
1545 } \
1546 } else if ( dst < src ) { \
1547 d = (HChar *)dst; \
1548 s = (const HChar *)src; \
1549 while ( len-- ) { \
1550 *d++ = *s++; \
1551 } \
1552 } \
1553 return dst; \
1554 badness: \
1555 VALGRIND_PRINTF_BACKTRACE( \
1556 "*** memcpy_chk: buffer overflow detected ***: " \
1557 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001558 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001559 /*NOTREACHED*/ \
1560 return NULL; \
1561 }
1562
1563#if defined(VGO_linux)
1564 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1565
1566#elif defined(VGO_darwin)
1567
sewardj8eb8bab2015-07-21 14:44:28 +00001568#elif defined(VGO_solaris)
1569
bart9c7779b2013-11-24 17:48:13 +00001570#endif
1571
1572
1573/*---------------------- strstr ----------------------*/
1574
1575#define STRSTR(soname, fnname) \
1576 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1577 (const char* haystack, const char* needle); \
1578 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1579 (const char* haystack, const char* needle) \
1580 { \
1581 const HChar* h = haystack; \
1582 const HChar* n = needle; \
1583 \
1584 /* find the length of n, not including terminating zero */ \
1585 UWord nlen = 0; \
1586 while (n[nlen]) nlen++; \
1587 \
1588 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001589 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001590 \
1591 /* assert(nlen >= 1); */ \
1592 HChar n0 = n[0]; \
1593 \
1594 while (1) { \
1595 const HChar hh = *h; \
1596 if (hh == 0) return NULL; \
1597 if (hh != n0) { h++; continue; } \
1598 \
1599 UWord i; \
1600 for (i = 0; i < nlen; i++) { \
1601 if (n[i] != h[i]) \
1602 break; \
1603 } \
1604 /* assert(i >= 0 && i <= nlen); */ \
1605 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001606 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001607 \
1608 h++; \
1609 } \
1610 }
1611
1612#if defined(VGO_linux)
1613 STRSTR(VG_Z_LIBC_SONAME, strstr)
1614 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1615 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1616
1617#elif defined(VGO_darwin)
1618
sewardj8eb8bab2015-07-21 14:44:28 +00001619#elif defined(VGO_solaris)
1620 STRSTR(VG_Z_LIBC_SONAME, strstr)
1621
bart9c7779b2013-11-24 17:48:13 +00001622#endif
1623
1624
1625/*---------------------- strpbrk ----------------------*/
1626
1627#define STRPBRK(soname, fnname) \
1628 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1629 (const char* sV, const char* acceptV); \
1630 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1631 (const char* sV, const char* acceptV) \
1632 { \
1633 const HChar* s = sV; \
1634 const HChar* accept = acceptV; \
1635 \
1636 /* find the length of 'accept', not including terminating zero */ \
1637 UWord nacc = 0; \
1638 while (accept[nacc]) nacc++; \
1639 \
1640 /* if n is the empty string, fail immediately. */ \
1641 if (nacc == 0) return NULL; \
1642 \
1643 /* assert(nacc >= 1); */ \
1644 while (1) { \
1645 UWord i; \
1646 HChar sc = *s; \
1647 if (sc == 0) \
1648 break; \
1649 for (i = 0; i < nacc; i++) { \
1650 if (sc == accept[i]) \
florian70a5de12014-10-22 12:53:16 +00001651 return CONST_CAST(HChar *,s); \
bart9c7779b2013-11-24 17:48:13 +00001652 } \
1653 s++; \
1654 } \
1655 \
1656 return NULL; \
1657 }
1658
1659#if defined(VGO_linux)
1660 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1661
1662#elif defined(VGO_darwin)
1663
sewardj8eb8bab2015-07-21 14:44:28 +00001664#elif defined(VGO_solaris)
1665 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1666
bart9c7779b2013-11-24 17:48:13 +00001667#endif
1668
1669
1670/*---------------------- strcspn ----------------------*/
1671
1672#define STRCSPN(soname, fnname) \
1673 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1674 (const char* sV, const char* rejectV); \
1675 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1676 (const char* sV, const char* rejectV) \
1677 { \
1678 const HChar* s = sV; \
1679 const HChar* reject = rejectV; \
1680 \
1681 /* find the length of 'reject', not including terminating zero */ \
1682 UWord nrej = 0; \
1683 while (reject[nrej]) nrej++; \
1684 \
1685 UWord len = 0; \
1686 while (1) { \
1687 UWord i; \
1688 HChar sc = *s; \
1689 if (sc == 0) \
1690 break; \
1691 for (i = 0; i < nrej; i++) { \
1692 if (sc == reject[i]) \
1693 break; \
1694 } \
1695 /* assert(i >= 0 && i <= nrej); */ \
1696 if (i < nrej) \
1697 break; \
1698 s++; \
1699 len++; \
1700 } \
1701 \
1702 return len; \
1703 }
1704
1705#if defined(VGO_linux)
1706 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1707
1708#elif defined(VGO_darwin)
1709
sewardj8eb8bab2015-07-21 14:44:28 +00001710#elif defined(VGO_solaris)
1711 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1712
bart9c7779b2013-11-24 17:48:13 +00001713#endif
1714
1715
1716/*---------------------- strspn ----------------------*/
1717
1718#define STRSPN(soname, fnname) \
1719 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1720 (const char* sV, const char* acceptV); \
1721 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1722 (const char* sV, const char* acceptV) \
1723 { \
1724 const UChar* s = (const UChar *)sV; \
1725 const UChar* accept = (const UChar *)acceptV; \
1726 \
1727 /* find the length of 'accept', not including terminating zero */ \
1728 UWord nacc = 0; \
1729 while (accept[nacc]) nacc++; \
1730 if (nacc == 0) return 0; \
1731 \
1732 UWord len = 0; \
1733 while (1) { \
1734 UWord i; \
1735 HChar sc = *s; \
1736 if (sc == 0) \
1737 break; \
1738 for (i = 0; i < nacc; i++) { \
1739 if (sc == accept[i]) \
1740 break; \
1741 } \
1742 /* assert(i >= 0 && i <= nacc); */ \
1743 if (i == nacc) \
1744 break; \
1745 s++; \
1746 len++; \
1747 } \
1748 \
1749 return len; \
1750 }
1751
1752#if defined(VGO_linux)
1753 STRSPN(VG_Z_LIBC_SONAME, strspn)
1754
1755#elif defined(VGO_darwin)
1756
sewardj8eb8bab2015-07-21 14:44:28 +00001757#elif defined(VGO_solaris)
1758 STRSPN(VG_Z_LIBC_SONAME, strspn)
1759
bart9c7779b2013-11-24 17:48:13 +00001760#endif
1761
1762
1763/*---------------------- strcasestr ----------------------*/
1764
1765#define STRCASESTR(soname, fnname) \
1766 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1767 (const char* haystack, const char* needle); \
1768 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1769 (const char* haystack, const char* needle) \
1770 { \
1771 extern int tolower(int); \
1772 const HChar* h = haystack; \
1773 const HChar* n = needle; \
1774 \
1775 /* find the length of n, not including terminating zero */ \
1776 UWord nlen = 0; \
1777 while (n[nlen]) nlen++; \
1778 \
1779 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001780 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001781 \
1782 /* assert(nlen >= 1); */ \
1783 UChar n0 = tolower(n[0]); \
1784 \
1785 while (1) { \
1786 UChar hh = tolower(*h); \
1787 if (hh == 0) return NULL; \
1788 if (hh != n0) { h++; continue; } \
1789 \
1790 UWord i; \
1791 for (i = 0; i < nlen; i++) { \
1792 if (tolower(n[i]) != tolower(h[i])) \
1793 break; \
1794 } \
1795 /* assert(i >= 0 && i <= nlen); */ \
1796 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001797 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001798 \
1799 h++; \
1800 } \
1801 }
1802
1803#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +00001804# if !defined(VGPV_arm_linux_android) \
1805 && !defined(VGPV_x86_linux_android) \
1806 && !defined(VGPV_mips32_linux_android) \
1807 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +00001808 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1809# endif
1810
1811#elif defined(VGO_darwin)
1812
sewardj8eb8bab2015-07-21 14:44:28 +00001813#elif defined(VGO_solaris)
1814 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1815
bart9c7779b2013-11-24 17:48:13 +00001816#endif
1817
1818
1819/*---------------------- wcslen ----------------------*/
1820
1821// This is a wchar_t equivalent to strlen. Unfortunately
1822// we don't have wchar_t available here, but it looks like
1823// a 32 bit int on Linux. I don't know if that is also
1824// valid on MacOSX.
1825
1826#define WCSLEN(soname, fnname) \
1827 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1828 ( const UInt* str ); \
1829 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1830 ( const UInt* str ) \
1831 { \
1832 SizeT i = 0; \
1833 while (str[i] != 0) i++; \
1834 return i; \
1835 }
1836
1837#if defined(VGO_linux)
1838 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1839
1840#elif defined(VGO_darwin)
1841
sewardj8eb8bab2015-07-21 14:44:28 +00001842#elif defined(VGO_solaris)
1843 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1844
bart9c7779b2013-11-24 17:48:13 +00001845#endif
1846
1847/*---------------------- wcscmp ----------------------*/
1848
1849// This is a wchar_t equivalent to strcmp. We don't
1850// have wchar_t available here, but in the GNU C Library
1851// wchar_t is always 32 bits wide and wcscmp uses signed
1852// comparison, not unsigned as in strcmp function.
1853
1854#define WCSCMP(soname, fnname) \
1855 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1856 ( const Int* s1, const Int* s2 ); \
1857 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1858 ( const Int* s1, const Int* s2 ) \
1859 { \
1860 register Int c1; \
1861 register Int c2; \
1862 while (True) { \
1863 c1 = *s1; \
1864 c2 = *s2; \
1865 if (c1 != c2) break; \
1866 if (c1 == 0) break; \
1867 s1++; s2++; \
1868 } \
1869 if (c1 < c2) return -1; \
1870 if (c1 > c2) return 1; \
1871 return 0; \
1872 }
1873
1874#if defined(VGO_linux)
1875 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
1876#endif
1877
1878/*---------------------- wcscpy ----------------------*/
1879
1880// This is a wchar_t equivalent to strcpy. We don't
1881// have wchar_t available here, but in the GNU C Library
1882// wchar_t is always 32 bits wide.
1883
1884#define WCSCPY(soname, fnname) \
1885 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1886 ( Int* dst, const Int* src ); \
1887 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1888 ( Int* dst, const Int* src ) \
1889 { \
1890 const Int* src_orig = src; \
1891 Int* dst_orig = dst; \
1892 \
1893 while (*src) *dst++ = *src++; \
1894 *dst = 0; \
1895 \
1896 /* This checks for overlap after copying, unavoidable without */ \
1897 /* pre-counting length... should be ok */ \
1898 if (is_overlap(dst_orig, \
1899 src_orig, \
1900 (Addr)dst-(Addr)dst_orig+1, \
1901 (Addr)src-(Addr)src_orig+1)) \
1902 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1903 \
1904 return dst_orig; \
1905 }
1906
1907#if defined(VGO_linux)
1908 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
1909#endif
1910
1911
1912/*---------------------- wcschr ----------------------*/
1913
1914// This is a wchar_t equivalent to strchr. We don't
1915// have wchar_t available here, but in the GNU C Library
1916// wchar_t is always 32 bits wide.
1917
1918#define WCSCHR(soname, fnname) \
1919 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1920 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1921 { \
florian70a5de12014-10-22 12:53:16 +00001922 const Int* p = s; \
bart9c7779b2013-11-24 17:48:13 +00001923 while (True) { \
florian70a5de12014-10-22 12:53:16 +00001924 if (*p == c) return CONST_CAST(Int *,p); \
bart9c7779b2013-11-24 17:48:13 +00001925 if (*p == 0) return NULL; \
1926 p++; \
1927 } \
1928 }
1929
1930#if defined(VGO_linux)
1931 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
1932#endif
1933/*---------------------- wcsrchr ----------------------*/
1934
1935// This is a wchar_t equivalent to strrchr. We don't
1936// have wchar_t available here, but in the GNU C Library
1937// wchar_t is always 32 bits wide.
1938
1939#define WCSRCHR(soname, fnname) \
1940 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1941 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1942 { \
florian70a5de12014-10-22 12:53:16 +00001943 const Int* p = s; \
1944 const Int* last = NULL; \
bart9c7779b2013-11-24 17:48:13 +00001945 while (True) { \
1946 if (*p == c) last = p; \
florian70a5de12014-10-22 12:53:16 +00001947 if (*p == 0) return CONST_CAST(Int *,last); \
bart9c7779b2013-11-24 17:48:13 +00001948 p++; \
1949 } \
1950 }
1951
1952#if defined(VGO_linux)
1953 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
1954#endif
1955
1956/*------------------------------------------------------------*/
1957/*--- Improve definedness checking of process environment ---*/
1958/*------------------------------------------------------------*/
1959
1960#if defined(VGO_linux)
1961
1962/* If these wind up getting generated via a macro, so that multiple
1963 versions of each function exist (as above), use the _EZU variants
1964 to assign equivalance class tags. */
1965
1966/*---------------------- putenv ----------------------*/
1967
1968int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1969int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1970{
1971 OrigFn fn;
1972 Word result;
1973 const HChar* p = string;
1974 VALGRIND_GET_ORIG_FN(fn);
1975 /* Now by walking over the string we magically produce
1976 traces when hitting undefined memory. */
1977 if (p)
1978 while (*p++)
1979 __asm__ __volatile__("" ::: "memory");
1980 CALL_FN_W_W(result, fn, string);
1981 return result;
1982}
1983
1984
1985/*---------------------- unsetenv ----------------------*/
1986
1987int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
1988int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1989{
1990 OrigFn fn;
1991 Word result;
1992 const HChar* p = name;
1993 VALGRIND_GET_ORIG_FN(fn);
1994 /* Now by walking over the string we magically produce
1995 traces when hitting undefined memory. */
1996 if (p)
1997 while (*p++)
1998 __asm__ __volatile__("" ::: "memory");
1999 CALL_FN_W_W(result, fn, name);
2000 return result;
2001}
2002
2003
2004/*---------------------- setenv ----------------------*/
2005
2006/* setenv */
2007int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2008 (const char* name, const char* value, int overwrite);
2009int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2010 (const char* name, const char* value, int overwrite)
2011{
2012 OrigFn fn;
2013 Word result;
2014 const HChar* p;
2015 VALGRIND_GET_ORIG_FN(fn);
2016 /* Now by walking over the string we magically produce
2017 traces when hitting undefined memory. */
2018 if (name)
2019 for (p = name; *p; p++)
2020 __asm__ __volatile__("" ::: "memory");
2021 if (value)
2022 for (p = value; *p; p++)
2023 __asm__ __volatile__("" ::: "memory");
2024 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2025 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2026 return result;
2027}
2028
2029#endif /* defined(VGO_linux) */
2030
2031/*--------------------------------------------------------------------*/
2032/*--- end ---*/
2033/*--------------------------------------------------------------------*/