blob: f2875fc2a66aa924662dccea15b95875d6730bb5 [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
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright (C) 2000-2017 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)
Elliott Hughesa0664b92017-04-18 17:46:52 -0700250# if !defined(VGP_x86_linux) && !defined(VGP_amd64_linux)
bart9c7779b2013-11-24 17:48:13 +0000251 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
Elliott Hughesed398002017-06-21 14:41:24 -0700257#if defined(VGPV_mips32_linux_android)
258 STRCHR(NONE, __dl_strchr)
259#endif
260
bart9c7779b2013-11-24 17:48:13 +0000261#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000262 STRCHR(VG_Z_LIBC_SONAME, strchr)
sewardjc3e09f62014-06-21 09:40:19 +0000263# if DARWIN_VERS == DARWIN_10_9
264 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
265# endif
rhyskidd9090d2f2015-07-08 13:46:57 +0000266# if DARWIN_VERS >= DARWIN_10_10
rhyskidd99513232015-03-26 10:14:25 +0000267 /* _platform_strchr$VARIANT$Generic */
268 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
rhyskidde4fcda32015-08-29 07:42:40 +0000269 /* _platform_strchr$VARIANT$Haswell */
rhyskidd366cefb2015-05-14 13:03:08 +0000270 STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
rhyskidd99513232015-03-26 10:14:25 +0000271# endif
sewardj8eb8bab2015-07-21 14:44:28 +0000272
273#elif defined(VGO_solaris)
274 STRCHR(VG_Z_LIBC_SONAME, strchr)
275 STRCHR(VG_Z_LIBC_SONAME, index)
276 STRCHR(VG_Z_LD_SO_1, strchr)
277
bart9c7779b2013-11-24 17:48:13 +0000278#endif
279
280
281/*---------------------- strcat ----------------------*/
282
283#define STRCAT(soname, fnname) \
284 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
285 ( char* dst, const char* src ); \
286 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
287 ( char* dst, const char* src ) \
288 { \
289 const HChar* src_orig = src; \
290 HChar* dst_orig = dst; \
291 while (*dst) dst++; \
292 while (*src) *dst++ = *src++; \
293 *dst = 0; \
294 \
295 /* This is a bit redundant, I think; any overlap and the strcat will */ \
296 /* go forever... or until a seg fault occurs. */ \
297 if (is_overlap(dst_orig, \
298 src_orig, \
299 (Addr)dst-(Addr)dst_orig+1, \
300 (Addr)src-(Addr)src_orig+1)) \
301 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
302 \
303 return dst_orig; \
304 }
305
306#if defined(VGO_linux)
307 STRCAT(VG_Z_LIBC_SONAME, strcat)
308 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
309
310#elif defined(VGO_darwin)
311 //STRCAT(VG_Z_LIBC_SONAME, strcat)
312
sewardj8eb8bab2015-07-21 14:44:28 +0000313#elif defined(VGO_solaris)
314 STRCAT(VG_Z_LIBC_SONAME, strcat)
315 STRCAT(VG_Z_LD_SO_1, strcat)
316
bart9c7779b2013-11-24 17:48:13 +0000317#endif
318
319
320/*---------------------- strncat ----------------------*/
321
322#define STRNCAT(soname, fnname) \
323 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
324 ( char* dst, const char* src, SizeT n ); \
325 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
326 ( char* dst, const char* src, SizeT n ) \
327 { \
328 const HChar* src_orig = src; \
329 HChar* dst_orig = dst; \
330 SizeT m = 0; \
331 \
332 while (*dst) dst++; \
333 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
334 *dst = 0; /* always add null */ \
335 \
336 /* This checks for overlap after copying, unavoidable without */ \
337 /* pre-counting lengths... should be ok */ \
338 if (is_overlap(dst_orig, \
339 src_orig, \
340 (Addr)dst-(Addr)dst_orig+1, \
341 (Addr)src-(Addr)src_orig+1)) \
342 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
343 \
344 return dst_orig; \
345 }
346
347#if defined(VGO_linux)
348 STRNCAT(VG_Z_LIBC_SONAME, strncat)
349
350#elif defined(VGO_darwin)
351 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
352 //STRNCAT(VG_Z_DYLD, strncat)
353
sewardj8eb8bab2015-07-21 14:44:28 +0000354#elif defined(VGO_solaris)
355 STRNCAT(VG_Z_LIBC_SONAME, strncat)
356
bart9c7779b2013-11-24 17:48:13 +0000357#endif
358
359
360/*---------------------- strlcat ----------------------*/
361
362/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
363 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
364 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
365 Truncation occurred if retval >= n.
366*/
367#define STRLCAT(soname, fnname) \
368 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
369 ( char* dst, const char* src, SizeT n ); \
370 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
371 ( char* dst, const char* src, SizeT n ) \
372 { \
373 const HChar* src_orig = src; \
374 HChar* dst_orig = dst; \
375 SizeT m = 0; \
376 \
377 while (m < n && *dst) { m++; dst++; } \
378 if (m < n) { \
379 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
380 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
381 *dst = 0; \
382 } else { \
383 /* No space to copy anything to dst. m == n */ \
384 } \
385 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
386 while (*src) { m++; src++; } \
387 /* This checks for overlap after copying, unavoidable without */ \
388 /* pre-counting lengths... should be ok */ \
389 if (is_overlap(dst_orig, \
390 src_orig, \
391 (Addr)dst-(Addr)dst_orig+1, \
392 (Addr)src-(Addr)src_orig+1)) \
393 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
394 \
395 return m; \
396 }
397
398#if defined(VGO_linux)
399
400#elif defined(VGO_darwin)
401 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
402 //STRLCAT(VG_Z_DYLD, strlcat)
403 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
404
sewardj8eb8bab2015-07-21 14:44:28 +0000405#elif defined(VGO_solaris)
406 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
407
bart9c7779b2013-11-24 17:48:13 +0000408#endif
409
410
411/*---------------------- strnlen ----------------------*/
412
413#define STRNLEN(soname, fnname) \
414 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
415 ( const char* str, SizeT n ); \
416 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
417 ( const char* str, SizeT n ) \
418 { \
419 SizeT i = 0; \
420 while (i < n && str[i] != 0) i++; \
421 return i; \
422 }
423
424#if defined(VGO_linux)
425 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
426 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
427
428#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000429# if DARWIN_VERS == DARWIN_10_9
430 STRNLEN(libsystemZucZddylib, strnlen)
431# endif
bart9c7779b2013-11-24 17:48:13 +0000432
sewardj8eb8bab2015-07-21 14:44:28 +0000433#elif defined(VGO_solaris)
434 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
435
bart9c7779b2013-11-24 17:48:13 +0000436#endif
437
438
439/*---------------------- strlen ----------------------*/
440
441// Note that this replacement often doesn't get used because gcc inlines
442// calls to strlen() with its own built-in version. This can be very
443// confusing if you aren't expecting it. Other small functions in
444// this file may also be inline by gcc.
445
446#define STRLEN(soname, fnname) \
447 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
448 ( const char* str ); \
449 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
450 ( const char* str ) \
451 { \
452 SizeT i = 0; \
453 while (str[i] != 0) i++; \
454 return i; \
455 }
456
457#if defined(VGO_linux)
458 STRLEN(VG_Z_LIBC_SONAME, strlen)
459 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
460 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
461 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
462 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
463 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
464 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
sewardj26ed4192014-11-04 17:44:21 +0000465# if defined(VGPV_arm_linux_android) \
466 || defined(VGPV_x86_linux_android) \
dejanj9c6b05d2013-12-27 09:06:55 +0000467 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000468 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
469# endif
470
471#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000472 STRLEN(VG_Z_LIBC_SONAME, strlen)
rhyskidd9090d2f2015-07-08 13:46:57 +0000473# if DARWIN_VERS >= DARWIN_10_9
sewardjc3e09f62014-06-21 09:40:19 +0000474 STRLEN(libsystemZucZddylib, strlen)
475# endif
sewardj8eb8bab2015-07-21 14:44:28 +0000476
477#elif defined(VGO_solaris)
478 STRLEN(VG_Z_LIBC_SONAME, strlen)
479 STRLEN(VG_Z_LD_SO_1, strlen)
480
bart9c7779b2013-11-24 17:48:13 +0000481#endif
482
483
484/*---------------------- strcpy ----------------------*/
485
486#define STRCPY(soname, fnname) \
487 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
488 ( char* dst, const char* src ); \
489 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
490 ( char* dst, const char* src ) \
491 { \
492 const HChar* src_orig = src; \
493 HChar* dst_orig = dst; \
494 \
495 while (*src) *dst++ = *src++; \
496 *dst = 0; \
497 \
498 /* This checks for overlap after copying, unavoidable without */ \
499 /* pre-counting length... should be ok */ \
500 if (is_overlap(dst_orig, \
501 src_orig, \
502 (Addr)dst-(Addr)dst_orig+1, \
503 (Addr)src-(Addr)src_orig+1)) \
504 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
505 \
506 return dst_orig; \
507 }
508
509#if defined(VGO_linux)
510 STRCPY(VG_Z_LIBC_SONAME, strcpy)
511 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
512
513#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000514 STRCPY(VG_Z_LIBC_SONAME, strcpy)
sewardjaec49a42014-06-23 16:03:45 +0000515# if DARWIN_VERS == DARWIN_10_9
516 STRCPY(libsystemZucZddylib, strcpy)
517# endif
bart9c7779b2013-11-24 17:48:13 +0000518
sewardj8eb8bab2015-07-21 14:44:28 +0000519#elif defined(VGO_solaris)
520 STRCPY(VG_Z_LIBC_SONAME, strcpy)
521 STRCPY(VG_Z_LD_SO_1, strcpy)
522
bart9c7779b2013-11-24 17:48:13 +0000523#endif
524
525
526/*---------------------- strncpy ----------------------*/
527
528#define STRNCPY(soname, fnname) \
529 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
530 ( char* dst, const char* src, SizeT n ); \
531 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
532 ( char* dst, const char* src, SizeT n ) \
533 { \
534 const HChar* src_orig = src; \
535 HChar* dst_orig = dst; \
536 SizeT m = 0; \
537 \
538 while (m < n && *src) { m++; *dst++ = *src++; } \
539 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
540 /* but only m+1 bytes of src if terminator was found */ \
541 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
542 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
543 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
544 \
545 return dst_orig; \
546 }
547
548#if defined(VGO_linux)
549 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
550 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
551 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
552 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
553
554#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000555 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
rhyskidd9090d2f2015-07-08 13:46:57 +0000556# if DARWIN_VERS >= DARWIN_10_9
sewardjaec49a42014-06-23 16:03:45 +0000557 STRNCPY(libsystemZucZddylib, strncpy)
558# endif
bart9c7779b2013-11-24 17:48:13 +0000559
sewardj8eb8bab2015-07-21 14:44:28 +0000560#elif defined(VGO_solaris)
561 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
562 STRNCPY(VG_Z_LD_SO_1, strncpy)
563
bart9c7779b2013-11-24 17:48:13 +0000564#endif
565
566
567/*---------------------- strlcpy ----------------------*/
568
569/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
570 Returns strlen(src). Does not zero-fill the remainder of dst. */
571#define STRLCPY(soname, fnname) \
572 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
573 ( char* dst, const char* src, SizeT n ); \
574 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
575 ( char* dst, const char* src, SizeT n ) \
576 { \
577 const HChar* src_orig = src; \
578 HChar* dst_orig = dst; \
579 SizeT m = 0; \
580 \
sewardj8eb8bab2015-07-21 14:44:28 +0000581 STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
582 \
bart9c7779b2013-11-24 17:48:13 +0000583 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
584 /* m non-nul bytes have now been copied, and m <= n-1. */ \
585 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
586 /* but only m+1 bytes of src if terminator was found */ \
587 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
588 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
589 /* Nul-terminate dst. */ \
590 if (n > 0) *dst = 0; \
591 /* Finish counting strlen(src). */ \
592 while (*src) src++; \
593 return src - src_orig; \
594 }
595
596#if defined(VGO_linux)
597
dejanj9c6b05d2013-12-27 09:06:55 +0000598#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
599 || defined(VGPV_mips32_linux_android)
sewardj8eb8bab2015-07-21 14:44:28 +0000600 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
bart9c7779b2013-11-24 17:48:13 +0000601 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
602#endif
603
604#elif defined(VGO_darwin)
sewardj8eb8bab2015-07-21 14:44:28 +0000605 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
bart9c7779b2013-11-24 17:48:13 +0000606 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
607 //STRLCPY(VG_Z_DYLD, strlcpy)
608 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
609
sewardj8eb8bab2015-07-21 14:44:28 +0000610#elif defined(VGO_solaris)
611 /* special case for n == 0 which is undocumented but heavily used */
612 #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
613 if (n == 0) { \
614 while (*src) src++; \
615 return src - src_orig; \
616 }
617
618 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
619
bart9c7779b2013-11-24 17:48:13 +0000620#endif
621
622
623/*---------------------- strncmp ----------------------*/
624
625#define STRNCMP(soname, fnname) \
626 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
627 ( const char* s1, const char* s2, SizeT nmax ); \
628 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
629 ( const char* s1, const char* s2, SizeT nmax ) \
630 { \
631 SizeT n = 0; \
632 while (True) { \
633 if (n >= nmax) return 0; \
634 if (*s1 == 0 && *s2 == 0) return 0; \
635 if (*s1 == 0) return -1; \
636 if (*s2 == 0) return 1; \
637 \
638 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
639 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
640 \
641 s1++; s2++; n++; \
642 } \
643 }
644
645#if defined(VGO_linux)
646 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
647 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
648 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
649 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
650
651#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000652 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
rhyskidd9090d2f2015-07-08 13:46:57 +0000653# if DARWIN_VERS >= DARWIN_10_9
sewardj798e95b2014-06-25 11:17:46 +0000654 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
655# endif
bart9c7779b2013-11-24 17:48:13 +0000656
sewardj8eb8bab2015-07-21 14:44:28 +0000657#elif defined(VGO_solaris)
658 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
659
bart9c7779b2013-11-24 17:48:13 +0000660#endif
661
662
663/*---------------------- strcasecmp ----------------------*/
664
665#define STRCASECMP(soname, fnname) \
666 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
667 ( const char* s1, const char* s2 ); \
668 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
669 ( const char* s1, const char* s2 ) \
670 { \
671 extern int tolower(int); \
672 register UChar c1; \
673 register UChar c2; \
674 while (True) { \
675 c1 = tolower(*(const UChar *)s1); \
676 c2 = tolower(*(const UChar *)s2); \
677 if (c1 != c2) break; \
678 if (c1 == 0) break; \
679 s1++; s2++; \
680 } \
681 if ((UChar)c1 < (UChar)c2) return -1; \
682 if ((UChar)c1 > (UChar)c2) return 1; \
683 return 0; \
684 }
685
686#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000687# if !defined(VGPV_arm_linux_android) \
688 && !defined(VGPV_x86_linux_android) \
689 && !defined(VGPV_mips32_linux_android) \
690 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000691 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
692 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
693# endif
694
695#elif defined(VGO_darwin)
696 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
697
sewardj8eb8bab2015-07-21 14:44:28 +0000698#elif defined(VGO_solaris)
699 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
700
bart9c7779b2013-11-24 17:48:13 +0000701#endif
702
703
704/*---------------------- strncasecmp ----------------------*/
705
706#define STRNCASECMP(soname, fnname) \
707 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
708 ( const char* s1, const char* s2, SizeT nmax ); \
709 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
710 ( const char* s1, const char* s2, SizeT nmax ) \
711 { \
712 extern int tolower(int); \
713 SizeT n = 0; \
714 while (True) { \
715 if (n >= nmax) return 0; \
716 if (*s1 == 0 && *s2 == 0) return 0; \
717 if (*s1 == 0) return -1; \
718 if (*s2 == 0) return 1; \
719 \
720 if (tolower(*(const UChar *)s1) \
721 < tolower(*(const UChar*)s2)) return -1; \
722 if (tolower(*(const UChar *)s1) \
723 > tolower(*(const UChar *)s2)) return 1; \
724 \
725 s1++; s2++; n++; \
726 } \
727 }
728
729#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000730# if !defined(VGPV_arm_linux_android) \
731 && !defined(VGPV_x86_linux_android) \
732 && !defined(VGPV_mips32_linux_android) \
733 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000734 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
735 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
736# endif
737
738#elif defined(VGO_darwin)
739 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
740 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
741
sewardj8eb8bab2015-07-21 14:44:28 +0000742#elif defined(VGO_solaris)
743 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
744
bart9c7779b2013-11-24 17:48:13 +0000745#endif
746
747
748/*---------------------- strcasecmp_l ----------------------*/
749
750#define STRCASECMP_L(soname, fnname) \
751 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
752 ( const char* s1, const char* s2, void* locale ); \
753 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
754 ( const char* s1, const char* s2, void* locale ) \
755 { \
756 extern int tolower_l(int, void*) __attribute__((weak)); \
757 register UChar c1; \
758 register UChar c2; \
759 while (True) { \
760 c1 = tolower_l(*(const UChar *)s1, locale); \
761 c2 = tolower_l(*(const UChar *)s2, locale); \
762 if (c1 != c2) break; \
763 if (c1 == 0) break; \
764 s1++; s2++; \
765 } \
766 if ((UChar)c1 < (UChar)c2) return -1; \
767 if ((UChar)c1 > (UChar)c2) return 1; \
768 return 0; \
769 }
770
771#if defined(VGO_linux)
772 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
773 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
774 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
775
776#elif defined(VGO_darwin)
777 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
778
sewardj8eb8bab2015-07-21 14:44:28 +0000779#elif defined(VGO_solaris)
780
bart9c7779b2013-11-24 17:48:13 +0000781#endif
782
783
784/*---------------------- strncasecmp_l ----------------------*/
785
786#define STRNCASECMP_L(soname, fnname) \
787 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
788 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
789 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
790 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
791 { \
792 extern int tolower_l(int, void*) __attribute__((weak)); \
793 SizeT n = 0; \
794 while (True) { \
795 if (n >= nmax) return 0; \
796 if (*s1 == 0 && *s2 == 0) return 0; \
797 if (*s1 == 0) return -1; \
798 if (*s2 == 0) return 1; \
799 \
800 if (tolower_l(*(const UChar *)s1, locale) \
801 < tolower_l(*(const UChar *)s2, locale)) return -1; \
802 if (tolower_l(*(const UChar *)s1, locale) \
803 > tolower_l(*(const UChar *)s2, locale)) return 1; \
804 \
805 s1++; s2++; n++; \
806 } \
807 }
808
809#if defined(VGO_linux)
810 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
811 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
812 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
813
814#elif defined(VGO_darwin)
815 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
816 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
817
sewardj8eb8bab2015-07-21 14:44:28 +0000818#elif defined(VGO_solaris)
819
bart9c7779b2013-11-24 17:48:13 +0000820#endif
821
822
823/*---------------------- strcmp ----------------------*/
824
825#define STRCMP(soname, fnname) \
826 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
827 ( const char* s1, const char* s2 ); \
828 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
829 ( const char* s1, const char* s2 ) \
830 { \
831 register UChar c1; \
832 register UChar c2; \
833 while (True) { \
834 c1 = *(const UChar *)s1; \
835 c2 = *(const UChar *)s2; \
836 if (c1 != c2) break; \
837 if (c1 == 0) break; \
838 s1++; s2++; \
839 } \
840 if ((UChar)c1 < (UChar)c2) return -1; \
841 if ((UChar)c1 > (UChar)c2) return 1; \
842 return 0; \
843 }
844
845#if defined(VGO_linux)
846 STRCMP(VG_Z_LIBC_SONAME, strcmp)
847 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
848 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
849 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
850 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
851 STRCMP(VG_Z_LD64_SO_1, strcmp)
dejanj9c6b05d2013-12-27 09:06:55 +0000852# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
853 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000854 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
855# endif
856
857#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000858 STRCMP(VG_Z_LIBC_SONAME, strcmp)
rhyskidd9090d2f2015-07-08 13:46:57 +0000859# if DARWIN_VERS >= DARWIN_10_9
sewardjc3e09f62014-06-21 09:40:19 +0000860 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
861# endif
bart9c7779b2013-11-24 17:48:13 +0000862
sewardj8eb8bab2015-07-21 14:44:28 +0000863#elif defined(VGO_solaris)
864 STRCMP(VG_Z_LIBC_SONAME, strcmp)
865 STRCMP(VG_Z_LD_SO_1, strcmp)
866
bart9c7779b2013-11-24 17:48:13 +0000867#endif
868
869
870/*---------------------- memchr ----------------------*/
871
872#define MEMCHR(soname, fnname) \
873 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
874 (const void *s, int c, SizeT n); \
875 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
876 (const void *s, int c, SizeT n) \
877 { \
878 SizeT i; \
879 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000880 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000881 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000882 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
bart9c7779b2013-11-24 17:48:13 +0000883 return NULL; \
884 }
885
886#if defined(VGO_linux)
887 MEMCHR(VG_Z_LIBC_SONAME, memchr)
888 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
889
890#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000891# if DARWIN_VERS == DARWIN_10_9
sewardj798e95b2014-06-25 11:17:46 +0000892 MEMCHR(VG_Z_DYLD, memchr)
sewardjaec49a42014-06-23 16:03:45 +0000893 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
894# endif
rhyskidd9090d2f2015-07-08 13:46:57 +0000895# if DARWIN_VERS >= DARWIN_10_10
sewardja95abea2014-11-19 09:14:07 +0000896 MEMCHR(VG_Z_DYLD, memchr)
sewardj312bcb12014-11-07 00:08:13 +0000897 /* _platform_memchr$VARIANT$Generic */
898 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
rhyskidde4fcda32015-08-29 07:42:40 +0000899 /* _platform_memchr$VARIANT$Haswell */
900 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
sewardj312bcb12014-11-07 00:08:13 +0000901# endif
bart9c7779b2013-11-24 17:48:13 +0000902
sewardj8eb8bab2015-07-21 14:44:28 +0000903#elif defined(VGO_solaris)
904 MEMCHR(VG_Z_LIBC_SONAME, memchr)
905
bart9c7779b2013-11-24 17:48:13 +0000906#endif
907
908
909/*---------------------- memrchr ----------------------*/
910
911#define MEMRCHR(soname, fnname) \
912 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
913 (const void *s, int c, SizeT n); \
914 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
915 (const void *s, int c, SizeT n) \
916 { \
917 SizeT i; \
918 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000919 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000920 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000921 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
bart9c7779b2013-11-24 17:48:13 +0000922 return NULL; \
923 }
924
925#if defined(VGO_linux)
926 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
927
928#elif defined(VGO_darwin)
929 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
930 //MEMRCHR(VG_Z_DYLD, memrchr)
931
sewardj8eb8bab2015-07-21 14:44:28 +0000932#elif defined(VGO_solaris)
933
bart9c7779b2013-11-24 17:48:13 +0000934#endif
935
936
937/*---------------------- memcpy ----------------------*/
938
939#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
940 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
941 ( void *dst, const void *src, SizeT len ); \
942 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
943 ( void *dst, const void *src, SizeT len ) \
944 { \
945 if (do_ol_check && is_overlap(dst, src, len, len)) \
946 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
947 \
948 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
949 const Addr WM = WS - 1; /* 7 or 3 */ \
950 \
951 if (len > 0) { \
952 if (dst < src || !is_overlap(dst, src, len, len)) { \
953 \
954 /* Copying backwards. */ \
955 SizeT n = len; \
956 Addr d = (Addr)dst; \
957 Addr s = (Addr)src; \
958 \
959 if (((s^d) & WM) == 0) { \
960 /* s and d have same UWord alignment. */ \
961 /* Pull up to a UWord boundary. */ \
962 while ((s & WM) != 0 && n >= 1) \
963 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
964 /* Copy UWords. */ \
965 while (n >= WS) \
966 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
967 if (n == 0) \
968 return dst; \
969 } \
970 if (((s|d) & 1) == 0) { \
971 /* Both are 16-aligned; copy what we can thusly. */ \
972 while (n >= 2) \
973 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
974 } \
975 /* Copy leftovers, or everything if misaligned. */ \
976 while (n >= 1) \
977 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
978 \
979 } else if (dst > src) { \
980 \
981 SizeT n = len; \
982 Addr d = ((Addr)dst) + n; \
983 Addr s = ((Addr)src) + n; \
984 \
985 /* Copying forwards. */ \
986 if (((s^d) & WM) == 0) { \
987 /* s and d have same UWord alignment. */ \
988 /* Back down to a UWord boundary. */ \
989 while ((s & WM) != 0 && n >= 1) \
990 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
991 /* Copy UWords. */ \
992 while (n >= WS) \
993 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
994 if (n == 0) \
995 return dst; \
996 } \
997 if (((s|d) & 1) == 0) { \
998 /* Both are 16-aligned; copy what we can thusly. */ \
999 while (n >= 2) \
1000 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
1001 } \
1002 /* Copy leftovers, or everything if misaligned. */ \
1003 while (n >= 1) \
1004 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
1005 \
1006 } \
1007 } \
1008 \
1009 return dst; \
1010 }
1011
1012#define MEMMOVE(soname, fnname) \
1013 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
1014
1015#define MEMCPY(soname, fnname) \
1016 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
1017
1018#if defined(VGO_linux)
1019 /* For older memcpy we have to use memmove-like semantics and skip
1020 the overlap check; sigh; see #275284. */
1021 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
1022 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
1023 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
1024 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
1025 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
1026 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
1027 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
1028 /* icc9 blats these around all over the place. Not only in the main
1029 executable but various .so's. They are highly tuned and read
1030 memory beyond the source boundary (although work correctly and
1031 never go across page boundaries), so give errors when run
1032 natively, at least for misaligned source arg. Just intercepting
1033 in the exe only until we understand more about the problem. See
1034 http://bugs.kde.org/show_bug.cgi?id=139776
1035 */
1036 MEMCPY(NONE, ZuintelZufastZumemcpy)
1037
1038#elif defined(VGO_darwin)
1039# if DARWIN_VERS <= DARWIN_10_6
1040 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
1041# endif
1042 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
1043 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
1044
sewardj8eb8bab2015-07-21 14:44:28 +00001045#elif defined(VGO_solaris)
1046 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
Elliott Hughesed398002017-06-21 14:41:24 -07001047 MEMCPY(VG_Z_LIBC_SONAME, memcpyZPZa)
sewardj8eb8bab2015-07-21 14:44:28 +00001048 MEMCPY(VG_Z_LD_SO_1, memcpy)
1049
bart9c7779b2013-11-24 17:48:13 +00001050#endif
1051
1052
1053/*---------------------- memcmp ----------------------*/
1054
1055#define MEMCMP(soname, fnname) \
1056 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1057 ( const void *s1V, const void *s2V, SizeT n ); \
1058 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
1059 ( const void *s1V, const void *s2V, SizeT n ) \
1060 { \
sewardj094b9912015-02-04 18:46:11 +00001061 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1062 const SizeT WM = WS - 1; /* 7 or 3 */ \
sewardj11e20f72015-02-04 17:52:42 +00001063 Addr s1A = (Addr)s1V; \
1064 Addr s2A = (Addr)s2V; \
1065 \
1066 if (((s1A | s2A) & WM) == 0) { \
1067 /* Both areas are word aligned. Skip over the */ \
1068 /* equal prefix as fast as possible. */ \
1069 while (n >= WS) { \
1070 UWord w1 = *(UWord*)s1A; \
1071 UWord w2 = *(UWord*)s2A; \
1072 if (w1 != w2) break; \
1073 s1A += WS; \
1074 s2A += WS; \
1075 n -= WS; \
1076 } \
1077 } \
1078 \
1079 const UChar* s1 = (const UChar*) s1A; \
1080 const UChar* s2 = (const UChar*) s2A; \
bart9c7779b2013-11-24 17:48:13 +00001081 \
1082 while (n != 0) { \
sewardj11e20f72015-02-04 17:52:42 +00001083 UChar a0 = s1[0]; \
1084 UChar b0 = s2[0]; \
bart9c7779b2013-11-24 17:48:13 +00001085 s1 += 1; \
1086 s2 += 1; \
sewardj11e20f72015-02-04 17:52:42 +00001087 int res = ((int)a0) - ((int)b0); \
bart9c7779b2013-11-24 17:48:13 +00001088 if (res != 0) \
1089 return res; \
1090 n -= 1; \
1091 } \
1092 return 0; \
1093 }
1094
1095#if defined(VGO_linux)
1096 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1097 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
1098 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1099 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1100 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1101 MEMCMP(VG_Z_LD_SO_1, bcmp)
1102
1103#elif defined(VGO_darwin)
rhyskidd9090d2f2015-07-08 13:46:57 +00001104# if DARWIN_VERS >= DARWIN_10_9
sewardjaec49a42014-06-23 16:03:45 +00001105 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1106# endif
bart9c7779b2013-11-24 17:48:13 +00001107
sewardj8eb8bab2015-07-21 14:44:28 +00001108#elif defined(VGO_solaris)
1109 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
1110 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1111 MEMCMP(VG_Z_LD_SO_1, memcmp)
1112
bart9c7779b2013-11-24 17:48:13 +00001113#endif
1114
1115
1116/*---------------------- stpcpy ----------------------*/
1117
1118/* Copy SRC to DEST, returning the address of the terminating '\0' in
1119 DEST. (minor variant of strcpy) */
1120#define STPCPY(soname, fnname) \
1121 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1122 ( char* dst, const char* src ); \
1123 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1124 ( char* dst, const char* src ) \
1125 { \
1126 const HChar* src_orig = src; \
1127 HChar* dst_orig = dst; \
1128 \
1129 while (*src) *dst++ = *src++; \
1130 *dst = 0; \
1131 \
1132 /* This checks for overlap after copying, unavoidable without */ \
1133 /* pre-counting length... should be ok */ \
1134 if (is_overlap(dst_orig, \
1135 src_orig, \
1136 (Addr)dst-(Addr)dst_orig+1, \
1137 (Addr)src-(Addr)src_orig+1)) \
1138 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1139 \
1140 return dst; \
1141 }
1142
1143#if defined(VGO_linux)
1144 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1145 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1146 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1147 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1148 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1149 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1150
1151#elif defined(VGO_darwin)
1152 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1153 //STPCPY(VG_Z_DYLD, stpcpy)
1154
sewardj8eb8bab2015-07-21 14:44:28 +00001155#elif defined(VGO_solaris)
1156 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1157
bart9c7779b2013-11-24 17:48:13 +00001158#endif
1159
1160
1161/*---------------------- stpncpy ----------------------*/
1162
1163#define STPNCPY(soname, fnname) \
1164 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1165 ( char* dst, const char* src, SizeT n ); \
1166 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1167 ( char* dst, const char* src, SizeT n ) \
1168 { \
1169 const HChar* src_orig = src; \
1170 HChar* dst_str = dst; \
1171 SizeT m = 0; \
1172 \
1173 while (m < n && *src) { m++; *dst++ = *src++; } \
1174 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1175 /* but only m+1 bytes of src if terminator was found */ \
1176 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1177 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1178 dst_str = dst; \
1179 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1180 \
1181 return dst_str; \
1182 }
1183
1184#if defined(VGO_linux)
1185 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1186#endif
1187
1188
1189/*---------------------- memset ----------------------*/
1190
1191/* Why are we bothering to intercept this? It seems entirely
1192 pointless. */
1193
1194#define MEMSET(soname, fnname) \
Elliott Hughesed398002017-06-21 14:41:24 -07001195 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
bart9c7779b2013-11-24 17:48:13 +00001196 (void *s, Int c, SizeT n); \
Elliott Hughesed398002017-06-21 14:41:24 -07001197 void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
bart9c7779b2013-11-24 17:48:13 +00001198 (void *s, Int c, SizeT n) \
1199 { \
1200 if (sizeof(void*) == 8) { \
1201 Addr a = (Addr)s; \
1202 ULong c8 = (c & 0xFF); \
1203 c8 = (c8 << 8) | c8; \
1204 c8 = (c8 << 16) | c8; \
1205 c8 = (c8 << 32) | c8; \
1206 while ((a & 7) != 0 && n >= 1) \
1207 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
Elliott Hughesa0664b92017-04-18 17:46:52 -07001208 while (n >= 32) \
1209 { *(ULong*)a = c8; a += 8; n -= 8; \
1210 *(ULong*)a = c8; a += 8; n -= 8; \
1211 *(ULong*)a = c8; a += 8; n -= 8; \
1212 *(ULong*)a = c8; a += 8; n -= 8; } \
bart9c7779b2013-11-24 17:48:13 +00001213 while (n >= 8) \
1214 { *(ULong*)a = c8; a += 8; n -= 8; } \
1215 while (n >= 1) \
1216 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1217 return s; \
1218 } else { \
1219 Addr a = (Addr)s; \
1220 UInt c4 = (c & 0xFF); \
1221 c4 = (c4 << 8) | c4; \
1222 c4 = (c4 << 16) | c4; \
1223 while ((a & 3) != 0 && n >= 1) \
1224 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
Elliott Hughesa0664b92017-04-18 17:46:52 -07001225 while (n >= 16) \
1226 { *(UInt*)a = c4; a += 4; n -= 4; \
1227 *(UInt*)a = c4; a += 4; n -= 4; \
1228 *(UInt*)a = c4; a += 4; n -= 4; \
1229 *(UInt*)a = c4; a += 4; n -= 4; } \
bart9c7779b2013-11-24 17:48:13 +00001230 while (n >= 4) \
1231 { *(UInt*)a = c4; a += 4; n -= 4; } \
1232 while (n >= 1) \
1233 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1234 return s; \
1235 } \
1236 }
1237
1238#if defined(VGO_linux)
1239 MEMSET(VG_Z_LIBC_SONAME, memset)
1240
1241#elif defined(VGO_darwin)
1242 //MEMSET(VG_Z_LIBC_SONAME, memset)
1243 //MEMSET(VG_Z_DYLD, memset)
1244 MEMSET(VG_Z_LIBC_SONAME, memset)
1245
sewardj8eb8bab2015-07-21 14:44:28 +00001246#elif defined(VGO_solaris)
1247 MEMSET(VG_Z_LIBC_SONAME, memset)
Elliott Hughesed398002017-06-21 14:41:24 -07001248 MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
sewardj8eb8bab2015-07-21 14:44:28 +00001249
bart9c7779b2013-11-24 17:48:13 +00001250#endif
1251
1252
1253/*---------------------- memmove ----------------------*/
1254
1255/* memmove -- use the MEMMOVE defn above. */
1256
1257#if defined(VGO_linux)
1258 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1259 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
mjwb97cf8e2015-07-07 13:01:39 +00001260 /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1261 arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1262 to call memcpy. */
1263 MEMMOVE(VG_Z_LD64_SO_1, memmove)
bart9c7779b2013-11-24 17:48:13 +00001264
1265#elif defined(VGO_darwin)
1266# if DARWIN_VERS <= DARWIN_10_6
1267 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1268# endif
1269 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1270 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
rhyskidd9090d2f2015-07-08 13:46:57 +00001271# if DARWIN_VERS >= DARWIN_10_9
sewardj312bcb12014-11-07 00:08:13 +00001272 /* _platform_memmove$VARIANT$Ivybridge */
sewardjeb86dda2014-10-17 15:07:37 +00001273 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1274# endif
sewardj8eb8bab2015-07-21 14:44:28 +00001275
1276#elif defined(VGO_solaris)
1277 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
Elliott Hughesed398002017-06-21 14:41:24 -07001278 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
sewardj8eb8bab2015-07-21 14:44:28 +00001279 MEMMOVE(VG_Z_LD_SO_1, memmove)
1280
bart9c7779b2013-11-24 17:48:13 +00001281#endif
1282
1283
1284/*---------------------- bcopy ----------------------*/
1285
1286#define BCOPY(soname, fnname) \
1287 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1288 (const void *srcV, void *dstV, SizeT n); \
1289 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1290 (const void *srcV, void *dstV, SizeT n) \
1291 { \
1292 SizeT i; \
1293 HChar* dst = dstV; \
1294 const HChar* src = srcV; \
1295 if (dst < src) { \
1296 for (i = 0; i < n; i++) \
1297 dst[i] = src[i]; \
1298 } \
1299 else \
1300 if (dst > src) { \
1301 for (i = 0; i < n; i++) \
1302 dst[n-i-1] = src[n-i-1]; \
1303 } \
1304 }
1305
1306#if defined(VGO_linux)
1307 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1308
1309#elif defined(VGO_darwin)
1310 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1311 //BCOPY(VG_Z_DYLD, bcopy)
1312
sewardj8eb8bab2015-07-21 14:44:28 +00001313#elif defined(VGO_darwin)
1314 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1315
bart9c7779b2013-11-24 17:48:13 +00001316#endif
1317
1318
1319/*-------------------- memmove_chk --------------------*/
1320
1321/* glibc 2.5 variant of memmove which checks the dest is big enough.
1322 There is no specific part of glibc that this is copied from. */
1323#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1324 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1325 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1326 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1327 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1328 { \
1329 SizeT i; \
1330 HChar* dst = dstV; \
1331 const HChar* src = srcV; \
1332 if (destlen < n) \
1333 goto badness; \
1334 if (dst < src) { \
1335 for (i = 0; i < n; i++) \
1336 dst[i] = src[i]; \
1337 } \
1338 else \
1339 if (dst > src) { \
1340 for (i = 0; i < n; i++) \
1341 dst[n-i-1] = src[n-i-1]; \
1342 } \
1343 return dst; \
1344 badness: \
1345 VALGRIND_PRINTF_BACKTRACE( \
1346 "*** memmove_chk: buffer overflow detected ***: " \
1347 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001348 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001349 /*NOTREACHED*/ \
1350 return NULL; \
1351 }
1352
1353#if defined(VGO_linux)
1354 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1355
1356#elif defined(VGO_darwin)
1357
sewardj8eb8bab2015-07-21 14:44:28 +00001358#elif defined(VGO_solaris)
1359
bart9c7779b2013-11-24 17:48:13 +00001360#endif
1361
1362
1363/*-------------------- strchrnul --------------------*/
1364
1365/* Find the first occurrence of C in S or the final NUL byte. */
1366#define GLIBC232_STRCHRNUL(soname, fnname) \
1367 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1368 (const char* s, int c_in); \
1369 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1370 (const char* s, int c_in) \
1371 { \
florian70a5de12014-10-22 12:53:16 +00001372 HChar c = (HChar) c_in; \
1373 const HChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001374 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001375 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1376 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001377 char_ptr++; \
1378 } \
1379 }
1380
1381#if defined(VGO_linux)
1382 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1383
1384#elif defined(VGO_darwin)
1385
sewardj8eb8bab2015-07-21 14:44:28 +00001386#elif defined(VGO_solaris)
1387
bart9c7779b2013-11-24 17:48:13 +00001388#endif
1389
1390
1391/*---------------------- rawmemchr ----------------------*/
1392
1393/* Find the first occurrence of C in S. */
1394#define GLIBC232_RAWMEMCHR(soname, fnname) \
florian1ef205b2014-10-22 12:06:22 +00001395 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1396 (const void* s, int c_in); \
1397 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1398 (const void* s, int c_in) \
bart9c7779b2013-11-24 17:48:13 +00001399 { \
florian1ef205b2014-10-22 12:06:22 +00001400 UChar c = (UChar) c_in; \
1401 const UChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001402 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001403 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001404 char_ptr++; \
1405 } \
1406 }
1407
1408#if defined (VGO_linux)
1409 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1410 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1411
1412#elif defined(VGO_darwin)
1413
sewardj8eb8bab2015-07-21 14:44:28 +00001414#elif defined(VGO_solaris)
1415
bart9c7779b2013-11-24 17:48:13 +00001416#endif
1417
1418
1419/*---------------------- strcpy_chk ----------------------*/
1420
1421/* glibc variant of strcpy that checks the dest is big enough.
1422 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1423#define GLIBC25___STRCPY_CHK(soname,fnname) \
1424 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1425 (char* dst, const char* src, SizeT len); \
1426 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1427 (char* dst, const char* src, SizeT len) \
1428 { \
1429 HChar* ret = dst; \
1430 if (! len) \
1431 goto badness; \
1432 while ((*dst++ = *src++) != '\0') \
1433 if (--len == 0) \
1434 goto badness; \
1435 return ret; \
1436 badness: \
1437 VALGRIND_PRINTF_BACKTRACE( \
1438 "*** strcpy_chk: buffer overflow detected ***: " \
1439 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001440 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001441 /*NOTREACHED*/ \
1442 return NULL; \
1443 }
1444
1445#if defined(VGO_linux)
1446 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1447
1448#elif defined(VGO_darwin)
1449
sewardj8eb8bab2015-07-21 14:44:28 +00001450#elif defined(VGO_solaris)
1451
bart9c7779b2013-11-24 17:48:13 +00001452#endif
1453
1454
1455/*---------------------- stpcpy_chk ----------------------*/
1456
1457/* glibc variant of stpcpy that checks the dest is big enough.
1458 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1459#define GLIBC25___STPCPY_CHK(soname,fnname) \
1460 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1461 (char* dst, const char* src, SizeT len); \
1462 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1463 (char* dst, const char* src, SizeT len) \
1464 { \
1465 if (! len) \
1466 goto badness; \
1467 while ((*dst++ = *src++) != '\0') \
1468 if (--len == 0) \
1469 goto badness; \
1470 return dst - 1; \
1471 badness: \
1472 VALGRIND_PRINTF_BACKTRACE( \
1473 "*** stpcpy_chk: buffer overflow detected ***: " \
1474 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001475 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001476 /*NOTREACHED*/ \
1477 return NULL; \
1478 }
1479
1480#if defined(VGO_linux)
1481 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1482
1483#elif defined(VGO_darwin)
1484
sewardj8eb8bab2015-07-21 14:44:28 +00001485#elif defined(VGO_solaris)
1486
bart9c7779b2013-11-24 17:48:13 +00001487#endif
1488
1489
1490/*---------------------- mempcpy ----------------------*/
1491
1492/* mempcpy */
1493#define GLIBC25_MEMPCPY(soname, fnname) \
1494 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1495 ( void *dst, const void *src, SizeT len ); \
1496 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1497 ( void *dst, const void *src, SizeT len ) \
1498 { \
bart9c7779b2013-11-24 17:48:13 +00001499 SizeT len_saved = len; \
1500 \
1501 if (len == 0) \
1502 return dst; \
1503 \
1504 if (is_overlap(dst, src, len, len)) \
1505 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1506 \
1507 if ( dst > src ) { \
florian09041e42014-10-21 17:15:14 +00001508 register HChar *d = (char *)dst + len - 1; \
1509 register const HChar *s = (const char *)src + len - 1; \
bart9c7779b2013-11-24 17:48:13 +00001510 while ( len-- ) { \
1511 *d-- = *s--; \
1512 } \
1513 } else if ( dst < src ) { \
florian09041e42014-10-21 17:15:14 +00001514 register HChar *d = dst; \
1515 register const HChar *s = src; \
bart9c7779b2013-11-24 17:48:13 +00001516 while ( len-- ) { \
1517 *d++ = *s++; \
1518 } \
1519 } \
1520 return (void*)( ((char*)dst) + len_saved ); \
1521 }
1522
1523#if defined(VGO_linux)
1524 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
mjwa9176d92015-01-13 16:10:20 +00001525 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
bart9c7779b2013-11-24 17:48:13 +00001526 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
bartf2d86632014-03-15 12:47:28 +00001527 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1528 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
bart9c7779b2013-11-24 17:48:13 +00001529
1530#elif defined(VGO_darwin)
1531 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1532
sewardj8eb8bab2015-07-21 14:44:28 +00001533#elif defined(VGO_solaris)
1534
bart9c7779b2013-11-24 17:48:13 +00001535#endif
1536
1537
1538/*-------------------- memcpy_chk --------------------*/
1539
1540#define GLIBC26___MEMCPY_CHK(soname, fnname) \
1541 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1542 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1543 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1544 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1545 { \
1546 register HChar *d; \
1547 register const HChar *s; \
1548 \
1549 if (dstlen < len) goto badness; \
1550 \
1551 if (len == 0) \
1552 return dst; \
1553 \
1554 if (is_overlap(dst, src, len, len)) \
1555 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1556 \
1557 if ( dst > src ) { \
1558 d = (HChar *)dst + len - 1; \
1559 s = (const HChar *)src + len - 1; \
1560 while ( len-- ) { \
1561 *d-- = *s--; \
1562 } \
1563 } else if ( dst < src ) { \
1564 d = (HChar *)dst; \
1565 s = (const HChar *)src; \
1566 while ( len-- ) { \
1567 *d++ = *s++; \
1568 } \
1569 } \
1570 return dst; \
1571 badness: \
1572 VALGRIND_PRINTF_BACKTRACE( \
1573 "*** memcpy_chk: buffer overflow detected ***: " \
1574 "program terminated\n"); \
florian77ae9992015-08-09 20:29:18 +00001575 my_exit(1); \
bart9c7779b2013-11-24 17:48:13 +00001576 /*NOTREACHED*/ \
1577 return NULL; \
1578 }
1579
1580#if defined(VGO_linux)
1581 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1582
1583#elif defined(VGO_darwin)
1584
sewardj8eb8bab2015-07-21 14:44:28 +00001585#elif defined(VGO_solaris)
1586
bart9c7779b2013-11-24 17:48:13 +00001587#endif
1588
1589
1590/*---------------------- strstr ----------------------*/
1591
1592#define STRSTR(soname, fnname) \
1593 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1594 (const char* haystack, const char* needle); \
1595 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1596 (const char* haystack, const char* needle) \
1597 { \
1598 const HChar* h = haystack; \
1599 const HChar* n = needle; \
1600 \
1601 /* find the length of n, not including terminating zero */ \
1602 UWord nlen = 0; \
1603 while (n[nlen]) nlen++; \
1604 \
1605 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001606 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001607 \
1608 /* assert(nlen >= 1); */ \
1609 HChar n0 = n[0]; \
1610 \
1611 while (1) { \
1612 const HChar hh = *h; \
1613 if (hh == 0) return NULL; \
1614 if (hh != n0) { h++; continue; } \
1615 \
1616 UWord i; \
1617 for (i = 0; i < nlen; i++) { \
1618 if (n[i] != h[i]) \
1619 break; \
1620 } \
1621 /* assert(i >= 0 && i <= nlen); */ \
1622 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001623 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001624 \
1625 h++; \
1626 } \
1627 }
1628
1629#if defined(VGO_linux)
1630 STRSTR(VG_Z_LIBC_SONAME, strstr)
1631 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1632 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1633
1634#elif defined(VGO_darwin)
1635
sewardj8eb8bab2015-07-21 14:44:28 +00001636#elif defined(VGO_solaris)
1637 STRSTR(VG_Z_LIBC_SONAME, strstr)
1638
bart9c7779b2013-11-24 17:48:13 +00001639#endif
1640
1641
1642/*---------------------- strpbrk ----------------------*/
1643
1644#define STRPBRK(soname, fnname) \
1645 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1646 (const char* sV, const char* acceptV); \
1647 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1648 (const char* sV, const char* acceptV) \
1649 { \
1650 const HChar* s = sV; \
1651 const HChar* accept = acceptV; \
1652 \
1653 /* find the length of 'accept', not including terminating zero */ \
1654 UWord nacc = 0; \
1655 while (accept[nacc]) nacc++; \
1656 \
1657 /* if n is the empty string, fail immediately. */ \
1658 if (nacc == 0) return NULL; \
1659 \
1660 /* assert(nacc >= 1); */ \
1661 while (1) { \
1662 UWord i; \
1663 HChar sc = *s; \
1664 if (sc == 0) \
1665 break; \
1666 for (i = 0; i < nacc; i++) { \
1667 if (sc == accept[i]) \
florian70a5de12014-10-22 12:53:16 +00001668 return CONST_CAST(HChar *,s); \
bart9c7779b2013-11-24 17:48:13 +00001669 } \
1670 s++; \
1671 } \
1672 \
1673 return NULL; \
1674 }
1675
1676#if defined(VGO_linux)
1677 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1678
1679#elif defined(VGO_darwin)
1680
sewardj8eb8bab2015-07-21 14:44:28 +00001681#elif defined(VGO_solaris)
1682 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1683
bart9c7779b2013-11-24 17:48:13 +00001684#endif
1685
1686
1687/*---------------------- strcspn ----------------------*/
1688
1689#define STRCSPN(soname, fnname) \
1690 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1691 (const char* sV, const char* rejectV); \
1692 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1693 (const char* sV, const char* rejectV) \
1694 { \
1695 const HChar* s = sV; \
1696 const HChar* reject = rejectV; \
1697 \
1698 /* find the length of 'reject', not including terminating zero */ \
1699 UWord nrej = 0; \
1700 while (reject[nrej]) nrej++; \
1701 \
1702 UWord len = 0; \
1703 while (1) { \
1704 UWord i; \
1705 HChar sc = *s; \
1706 if (sc == 0) \
1707 break; \
1708 for (i = 0; i < nrej; i++) { \
1709 if (sc == reject[i]) \
1710 break; \
1711 } \
1712 /* assert(i >= 0 && i <= nrej); */ \
1713 if (i < nrej) \
1714 break; \
1715 s++; \
1716 len++; \
1717 } \
1718 \
1719 return len; \
1720 }
1721
1722#if defined(VGO_linux)
1723 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
Elliott Hughesed398002017-06-21 14:41:24 -07001724 STRCSPN(VG_Z_LIBC_SONAME, __GI_strcspn)
bart9c7779b2013-11-24 17:48:13 +00001725
1726#elif defined(VGO_darwin)
1727
sewardj8eb8bab2015-07-21 14:44:28 +00001728#elif defined(VGO_solaris)
1729 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1730
bart9c7779b2013-11-24 17:48:13 +00001731#endif
1732
1733
1734/*---------------------- strspn ----------------------*/
1735
1736#define STRSPN(soname, fnname) \
1737 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1738 (const char* sV, const char* acceptV); \
1739 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1740 (const char* sV, const char* acceptV) \
1741 { \
1742 const UChar* s = (const UChar *)sV; \
1743 const UChar* accept = (const UChar *)acceptV; \
1744 \
1745 /* find the length of 'accept', not including terminating zero */ \
1746 UWord nacc = 0; \
1747 while (accept[nacc]) nacc++; \
1748 if (nacc == 0) return 0; \
1749 \
1750 UWord len = 0; \
1751 while (1) { \
1752 UWord i; \
1753 HChar sc = *s; \
1754 if (sc == 0) \
1755 break; \
1756 for (i = 0; i < nacc; i++) { \
1757 if (sc == accept[i]) \
1758 break; \
1759 } \
1760 /* assert(i >= 0 && i <= nacc); */ \
1761 if (i == nacc) \
1762 break; \
1763 s++; \
1764 len++; \
1765 } \
1766 \
1767 return len; \
1768 }
1769
1770#if defined(VGO_linux)
1771 STRSPN(VG_Z_LIBC_SONAME, strspn)
1772
1773#elif defined(VGO_darwin)
1774
sewardj8eb8bab2015-07-21 14:44:28 +00001775#elif defined(VGO_solaris)
1776 STRSPN(VG_Z_LIBC_SONAME, strspn)
1777
bart9c7779b2013-11-24 17:48:13 +00001778#endif
1779
1780
1781/*---------------------- strcasestr ----------------------*/
1782
1783#define STRCASESTR(soname, fnname) \
1784 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1785 (const char* haystack, const char* needle); \
1786 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1787 (const char* haystack, const char* needle) \
1788 { \
1789 extern int tolower(int); \
1790 const HChar* h = haystack; \
1791 const HChar* n = needle; \
1792 \
1793 /* find the length of n, not including terminating zero */ \
1794 UWord nlen = 0; \
1795 while (n[nlen]) nlen++; \
1796 \
1797 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001798 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001799 \
1800 /* assert(nlen >= 1); */ \
1801 UChar n0 = tolower(n[0]); \
1802 \
1803 while (1) { \
1804 UChar hh = tolower(*h); \
1805 if (hh == 0) return NULL; \
1806 if (hh != n0) { h++; continue; } \
1807 \
1808 UWord i; \
1809 for (i = 0; i < nlen; i++) { \
1810 if (tolower(n[i]) != tolower(h[i])) \
1811 break; \
1812 } \
1813 /* assert(i >= 0 && i <= nlen); */ \
1814 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001815 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001816 \
1817 h++; \
1818 } \
1819 }
1820
1821#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +00001822# if !defined(VGPV_arm_linux_android) \
1823 && !defined(VGPV_x86_linux_android) \
1824 && !defined(VGPV_mips32_linux_android) \
1825 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +00001826 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1827# endif
1828
1829#elif defined(VGO_darwin)
1830
sewardj8eb8bab2015-07-21 14:44:28 +00001831#elif defined(VGO_solaris)
1832 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1833
bart9c7779b2013-11-24 17:48:13 +00001834#endif
1835
1836
1837/*---------------------- wcslen ----------------------*/
1838
1839// This is a wchar_t equivalent to strlen. Unfortunately
1840// we don't have wchar_t available here, but it looks like
1841// a 32 bit int on Linux. I don't know if that is also
1842// valid on MacOSX.
1843
1844#define WCSLEN(soname, fnname) \
1845 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1846 ( const UInt* str ); \
1847 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1848 ( const UInt* str ) \
1849 { \
1850 SizeT i = 0; \
1851 while (str[i] != 0) i++; \
1852 return i; \
1853 }
1854
1855#if defined(VGO_linux)
1856 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1857
1858#elif defined(VGO_darwin)
1859
sewardj8eb8bab2015-07-21 14:44:28 +00001860#elif defined(VGO_solaris)
1861 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1862
bart9c7779b2013-11-24 17:48:13 +00001863#endif
1864
1865/*---------------------- wcscmp ----------------------*/
1866
1867// This is a wchar_t equivalent to strcmp. We don't
1868// have wchar_t available here, but in the GNU C Library
1869// wchar_t is always 32 bits wide and wcscmp uses signed
1870// comparison, not unsigned as in strcmp function.
1871
1872#define WCSCMP(soname, fnname) \
1873 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1874 ( const Int* s1, const Int* s2 ); \
1875 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1876 ( const Int* s1, const Int* s2 ) \
1877 { \
1878 register Int c1; \
1879 register Int c2; \
1880 while (True) { \
1881 c1 = *s1; \
1882 c2 = *s2; \
1883 if (c1 != c2) break; \
1884 if (c1 == 0) break; \
1885 s1++; s2++; \
1886 } \
1887 if (c1 < c2) return -1; \
1888 if (c1 > c2) return 1; \
1889 return 0; \
1890 }
1891
1892#if defined(VGO_linux)
1893 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
1894#endif
1895
1896/*---------------------- wcscpy ----------------------*/
1897
1898// This is a wchar_t equivalent to strcpy. We don't
1899// have wchar_t available here, but in the GNU C Library
1900// wchar_t is always 32 bits wide.
1901
1902#define WCSCPY(soname, fnname) \
1903 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1904 ( Int* dst, const Int* src ); \
1905 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1906 ( Int* dst, const Int* src ) \
1907 { \
1908 const Int* src_orig = src; \
1909 Int* dst_orig = dst; \
1910 \
1911 while (*src) *dst++ = *src++; \
1912 *dst = 0; \
1913 \
1914 /* This checks for overlap after copying, unavoidable without */ \
1915 /* pre-counting length... should be ok */ \
1916 if (is_overlap(dst_orig, \
1917 src_orig, \
1918 (Addr)dst-(Addr)dst_orig+1, \
1919 (Addr)src-(Addr)src_orig+1)) \
1920 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1921 \
1922 return dst_orig; \
1923 }
1924
1925#if defined(VGO_linux)
1926 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
1927#endif
1928
1929
1930/*---------------------- wcschr ----------------------*/
1931
1932// This is a wchar_t equivalent to strchr. We don't
1933// have wchar_t available here, but in the GNU C Library
1934// wchar_t is always 32 bits wide.
1935
1936#define WCSCHR(soname, fnname) \
1937 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1938 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1939 { \
florian70a5de12014-10-22 12:53:16 +00001940 const Int* p = s; \
bart9c7779b2013-11-24 17:48:13 +00001941 while (True) { \
florian70a5de12014-10-22 12:53:16 +00001942 if (*p == c) return CONST_CAST(Int *,p); \
bart9c7779b2013-11-24 17:48:13 +00001943 if (*p == 0) return NULL; \
1944 p++; \
1945 } \
1946 }
1947
1948#if defined(VGO_linux)
1949 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
1950#endif
1951/*---------------------- wcsrchr ----------------------*/
1952
1953// This is a wchar_t equivalent to strrchr. We don't
1954// have wchar_t available here, but in the GNU C Library
1955// wchar_t is always 32 bits wide.
1956
1957#define WCSRCHR(soname, fnname) \
1958 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1959 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1960 { \
florian70a5de12014-10-22 12:53:16 +00001961 const Int* p = s; \
1962 const Int* last = NULL; \
bart9c7779b2013-11-24 17:48:13 +00001963 while (True) { \
1964 if (*p == c) last = p; \
florian70a5de12014-10-22 12:53:16 +00001965 if (*p == 0) return CONST_CAST(Int *,last); \
bart9c7779b2013-11-24 17:48:13 +00001966 p++; \
1967 } \
1968 }
1969
1970#if defined(VGO_linux)
1971 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
1972#endif
1973
1974/*------------------------------------------------------------*/
1975/*--- Improve definedness checking of process environment ---*/
1976/*------------------------------------------------------------*/
1977
1978#if defined(VGO_linux)
1979
1980/* If these wind up getting generated via a macro, so that multiple
1981 versions of each function exist (as above), use the _EZU variants
1982 to assign equivalance class tags. */
1983
1984/*---------------------- putenv ----------------------*/
1985
1986int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1987int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1988{
1989 OrigFn fn;
1990 Word result;
1991 const HChar* p = string;
1992 VALGRIND_GET_ORIG_FN(fn);
1993 /* Now by walking over the string we magically produce
1994 traces when hitting undefined memory. */
1995 if (p)
1996 while (*p++)
1997 __asm__ __volatile__("" ::: "memory");
1998 CALL_FN_W_W(result, fn, string);
1999 return result;
2000}
2001
2002
2003/*---------------------- unsetenv ----------------------*/
2004
2005int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
2006int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
2007{
2008 OrigFn fn;
2009 Word result;
2010 const HChar* p = name;
2011 VALGRIND_GET_ORIG_FN(fn);
2012 /* Now by walking over the string we magically produce
2013 traces when hitting undefined memory. */
2014 if (p)
2015 while (*p++)
2016 __asm__ __volatile__("" ::: "memory");
2017 CALL_FN_W_W(result, fn, name);
2018 return result;
2019}
2020
2021
2022/*---------------------- setenv ----------------------*/
2023
2024/* setenv */
2025int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2026 (const char* name, const char* value, int overwrite);
2027int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
2028 (const char* name, const char* value, int overwrite)
2029{
2030 OrigFn fn;
2031 Word result;
2032 const HChar* p;
2033 VALGRIND_GET_ORIG_FN(fn);
2034 /* Now by walking over the string we magically produce
2035 traces when hitting undefined memory. */
2036 if (name)
2037 for (p = name; *p; p++)
2038 __asm__ __volatile__("" ::: "memory");
2039 if (value)
2040 for (p = value; *p; p++)
2041 __asm__ __volatile__("" ::: "memory");
2042 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
2043 CALL_FN_W_WWW(result, fn, name, value, overwrite);
2044 return result;
2045}
2046
2047#endif /* defined(VGO_linux) */
2048
2049/*--------------------------------------------------------------------*/
2050/*--- end ---*/
2051/*--------------------------------------------------------------------*/