blob: da00dd17157c20d4184d4923932f0b4e2245b62e [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
11 Copyright (C) 2000-2013 Julian Seward
12 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
106
107/* Figure out if [dst .. dst+dstlen-1] overlaps with
108 [src .. src+srclen-1].
109 We assume that the address ranges do not wrap around
110 (which is safe since on Linux addresses >= 0xC0000000
111 are not accessible and the program will segfault in this
112 circumstance, presumably).
113*/
114static inline
115Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
116{
117 Addr loS, hiS, loD, hiD;
118
119 if (dstlen == 0 || srclen == 0)
120 return False;
121
122 loS = (Addr)src;
123 loD = (Addr)dst;
124 hiS = loS + srclen - 1;
125 hiD = loD + dstlen - 1;
126
127 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
128 if (loS < loD) {
129 return !(hiS < loD);
130 }
131 else if (loD < loS) {
132 return !(hiD < loS);
133 }
134 else {
135 /* They start at same place. Since we know neither of them has
136 zero length, they must overlap. */
137 return True;
138 }
139}
140
141
142/* Call here to exit if we can't continue. On Android we can't call
143 _exit for some reason, so we have to blunt-instrument it. */
144__attribute__ ((__noreturn__))
145static inline void my_exit ( int x )
146{
dejanj9c6b05d2013-12-27 09:06:55 +0000147# if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
sewardj26ed4192014-11-04 17:44:21 +0000148 || defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000149 __asm__ __volatile__(".word 0xFFFFFFFF");
150 while (1) {}
151# elif defined(VGPV_x86_linux_android)
152 __asm__ __volatile__("ud2");
153 while (1) {}
154# else
155 extern __attribute__ ((__noreturn__)) void _exit(int status);
156 _exit(x);
157# endif
158}
159
160
161// This is a macro rather than a function because we don't want to have an
162// extra function in the stack trace.
163#ifndef RECORD_OVERLAP_ERROR
164#define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
165#endif
166#ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
167#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
168#endif
169
170
171/*---------------------- strrchr ----------------------*/
172
173#define STRRCHR(soname, fnname) \
174 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
175 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
176 { \
177 HChar ch = (HChar)c; \
178 const HChar* p = s; \
179 const HChar* last = NULL; \
180 while (True) { \
181 if (*p == ch) last = p; \
florian70a5de12014-10-22 12:53:16 +0000182 if (*p == 0) return CONST_CAST(HChar *,last); \
bart9c7779b2013-11-24 17:48:13 +0000183 p++; \
184 } \
185 }
186
187// Apparently rindex() is the same thing as strrchr()
188#if defined(VGO_linux)
189 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
190 STRRCHR(VG_Z_LIBC_SONAME, rindex)
191 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
192 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
193 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
194 STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
195 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
dejanj9c6b05d2013-12-27 09:06:55 +0000196#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
197 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000198 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
199#endif
200
201#elif defined(VGO_darwin)
202 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
203 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
204 //STRRCHR(VG_Z_DYLD, strrchr)
205 //STRRCHR(VG_Z_DYLD, rindex)
206 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
sewardjeb86dda2014-10-17 15:07:37 +0000207# if DARWIN_VERS == DARWIN_10_9
208 STRRCHR(libsystemZucZddylib, strrchr)
209# endif
bart9c7779b2013-11-24 17:48:13 +0000210
211#endif
212
213
214/*---------------------- strchr ----------------------*/
215
216#define STRCHR(soname, fnname) \
217 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
218 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
219 { \
220 HChar ch = (HChar)c ; \
221 const HChar* p = s; \
222 while (True) { \
florian70a5de12014-10-22 12:53:16 +0000223 if (*p == ch) return CONST_CAST(HChar *,p); \
bart9c7779b2013-11-24 17:48:13 +0000224 if (*p == 0) return NULL; \
225 p++; \
226 } \
227 }
228
229// Apparently index() is the same thing as strchr()
230#if defined(VGO_linux)
231 STRCHR(VG_Z_LIBC_SONAME, strchr)
232 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
233 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
234 STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
235 STRCHR(VG_Z_LIBC_SONAME, index)
236# if !defined(VGP_x86_linux)
237 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
238 STRCHR(VG_Z_LD_LINUX_SO_2, index)
239 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
240 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
241# endif
242
243#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000244 STRCHR(VG_Z_LIBC_SONAME, strchr)
sewardjc3e09f62014-06-21 09:40:19 +0000245# if DARWIN_VERS == DARWIN_10_9
246 STRCHR(libsystemZuplatformZddylib, _platform_strchr)
247# endif
bart9c7779b2013-11-24 17:48:13 +0000248#endif
249
250
251/*---------------------- strcat ----------------------*/
252
253#define STRCAT(soname, fnname) \
254 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
255 ( char* dst, const char* src ); \
256 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
257 ( char* dst, const char* src ) \
258 { \
259 const HChar* src_orig = src; \
260 HChar* dst_orig = dst; \
261 while (*dst) dst++; \
262 while (*src) *dst++ = *src++; \
263 *dst = 0; \
264 \
265 /* This is a bit redundant, I think; any overlap and the strcat will */ \
266 /* go forever... or until a seg fault occurs. */ \
267 if (is_overlap(dst_orig, \
268 src_orig, \
269 (Addr)dst-(Addr)dst_orig+1, \
270 (Addr)src-(Addr)src_orig+1)) \
271 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
272 \
273 return dst_orig; \
274 }
275
276#if defined(VGO_linux)
277 STRCAT(VG_Z_LIBC_SONAME, strcat)
278 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
279
280#elif defined(VGO_darwin)
281 //STRCAT(VG_Z_LIBC_SONAME, strcat)
282
283#endif
284
285
286/*---------------------- strncat ----------------------*/
287
288#define STRNCAT(soname, fnname) \
289 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
290 ( char* dst, const char* src, SizeT n ); \
291 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
292 ( char* dst, const char* src, SizeT n ) \
293 { \
294 const HChar* src_orig = src; \
295 HChar* dst_orig = dst; \
296 SizeT m = 0; \
297 \
298 while (*dst) dst++; \
299 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
300 *dst = 0; /* always add null */ \
301 \
302 /* This checks for overlap after copying, unavoidable without */ \
303 /* pre-counting lengths... should be ok */ \
304 if (is_overlap(dst_orig, \
305 src_orig, \
306 (Addr)dst-(Addr)dst_orig+1, \
307 (Addr)src-(Addr)src_orig+1)) \
308 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
309 \
310 return dst_orig; \
311 }
312
313#if defined(VGO_linux)
314 STRNCAT(VG_Z_LIBC_SONAME, strncat)
315
316#elif defined(VGO_darwin)
317 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
318 //STRNCAT(VG_Z_DYLD, strncat)
319
320#endif
321
322
323/*---------------------- strlcat ----------------------*/
324
325/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
326 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
327 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
328 Truncation occurred if retval >= n.
329*/
330#define STRLCAT(soname, fnname) \
331 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
332 ( char* dst, const char* src, SizeT n ); \
333 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
334 ( char* dst, const char* src, SizeT n ) \
335 { \
336 const HChar* src_orig = src; \
337 HChar* dst_orig = dst; \
338 SizeT m = 0; \
339 \
340 while (m < n && *dst) { m++; dst++; } \
341 if (m < n) { \
342 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
343 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
344 *dst = 0; \
345 } else { \
346 /* No space to copy anything to dst. m == n */ \
347 } \
348 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
349 while (*src) { m++; src++; } \
350 /* This checks for overlap after copying, unavoidable without */ \
351 /* pre-counting lengths... should be ok */ \
352 if (is_overlap(dst_orig, \
353 src_orig, \
354 (Addr)dst-(Addr)dst_orig+1, \
355 (Addr)src-(Addr)src_orig+1)) \
356 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
357 \
358 return m; \
359 }
360
361#if defined(VGO_linux)
362
363#elif defined(VGO_darwin)
364 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
365 //STRLCAT(VG_Z_DYLD, strlcat)
366 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
367
368#endif
369
370
371/*---------------------- strnlen ----------------------*/
372
373#define STRNLEN(soname, fnname) \
374 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
375 ( const char* str, SizeT n ); \
376 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
377 ( const char* str, SizeT n ) \
378 { \
379 SizeT i = 0; \
380 while (i < n && str[i] != 0) i++; \
381 return i; \
382 }
383
384#if defined(VGO_linux)
385 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
386 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
387
388#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000389# if DARWIN_VERS == DARWIN_10_9
390 STRNLEN(libsystemZucZddylib, strnlen)
391# endif
bart9c7779b2013-11-24 17:48:13 +0000392
393#endif
394
395
396/*---------------------- strlen ----------------------*/
397
398// Note that this replacement often doesn't get used because gcc inlines
399// calls to strlen() with its own built-in version. This can be very
400// confusing if you aren't expecting it. Other small functions in
401// this file may also be inline by gcc.
402
403#define STRLEN(soname, fnname) \
404 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
405 ( const char* str ); \
406 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
407 ( const char* str ) \
408 { \
409 SizeT i = 0; \
410 while (str[i] != 0) i++; \
411 return i; \
412 }
413
414#if defined(VGO_linux)
415 STRLEN(VG_Z_LIBC_SONAME, strlen)
416 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
417 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
418 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
419 STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
420 STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
421 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
sewardj26ed4192014-11-04 17:44:21 +0000422# if defined(VGPV_arm_linux_android) \
423 || defined(VGPV_x86_linux_android) \
dejanj9c6b05d2013-12-27 09:06:55 +0000424 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000425 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
426# endif
427
428#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000429 STRLEN(VG_Z_LIBC_SONAME, strlen)
sewardj312bcb12014-11-07 00:08:13 +0000430# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
sewardjc3e09f62014-06-21 09:40:19 +0000431 STRLEN(libsystemZucZddylib, strlen)
432# endif
bart9c7779b2013-11-24 17:48:13 +0000433#endif
434
435
436/*---------------------- strcpy ----------------------*/
437
438#define STRCPY(soname, fnname) \
439 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
440 ( char* dst, const char* src ); \
441 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
442 ( char* dst, const char* src ) \
443 { \
444 const HChar* src_orig = src; \
445 HChar* dst_orig = dst; \
446 \
447 while (*src) *dst++ = *src++; \
448 *dst = 0; \
449 \
450 /* This checks for overlap after copying, unavoidable without */ \
451 /* pre-counting length... should be ok */ \
452 if (is_overlap(dst_orig, \
453 src_orig, \
454 (Addr)dst-(Addr)dst_orig+1, \
455 (Addr)src-(Addr)src_orig+1)) \
456 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
457 \
458 return dst_orig; \
459 }
460
461#if defined(VGO_linux)
462 STRCPY(VG_Z_LIBC_SONAME, strcpy)
463 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
464
465#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000466 STRCPY(VG_Z_LIBC_SONAME, strcpy)
sewardjaec49a42014-06-23 16:03:45 +0000467# if DARWIN_VERS == DARWIN_10_9
468 STRCPY(libsystemZucZddylib, strcpy)
469# endif
bart9c7779b2013-11-24 17:48:13 +0000470
471#endif
472
473
474/*---------------------- strncpy ----------------------*/
475
476#define STRNCPY(soname, fnname) \
477 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
478 ( char* dst, const char* src, SizeT n ); \
479 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
480 ( char* dst, const char* src, SizeT n ) \
481 { \
482 const HChar* src_orig = src; \
483 HChar* dst_orig = dst; \
484 SizeT m = 0; \
485 \
486 while (m < n && *src) { m++; *dst++ = *src++; } \
487 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
488 /* but only m+1 bytes of src if terminator was found */ \
489 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
490 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
491 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
492 \
493 return dst_orig; \
494 }
495
496#if defined(VGO_linux)
497 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
498 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
499 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
500 STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
501
502#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000503 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
sewardj312bcb12014-11-07 00:08:13 +0000504# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
sewardjaec49a42014-06-23 16:03:45 +0000505 STRNCPY(libsystemZucZddylib, strncpy)
506# endif
bart9c7779b2013-11-24 17:48:13 +0000507
508#endif
509
510
511/*---------------------- strlcpy ----------------------*/
512
513/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
514 Returns strlen(src). Does not zero-fill the remainder of dst. */
515#define STRLCPY(soname, fnname) \
516 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
517 ( char* dst, const char* src, SizeT n ); \
518 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
519 ( char* dst, const char* src, SizeT n ) \
520 { \
521 const HChar* src_orig = src; \
522 HChar* dst_orig = dst; \
523 SizeT m = 0; \
524 \
525 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
526 /* m non-nul bytes have now been copied, and m <= n-1. */ \
527 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
528 /* but only m+1 bytes of src if terminator was found */ \
529 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
530 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
531 /* Nul-terminate dst. */ \
532 if (n > 0) *dst = 0; \
533 /* Finish counting strlen(src). */ \
534 while (*src) src++; \
535 return src - src_orig; \
536 }
537
538#if defined(VGO_linux)
539
dejanj9c6b05d2013-12-27 09:06:55 +0000540#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
541 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000542 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
543#endif
544
545#elif defined(VGO_darwin)
546 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
547 //STRLCPY(VG_Z_DYLD, strlcpy)
548 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
549
550#endif
551
552
553/*---------------------- strncmp ----------------------*/
554
555#define STRNCMP(soname, fnname) \
556 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
557 ( const char* s1, const char* s2, SizeT nmax ); \
558 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
559 ( const char* s1, const char* s2, SizeT nmax ) \
560 { \
561 SizeT n = 0; \
562 while (True) { \
563 if (n >= nmax) return 0; \
564 if (*s1 == 0 && *s2 == 0) return 0; \
565 if (*s1 == 0) return -1; \
566 if (*s2 == 0) return 1; \
567 \
568 if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
569 if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
570 \
571 s1++; s2++; n++; \
572 } \
573 }
574
575#if defined(VGO_linux)
576 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
577 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
578 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
579 STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
580
581#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000582 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
sewardj3c02a922014-11-11 12:46:58 +0000583# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
sewardj798e95b2014-06-25 11:17:46 +0000584 STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
585# endif
bart9c7779b2013-11-24 17:48:13 +0000586
587#endif
588
589
590/*---------------------- strcasecmp ----------------------*/
591
592#define STRCASECMP(soname, fnname) \
593 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
594 ( const char* s1, const char* s2 ); \
595 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
596 ( const char* s1, const char* s2 ) \
597 { \
598 extern int tolower(int); \
599 register UChar c1; \
600 register UChar c2; \
601 while (True) { \
602 c1 = tolower(*(const UChar *)s1); \
603 c2 = tolower(*(const UChar *)s2); \
604 if (c1 != c2) break; \
605 if (c1 == 0) break; \
606 s1++; s2++; \
607 } \
608 if ((UChar)c1 < (UChar)c2) return -1; \
609 if ((UChar)c1 > (UChar)c2) return 1; \
610 return 0; \
611 }
612
613#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000614# if !defined(VGPV_arm_linux_android) \
615 && !defined(VGPV_x86_linux_android) \
616 && !defined(VGPV_mips32_linux_android) \
617 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000618 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
619 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
620# endif
621
622#elif defined(VGO_darwin)
623 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
624
625#endif
626
627
628/*---------------------- strncasecmp ----------------------*/
629
630#define STRNCASECMP(soname, fnname) \
631 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
632 ( const char* s1, const char* s2, SizeT nmax ); \
633 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
634 ( const char* s1, const char* s2, SizeT nmax ) \
635 { \
636 extern int tolower(int); \
637 SizeT n = 0; \
638 while (True) { \
639 if (n >= nmax) return 0; \
640 if (*s1 == 0 && *s2 == 0) return 0; \
641 if (*s1 == 0) return -1; \
642 if (*s2 == 0) return 1; \
643 \
644 if (tolower(*(const UChar *)s1) \
645 < tolower(*(const UChar*)s2)) return -1; \
646 if (tolower(*(const UChar *)s1) \
647 > tolower(*(const UChar *)s2)) return 1; \
648 \
649 s1++; s2++; n++; \
650 } \
651 }
652
653#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +0000654# if !defined(VGPV_arm_linux_android) \
655 && !defined(VGPV_x86_linux_android) \
656 && !defined(VGPV_mips32_linux_android) \
657 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000658 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
659 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
660# endif
661
662#elif defined(VGO_darwin)
663 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
664 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
665
666#endif
667
668
669/*---------------------- strcasecmp_l ----------------------*/
670
671#define STRCASECMP_L(soname, fnname) \
672 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
673 ( const char* s1, const char* s2, void* locale ); \
674 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
675 ( const char* s1, const char* s2, void* locale ) \
676 { \
677 extern int tolower_l(int, void*) __attribute__((weak)); \
678 register UChar c1; \
679 register UChar c2; \
680 while (True) { \
681 c1 = tolower_l(*(const UChar *)s1, locale); \
682 c2 = tolower_l(*(const UChar *)s2, locale); \
683 if (c1 != c2) break; \
684 if (c1 == 0) break; \
685 s1++; s2++; \
686 } \
687 if ((UChar)c1 < (UChar)c2) return -1; \
688 if ((UChar)c1 > (UChar)c2) return 1; \
689 return 0; \
690 }
691
692#if defined(VGO_linux)
693 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
694 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
695 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
696
697#elif defined(VGO_darwin)
698 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
699
700#endif
701
702
703/*---------------------- strncasecmp_l ----------------------*/
704
705#define STRNCASECMP_L(soname, fnname) \
706 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
707 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
708 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
709 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
710 { \
711 extern int tolower_l(int, void*) __attribute__((weak)); \
712 SizeT n = 0; \
713 while (True) { \
714 if (n >= nmax) return 0; \
715 if (*s1 == 0 && *s2 == 0) return 0; \
716 if (*s1 == 0) return -1; \
717 if (*s2 == 0) return 1; \
718 \
719 if (tolower_l(*(const UChar *)s1, locale) \
720 < tolower_l(*(const UChar *)s2, locale)) return -1; \
721 if (tolower_l(*(const UChar *)s1, locale) \
722 > tolower_l(*(const UChar *)s2, locale)) return 1; \
723 \
724 s1++; s2++; n++; \
725 } \
726 }
727
728#if defined(VGO_linux)
729 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
730 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
731 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
732
733#elif defined(VGO_darwin)
734 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
735 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
736
737#endif
738
739
740/*---------------------- strcmp ----------------------*/
741
742#define STRCMP(soname, fnname) \
743 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
744 ( const char* s1, const char* s2 ); \
745 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
746 ( const char* s1, const char* s2 ) \
747 { \
748 register UChar c1; \
749 register UChar c2; \
750 while (True) { \
751 c1 = *(const UChar *)s1; \
752 c2 = *(const UChar *)s2; \
753 if (c1 != c2) break; \
754 if (c1 == 0) break; \
755 s1++; s2++; \
756 } \
757 if ((UChar)c1 < (UChar)c2) return -1; \
758 if ((UChar)c1 > (UChar)c2) return 1; \
759 return 0; \
760 }
761
762#if defined(VGO_linux)
763 STRCMP(VG_Z_LIBC_SONAME, strcmp)
764 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
765 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
766 STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
767 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
768 STRCMP(VG_Z_LD64_SO_1, strcmp)
dejanj9c6b05d2013-12-27 09:06:55 +0000769# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
770 || defined(VGPV_mips32_linux_android)
bart9c7779b2013-11-24 17:48:13 +0000771 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
772# endif
773
774#elif defined(VGO_darwin)
bart9c7779b2013-11-24 17:48:13 +0000775 STRCMP(VG_Z_LIBC_SONAME, strcmp)
sewardj312bcb12014-11-07 00:08:13 +0000776# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
sewardjc3e09f62014-06-21 09:40:19 +0000777 STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
778# endif
bart9c7779b2013-11-24 17:48:13 +0000779
780#endif
781
782
783/*---------------------- memchr ----------------------*/
784
785#define MEMCHR(soname, fnname) \
786 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
787 (const void *s, int c, SizeT n); \
788 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
789 (const void *s, int c, SizeT n) \
790 { \
791 SizeT i; \
792 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000793 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000794 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000795 if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
bart9c7779b2013-11-24 17:48:13 +0000796 return NULL; \
797 }
798
799#if defined(VGO_linux)
800 MEMCHR(VG_Z_LIBC_SONAME, memchr)
801 MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
802
803#elif defined(VGO_darwin)
sewardjaec49a42014-06-23 16:03:45 +0000804# if DARWIN_VERS == DARWIN_10_9
sewardj798e95b2014-06-25 11:17:46 +0000805 MEMCHR(VG_Z_DYLD, memchr)
sewardjaec49a42014-06-23 16:03:45 +0000806 MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
807# endif
sewardj312bcb12014-11-07 00:08:13 +0000808# if DARWIN_VERS == DARWIN_10_10
sewardja95abea2014-11-19 09:14:07 +0000809 MEMCHR(VG_Z_DYLD, memchr)
sewardj312bcb12014-11-07 00:08:13 +0000810 /* _platform_memchr$VARIANT$Generic */
811 MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
812# endif
bart9c7779b2013-11-24 17:48:13 +0000813
814#endif
815
816
817/*---------------------- memrchr ----------------------*/
818
819#define MEMRCHR(soname, fnname) \
820 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
821 (const void *s, int c, SizeT n); \
822 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
823 (const void *s, int c, SizeT n) \
824 { \
825 SizeT i; \
826 UChar c0 = (UChar)c; \
florian70a5de12014-10-22 12:53:16 +0000827 const UChar* p = s; \
bart9c7779b2013-11-24 17:48:13 +0000828 for (i = 0; i < n; i++) \
florian70a5de12014-10-22 12:53:16 +0000829 if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
bart9c7779b2013-11-24 17:48:13 +0000830 return NULL; \
831 }
832
833#if defined(VGO_linux)
834 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
835
836#elif defined(VGO_darwin)
837 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
838 //MEMRCHR(VG_Z_DYLD, memrchr)
839
840#endif
841
842
843/*---------------------- memcpy ----------------------*/
844
845#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
846 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
847 ( void *dst, const void *src, SizeT len ); \
848 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
849 ( void *dst, const void *src, SizeT len ) \
850 { \
851 if (do_ol_check && is_overlap(dst, src, len, len)) \
852 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
853 \
854 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
855 const Addr WM = WS - 1; /* 7 or 3 */ \
856 \
857 if (len > 0) { \
858 if (dst < src || !is_overlap(dst, src, len, len)) { \
859 \
860 /* Copying backwards. */ \
861 SizeT n = len; \
862 Addr d = (Addr)dst; \
863 Addr s = (Addr)src; \
864 \
865 if (((s^d) & WM) == 0) { \
866 /* s and d have same UWord alignment. */ \
867 /* Pull up to a UWord boundary. */ \
868 while ((s & WM) != 0 && n >= 1) \
869 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
870 /* Copy UWords. */ \
871 while (n >= WS) \
872 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
873 if (n == 0) \
874 return dst; \
875 } \
876 if (((s|d) & 1) == 0) { \
877 /* Both are 16-aligned; copy what we can thusly. */ \
878 while (n >= 2) \
879 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
880 } \
881 /* Copy leftovers, or everything if misaligned. */ \
882 while (n >= 1) \
883 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
884 \
885 } else if (dst > src) { \
886 \
887 SizeT n = len; \
888 Addr d = ((Addr)dst) + n; \
889 Addr s = ((Addr)src) + n; \
890 \
891 /* Copying forwards. */ \
892 if (((s^d) & WM) == 0) { \
893 /* s and d have same UWord alignment. */ \
894 /* Back down to a UWord boundary. */ \
895 while ((s & WM) != 0 && n >= 1) \
896 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
897 /* Copy UWords. */ \
898 while (n >= WS) \
899 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
900 if (n == 0) \
901 return dst; \
902 } \
903 if (((s|d) & 1) == 0) { \
904 /* Both are 16-aligned; copy what we can thusly. */ \
905 while (n >= 2) \
906 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
907 } \
908 /* Copy leftovers, or everything if misaligned. */ \
909 while (n >= 1) \
910 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
911 \
912 } \
913 } \
914 \
915 return dst; \
916 }
917
918#define MEMMOVE(soname, fnname) \
919 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
920
921#define MEMCPY(soname, fnname) \
922 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
923
924#if defined(VGO_linux)
925 /* For older memcpy we have to use memmove-like semantics and skip
926 the overlap check; sigh; see #275284. */
927 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
928 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
929 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
930 MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
931 MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
932 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
933 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
934 /* icc9 blats these around all over the place. Not only in the main
935 executable but various .so's. They are highly tuned and read
936 memory beyond the source boundary (although work correctly and
937 never go across page boundaries), so give errors when run
938 natively, at least for misaligned source arg. Just intercepting
939 in the exe only until we understand more about the problem. See
940 http://bugs.kde.org/show_bug.cgi?id=139776
941 */
942 MEMCPY(NONE, ZuintelZufastZumemcpy)
943
944#elif defined(VGO_darwin)
945# if DARWIN_VERS <= DARWIN_10_6
946 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
947# endif
948 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
949 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
950
951#endif
952
953
954/*---------------------- memcmp ----------------------*/
955
956#define MEMCMP(soname, fnname) \
957 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
958 ( const void *s1V, const void *s2V, SizeT n ); \
959 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
960 ( const void *s1V, const void *s2V, SizeT n ) \
961 { \
sewardj094b9912015-02-04 18:46:11 +0000962 const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
963 const SizeT WM = WS - 1; /* 7 or 3 */ \
sewardj11e20f72015-02-04 17:52:42 +0000964 Addr s1A = (Addr)s1V; \
965 Addr s2A = (Addr)s2V; \
966 \
967 if (((s1A | s2A) & WM) == 0) { \
968 /* Both areas are word aligned. Skip over the */ \
969 /* equal prefix as fast as possible. */ \
970 while (n >= WS) { \
971 UWord w1 = *(UWord*)s1A; \
972 UWord w2 = *(UWord*)s2A; \
973 if (w1 != w2) break; \
974 s1A += WS; \
975 s2A += WS; \
976 n -= WS; \
977 } \
978 } \
979 \
980 const UChar* s1 = (const UChar*) s1A; \
981 const UChar* s2 = (const UChar*) s2A; \
bart9c7779b2013-11-24 17:48:13 +0000982 \
983 while (n != 0) { \
sewardj11e20f72015-02-04 17:52:42 +0000984 UChar a0 = s1[0]; \
985 UChar b0 = s2[0]; \
bart9c7779b2013-11-24 17:48:13 +0000986 s1 += 1; \
987 s2 += 1; \
sewardj11e20f72015-02-04 17:52:42 +0000988 int res = ((int)a0) - ((int)b0); \
bart9c7779b2013-11-24 17:48:13 +0000989 if (res != 0) \
990 return res; \
991 n -= 1; \
992 } \
993 return 0; \
994 }
995
996#if defined(VGO_linux)
997 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
998 MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
999 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
1000 MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
1001 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
1002 MEMCMP(VG_Z_LD_SO_1, bcmp)
1003
1004#elif defined(VGO_darwin)
sewardj312bcb12014-11-07 00:08:13 +00001005# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
sewardjaec49a42014-06-23 16:03:45 +00001006 MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1007# endif
bart9c7779b2013-11-24 17:48:13 +00001008
1009#endif
1010
1011
1012/*---------------------- stpcpy ----------------------*/
1013
1014/* Copy SRC to DEST, returning the address of the terminating '\0' in
1015 DEST. (minor variant of strcpy) */
1016#define STPCPY(soname, fnname) \
1017 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1018 ( char* dst, const char* src ); \
1019 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
1020 ( char* dst, const char* src ) \
1021 { \
1022 const HChar* src_orig = src; \
1023 HChar* dst_orig = dst; \
1024 \
1025 while (*src) *dst++ = *src++; \
1026 *dst = 0; \
1027 \
1028 /* This checks for overlap after copying, unavoidable without */ \
1029 /* pre-counting length... should be ok */ \
1030 if (is_overlap(dst_orig, \
1031 src_orig, \
1032 (Addr)dst-(Addr)dst_orig+1, \
1033 (Addr)src-(Addr)src_orig+1)) \
1034 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
1035 \
1036 return dst; \
1037 }
1038
1039#if defined(VGO_linux)
1040 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1041 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
1042 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
1043 STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
1044 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
1045 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
1046
1047#elif defined(VGO_darwin)
1048 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
1049 //STPCPY(VG_Z_DYLD, stpcpy)
1050
1051#endif
1052
1053
1054/*---------------------- stpncpy ----------------------*/
1055
1056#define STPNCPY(soname, fnname) \
1057 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1058 ( char* dst, const char* src, SizeT n ); \
1059 char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
1060 ( char* dst, const char* src, SizeT n ) \
1061 { \
1062 const HChar* src_orig = src; \
1063 HChar* dst_str = dst; \
1064 SizeT m = 0; \
1065 \
1066 while (m < n && *src) { m++; *dst++ = *src++; } \
1067 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
1068 /* but only m+1 bytes of src if terminator was found */ \
1069 if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
1070 RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
1071 dst_str = dst; \
1072 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
1073 \
1074 return dst_str; \
1075 }
1076
1077#if defined(VGO_linux)
1078 STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
1079#endif
1080
1081
1082/*---------------------- memset ----------------------*/
1083
1084/* Why are we bothering to intercept this? It seems entirely
1085 pointless. */
1086
1087#define MEMSET(soname, fnname) \
1088 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1089 (void *s, Int c, SizeT n); \
1090 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
1091 (void *s, Int c, SizeT n) \
1092 { \
1093 if (sizeof(void*) == 8) { \
1094 Addr a = (Addr)s; \
1095 ULong c8 = (c & 0xFF); \
1096 c8 = (c8 << 8) | c8; \
1097 c8 = (c8 << 16) | c8; \
1098 c8 = (c8 << 32) | c8; \
1099 while ((a & 7) != 0 && n >= 1) \
1100 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1101 while (n >= 8) \
1102 { *(ULong*)a = c8; a += 8; n -= 8; } \
1103 while (n >= 1) \
1104 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1105 return s; \
1106 } else { \
1107 Addr a = (Addr)s; \
1108 UInt c4 = (c & 0xFF); \
1109 c4 = (c4 << 8) | c4; \
1110 c4 = (c4 << 16) | c4; \
1111 while ((a & 3) != 0 && n >= 1) \
1112 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1113 while (n >= 4) \
1114 { *(UInt*)a = c4; a += 4; n -= 4; } \
1115 while (n >= 1) \
1116 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1117 return s; \
1118 } \
1119 }
1120
1121#if defined(VGO_linux)
1122 MEMSET(VG_Z_LIBC_SONAME, memset)
1123
1124#elif defined(VGO_darwin)
1125 //MEMSET(VG_Z_LIBC_SONAME, memset)
1126 //MEMSET(VG_Z_DYLD, memset)
1127 MEMSET(VG_Z_LIBC_SONAME, memset)
1128
1129#endif
1130
1131
1132/*---------------------- memmove ----------------------*/
1133
1134/* memmove -- use the MEMMOVE defn above. */
1135
1136#if defined(VGO_linux)
1137 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1138 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1139
1140#elif defined(VGO_darwin)
1141# if DARWIN_VERS <= DARWIN_10_6
1142 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1143# endif
1144 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1145 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
sewardj312bcb12014-11-07 00:08:13 +00001146# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
1147 /* _platform_memmove$VARIANT$Ivybridge */
sewardjeb86dda2014-10-17 15:07:37 +00001148 MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1149# endif
bart9c7779b2013-11-24 17:48:13 +00001150#endif
1151
1152
1153/*---------------------- bcopy ----------------------*/
1154
1155#define BCOPY(soname, fnname) \
1156 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1157 (const void *srcV, void *dstV, SizeT n); \
1158 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1159 (const void *srcV, void *dstV, SizeT n) \
1160 { \
1161 SizeT i; \
1162 HChar* dst = dstV; \
1163 const HChar* src = srcV; \
1164 if (dst < src) { \
1165 for (i = 0; i < n; i++) \
1166 dst[i] = src[i]; \
1167 } \
1168 else \
1169 if (dst > src) { \
1170 for (i = 0; i < n; i++) \
1171 dst[n-i-1] = src[n-i-1]; \
1172 } \
1173 }
1174
1175#if defined(VGO_linux)
1176 BCOPY(VG_Z_LIBC_SONAME, bcopy)
1177
1178#elif defined(VGO_darwin)
1179 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1180 //BCOPY(VG_Z_DYLD, bcopy)
1181
1182#endif
1183
1184
1185/*-------------------- memmove_chk --------------------*/
1186
1187/* glibc 2.5 variant of memmove which checks the dest is big enough.
1188 There is no specific part of glibc that this is copied from. */
1189#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1190 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1191 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1192 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1193 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1194 { \
1195 SizeT i; \
1196 HChar* dst = dstV; \
1197 const HChar* src = srcV; \
1198 if (destlen < n) \
1199 goto badness; \
1200 if (dst < src) { \
1201 for (i = 0; i < n; i++) \
1202 dst[i] = src[i]; \
1203 } \
1204 else \
1205 if (dst > src) { \
1206 for (i = 0; i < n; i++) \
1207 dst[n-i-1] = src[n-i-1]; \
1208 } \
1209 return dst; \
1210 badness: \
1211 VALGRIND_PRINTF_BACKTRACE( \
1212 "*** memmove_chk: buffer overflow detected ***: " \
1213 "program terminated\n"); \
1214 my_exit(127); \
1215 /*NOTREACHED*/ \
1216 return NULL; \
1217 }
1218
1219#if defined(VGO_linux)
1220 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1221
1222#elif defined(VGO_darwin)
1223
1224#endif
1225
1226
1227/*-------------------- strchrnul --------------------*/
1228
1229/* Find the first occurrence of C in S or the final NUL byte. */
1230#define GLIBC232_STRCHRNUL(soname, fnname) \
1231 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1232 (const char* s, int c_in); \
1233 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1234 (const char* s, int c_in) \
1235 { \
florian70a5de12014-10-22 12:53:16 +00001236 HChar c = (HChar) c_in; \
1237 const HChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001238 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001239 if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr); \
1240 if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001241 char_ptr++; \
1242 } \
1243 }
1244
1245#if defined(VGO_linux)
1246 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1247
1248#elif defined(VGO_darwin)
1249
1250#endif
1251
1252
1253/*---------------------- rawmemchr ----------------------*/
1254
1255/* Find the first occurrence of C in S. */
1256#define GLIBC232_RAWMEMCHR(soname, fnname) \
florian1ef205b2014-10-22 12:06:22 +00001257 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1258 (const void* s, int c_in); \
1259 void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1260 (const void* s, int c_in) \
bart9c7779b2013-11-24 17:48:13 +00001261 { \
florian1ef205b2014-10-22 12:06:22 +00001262 UChar c = (UChar) c_in; \
1263 const UChar* char_ptr = s; \
bart9c7779b2013-11-24 17:48:13 +00001264 while (1) { \
florian70a5de12014-10-22 12:53:16 +00001265 if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
bart9c7779b2013-11-24 17:48:13 +00001266 char_ptr++; \
1267 } \
1268 }
1269
1270#if defined (VGO_linux)
1271 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1272 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1273
1274#elif defined(VGO_darwin)
1275
1276#endif
1277
1278
1279/*---------------------- strcpy_chk ----------------------*/
1280
1281/* glibc variant of strcpy that checks the dest is big enough.
1282 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1283#define GLIBC25___STRCPY_CHK(soname,fnname) \
1284 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1285 (char* dst, const char* src, SizeT len); \
1286 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1287 (char* dst, const char* src, SizeT len) \
1288 { \
1289 HChar* ret = dst; \
1290 if (! len) \
1291 goto badness; \
1292 while ((*dst++ = *src++) != '\0') \
1293 if (--len == 0) \
1294 goto badness; \
1295 return ret; \
1296 badness: \
1297 VALGRIND_PRINTF_BACKTRACE( \
1298 "*** strcpy_chk: buffer overflow detected ***: " \
1299 "program terminated\n"); \
1300 my_exit(127); \
1301 /*NOTREACHED*/ \
1302 return NULL; \
1303 }
1304
1305#if defined(VGO_linux)
1306 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1307
1308#elif defined(VGO_darwin)
1309
1310#endif
1311
1312
1313/*---------------------- stpcpy_chk ----------------------*/
1314
1315/* glibc variant of stpcpy that checks the dest is big enough.
1316 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1317#define GLIBC25___STPCPY_CHK(soname,fnname) \
1318 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1319 (char* dst, const char* src, SizeT len); \
1320 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1321 (char* dst, const char* src, SizeT len) \
1322 { \
1323 if (! len) \
1324 goto badness; \
1325 while ((*dst++ = *src++) != '\0') \
1326 if (--len == 0) \
1327 goto badness; \
1328 return dst - 1; \
1329 badness: \
1330 VALGRIND_PRINTF_BACKTRACE( \
1331 "*** stpcpy_chk: buffer overflow detected ***: " \
1332 "program terminated\n"); \
1333 my_exit(127); \
1334 /*NOTREACHED*/ \
1335 return NULL; \
1336 }
1337
1338#if defined(VGO_linux)
1339 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1340
1341#elif defined(VGO_darwin)
1342
1343#endif
1344
1345
1346/*---------------------- mempcpy ----------------------*/
1347
1348/* mempcpy */
1349#define GLIBC25_MEMPCPY(soname, fnname) \
1350 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1351 ( void *dst, const void *src, SizeT len ); \
1352 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1353 ( void *dst, const void *src, SizeT len ) \
1354 { \
bart9c7779b2013-11-24 17:48:13 +00001355 SizeT len_saved = len; \
1356 \
1357 if (len == 0) \
1358 return dst; \
1359 \
1360 if (is_overlap(dst, src, len, len)) \
1361 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1362 \
1363 if ( dst > src ) { \
florian09041e42014-10-21 17:15:14 +00001364 register HChar *d = (char *)dst + len - 1; \
1365 register const HChar *s = (const char *)src + len - 1; \
bart9c7779b2013-11-24 17:48:13 +00001366 while ( len-- ) { \
1367 *d-- = *s--; \
1368 } \
1369 } else if ( dst < src ) { \
florian09041e42014-10-21 17:15:14 +00001370 register HChar *d = dst; \
1371 register const HChar *s = src; \
bart9c7779b2013-11-24 17:48:13 +00001372 while ( len-- ) { \
1373 *d++ = *s++; \
1374 } \
1375 } \
1376 return (void*)( ((char*)dst) + len_saved ); \
1377 }
1378
1379#if defined(VGO_linux)
1380 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
mjwa9176d92015-01-13 16:10:20 +00001381 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
bart9c7779b2013-11-24 17:48:13 +00001382 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
bartf2d86632014-03-15 12:47:28 +00001383 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1384 GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
bart9c7779b2013-11-24 17:48:13 +00001385
1386#elif defined(VGO_darwin)
1387 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1388
1389#endif
1390
1391
1392/*-------------------- memcpy_chk --------------------*/
1393
1394#define GLIBC26___MEMCPY_CHK(soname, fnname) \
1395 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1396 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1397 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1398 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1399 { \
1400 register HChar *d; \
1401 register const HChar *s; \
1402 \
1403 if (dstlen < len) goto badness; \
1404 \
1405 if (len == 0) \
1406 return dst; \
1407 \
1408 if (is_overlap(dst, src, len, len)) \
1409 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1410 \
1411 if ( dst > src ) { \
1412 d = (HChar *)dst + len - 1; \
1413 s = (const HChar *)src + len - 1; \
1414 while ( len-- ) { \
1415 *d-- = *s--; \
1416 } \
1417 } else if ( dst < src ) { \
1418 d = (HChar *)dst; \
1419 s = (const HChar *)src; \
1420 while ( len-- ) { \
1421 *d++ = *s++; \
1422 } \
1423 } \
1424 return dst; \
1425 badness: \
1426 VALGRIND_PRINTF_BACKTRACE( \
1427 "*** memcpy_chk: buffer overflow detected ***: " \
1428 "program terminated\n"); \
1429 my_exit(127); \
1430 /*NOTREACHED*/ \
1431 return NULL; \
1432 }
1433
1434#if defined(VGO_linux)
1435 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1436
1437#elif defined(VGO_darwin)
1438
1439#endif
1440
1441
1442/*---------------------- strstr ----------------------*/
1443
1444#define STRSTR(soname, fnname) \
1445 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1446 (const char* haystack, const char* needle); \
1447 char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1448 (const char* haystack, const char* needle) \
1449 { \
1450 const HChar* h = haystack; \
1451 const HChar* n = needle; \
1452 \
1453 /* find the length of n, not including terminating zero */ \
1454 UWord nlen = 0; \
1455 while (n[nlen]) nlen++; \
1456 \
1457 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001458 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001459 \
1460 /* assert(nlen >= 1); */ \
1461 HChar n0 = n[0]; \
1462 \
1463 while (1) { \
1464 const HChar hh = *h; \
1465 if (hh == 0) return NULL; \
1466 if (hh != n0) { h++; continue; } \
1467 \
1468 UWord i; \
1469 for (i = 0; i < nlen; i++) { \
1470 if (n[i] != h[i]) \
1471 break; \
1472 } \
1473 /* assert(i >= 0 && i <= nlen); */ \
1474 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001475 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001476 \
1477 h++; \
1478 } \
1479 }
1480
1481#if defined(VGO_linux)
1482 STRSTR(VG_Z_LIBC_SONAME, strstr)
1483 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
1484 STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
1485
1486#elif defined(VGO_darwin)
1487
1488#endif
1489
1490
1491/*---------------------- strpbrk ----------------------*/
1492
1493#define STRPBRK(soname, fnname) \
1494 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1495 (const char* sV, const char* acceptV); \
1496 char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1497 (const char* sV, const char* acceptV) \
1498 { \
1499 const HChar* s = sV; \
1500 const HChar* accept = acceptV; \
1501 \
1502 /* find the length of 'accept', not including terminating zero */ \
1503 UWord nacc = 0; \
1504 while (accept[nacc]) nacc++; \
1505 \
1506 /* if n is the empty string, fail immediately. */ \
1507 if (nacc == 0) return NULL; \
1508 \
1509 /* assert(nacc >= 1); */ \
1510 while (1) { \
1511 UWord i; \
1512 HChar sc = *s; \
1513 if (sc == 0) \
1514 break; \
1515 for (i = 0; i < nacc; i++) { \
1516 if (sc == accept[i]) \
florian70a5de12014-10-22 12:53:16 +00001517 return CONST_CAST(HChar *,s); \
bart9c7779b2013-11-24 17:48:13 +00001518 } \
1519 s++; \
1520 } \
1521 \
1522 return NULL; \
1523 }
1524
1525#if defined(VGO_linux)
1526 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1527
1528#elif defined(VGO_darwin)
1529
1530#endif
1531
1532
1533/*---------------------- strcspn ----------------------*/
1534
1535#define STRCSPN(soname, fnname) \
1536 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1537 (const char* sV, const char* rejectV); \
1538 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1539 (const char* sV, const char* rejectV) \
1540 { \
1541 const HChar* s = sV; \
1542 const HChar* reject = rejectV; \
1543 \
1544 /* find the length of 'reject', not including terminating zero */ \
1545 UWord nrej = 0; \
1546 while (reject[nrej]) nrej++; \
1547 \
1548 UWord len = 0; \
1549 while (1) { \
1550 UWord i; \
1551 HChar sc = *s; \
1552 if (sc == 0) \
1553 break; \
1554 for (i = 0; i < nrej; i++) { \
1555 if (sc == reject[i]) \
1556 break; \
1557 } \
1558 /* assert(i >= 0 && i <= nrej); */ \
1559 if (i < nrej) \
1560 break; \
1561 s++; \
1562 len++; \
1563 } \
1564 \
1565 return len; \
1566 }
1567
1568#if defined(VGO_linux)
1569 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1570
1571#elif defined(VGO_darwin)
1572
1573#endif
1574
1575
1576/*---------------------- strspn ----------------------*/
1577
1578#define STRSPN(soname, fnname) \
1579 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1580 (const char* sV, const char* acceptV); \
1581 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1582 (const char* sV, const char* acceptV) \
1583 { \
1584 const UChar* s = (const UChar *)sV; \
1585 const UChar* accept = (const UChar *)acceptV; \
1586 \
1587 /* find the length of 'accept', not including terminating zero */ \
1588 UWord nacc = 0; \
1589 while (accept[nacc]) nacc++; \
1590 if (nacc == 0) return 0; \
1591 \
1592 UWord len = 0; \
1593 while (1) { \
1594 UWord i; \
1595 HChar sc = *s; \
1596 if (sc == 0) \
1597 break; \
1598 for (i = 0; i < nacc; i++) { \
1599 if (sc == accept[i]) \
1600 break; \
1601 } \
1602 /* assert(i >= 0 && i <= nacc); */ \
1603 if (i == nacc) \
1604 break; \
1605 s++; \
1606 len++; \
1607 } \
1608 \
1609 return len; \
1610 }
1611
1612#if defined(VGO_linux)
1613 STRSPN(VG_Z_LIBC_SONAME, strspn)
1614
1615#elif defined(VGO_darwin)
1616
1617#endif
1618
1619
1620/*---------------------- strcasestr ----------------------*/
1621
1622#define STRCASESTR(soname, fnname) \
1623 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1624 (const char* haystack, const char* needle); \
1625 char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1626 (const char* haystack, const char* needle) \
1627 { \
1628 extern int tolower(int); \
1629 const HChar* h = haystack; \
1630 const HChar* n = needle; \
1631 \
1632 /* find the length of n, not including terminating zero */ \
1633 UWord nlen = 0; \
1634 while (n[nlen]) nlen++; \
1635 \
1636 /* if n is the empty string, match immediately. */ \
florian70a5de12014-10-22 12:53:16 +00001637 if (nlen == 0) return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001638 \
1639 /* assert(nlen >= 1); */ \
1640 UChar n0 = tolower(n[0]); \
1641 \
1642 while (1) { \
1643 UChar hh = tolower(*h); \
1644 if (hh == 0) return NULL; \
1645 if (hh != n0) { h++; continue; } \
1646 \
1647 UWord i; \
1648 for (i = 0; i < nlen; i++) { \
1649 if (tolower(n[i]) != tolower(h[i])) \
1650 break; \
1651 } \
1652 /* assert(i >= 0 && i <= nlen); */ \
1653 if (i == nlen) \
florian70a5de12014-10-22 12:53:16 +00001654 return CONST_CAST(HChar *,h); \
bart9c7779b2013-11-24 17:48:13 +00001655 \
1656 h++; \
1657 } \
1658 }
1659
1660#if defined(VGO_linux)
sewardj26ed4192014-11-04 17:44:21 +00001661# if !defined(VGPV_arm_linux_android) \
1662 && !defined(VGPV_x86_linux_android) \
1663 && !defined(VGPV_mips32_linux_android) \
1664 && !defined(VGPV_arm64_linux_android)
bart9c7779b2013-11-24 17:48:13 +00001665 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1666# endif
1667
1668#elif defined(VGO_darwin)
1669
1670#endif
1671
1672
1673/*---------------------- wcslen ----------------------*/
1674
1675// This is a wchar_t equivalent to strlen. Unfortunately
1676// we don't have wchar_t available here, but it looks like
1677// a 32 bit int on Linux. I don't know if that is also
1678// valid on MacOSX.
1679
1680#define WCSLEN(soname, fnname) \
1681 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1682 ( const UInt* str ); \
1683 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1684 ( const UInt* str ) \
1685 { \
1686 SizeT i = 0; \
1687 while (str[i] != 0) i++; \
1688 return i; \
1689 }
1690
1691#if defined(VGO_linux)
1692 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1693
1694#elif defined(VGO_darwin)
1695
1696#endif
1697
1698/*---------------------- wcscmp ----------------------*/
1699
1700// This is a wchar_t equivalent to strcmp. We don't
1701// have wchar_t available here, but in the GNU C Library
1702// wchar_t is always 32 bits wide and wcscmp uses signed
1703// comparison, not unsigned as in strcmp function.
1704
1705#define WCSCMP(soname, fnname) \
1706 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1707 ( const Int* s1, const Int* s2 ); \
1708 int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
1709 ( const Int* s1, const Int* s2 ) \
1710 { \
1711 register Int c1; \
1712 register Int c2; \
1713 while (True) { \
1714 c1 = *s1; \
1715 c2 = *s2; \
1716 if (c1 != c2) break; \
1717 if (c1 == 0) break; \
1718 s1++; s2++; \
1719 } \
1720 if (c1 < c2) return -1; \
1721 if (c1 > c2) return 1; \
1722 return 0; \
1723 }
1724
1725#if defined(VGO_linux)
1726 WCSCMP(VG_Z_LIBC_SONAME, wcscmp)
1727#endif
1728
1729/*---------------------- wcscpy ----------------------*/
1730
1731// This is a wchar_t equivalent to strcpy. We don't
1732// have wchar_t available here, but in the GNU C Library
1733// wchar_t is always 32 bits wide.
1734
1735#define WCSCPY(soname, fnname) \
1736 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1737 ( Int* dst, const Int* src ); \
1738 Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
1739 ( Int* dst, const Int* src ) \
1740 { \
1741 const Int* src_orig = src; \
1742 Int* dst_orig = dst; \
1743 \
1744 while (*src) *dst++ = *src++; \
1745 *dst = 0; \
1746 \
1747 /* This checks for overlap after copying, unavoidable without */ \
1748 /* pre-counting length... should be ok */ \
1749 if (is_overlap(dst_orig, \
1750 src_orig, \
1751 (Addr)dst-(Addr)dst_orig+1, \
1752 (Addr)src-(Addr)src_orig+1)) \
1753 RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
1754 \
1755 return dst_orig; \
1756 }
1757
1758#if defined(VGO_linux)
1759 WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
1760#endif
1761
1762
1763/*---------------------- wcschr ----------------------*/
1764
1765// This is a wchar_t equivalent to strchr. We don't
1766// have wchar_t available here, but in the GNU C Library
1767// wchar_t is always 32 bits wide.
1768
1769#define WCSCHR(soname, fnname) \
1770 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
1771 Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
1772 { \
florian70a5de12014-10-22 12:53:16 +00001773 const Int* p = s; \
bart9c7779b2013-11-24 17:48:13 +00001774 while (True) { \
florian70a5de12014-10-22 12:53:16 +00001775 if (*p == c) return CONST_CAST(Int *,p); \
bart9c7779b2013-11-24 17:48:13 +00001776 if (*p == 0) return NULL; \
1777 p++; \
1778 } \
1779 }
1780
1781#if defined(VGO_linux)
1782 WCSCHR(VG_Z_LIBC_SONAME, wcschr)
1783#endif
1784/*---------------------- wcsrchr ----------------------*/
1785
1786// This is a wchar_t equivalent to strrchr. We don't
1787// have wchar_t available here, but in the GNU C Library
1788// wchar_t is always 32 bits wide.
1789
1790#define WCSRCHR(soname, fnname) \
1791 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
1792 Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
1793 { \
florian70a5de12014-10-22 12:53:16 +00001794 const Int* p = s; \
1795 const Int* last = NULL; \
bart9c7779b2013-11-24 17:48:13 +00001796 while (True) { \
1797 if (*p == c) last = p; \
florian70a5de12014-10-22 12:53:16 +00001798 if (*p == 0) return CONST_CAST(Int *,last); \
bart9c7779b2013-11-24 17:48:13 +00001799 p++; \
1800 } \
1801 }
1802
1803#if defined(VGO_linux)
1804 WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
1805#endif
1806
1807/*------------------------------------------------------------*/
1808/*--- Improve definedness checking of process environment ---*/
1809/*------------------------------------------------------------*/
1810
1811#if defined(VGO_linux)
1812
1813/* If these wind up getting generated via a macro, so that multiple
1814 versions of each function exist (as above), use the _EZU variants
1815 to assign equivalance class tags. */
1816
1817/*---------------------- putenv ----------------------*/
1818
1819int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1820int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1821{
1822 OrigFn fn;
1823 Word result;
1824 const HChar* p = string;
1825 VALGRIND_GET_ORIG_FN(fn);
1826 /* Now by walking over the string we magically produce
1827 traces when hitting undefined memory. */
1828 if (p)
1829 while (*p++)
1830 __asm__ __volatile__("" ::: "memory");
1831 CALL_FN_W_W(result, fn, string);
1832 return result;
1833}
1834
1835
1836/*---------------------- unsetenv ----------------------*/
1837
1838int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
1839int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1840{
1841 OrigFn fn;
1842 Word result;
1843 const HChar* p = name;
1844 VALGRIND_GET_ORIG_FN(fn);
1845 /* Now by walking over the string we magically produce
1846 traces when hitting undefined memory. */
1847 if (p)
1848 while (*p++)
1849 __asm__ __volatile__("" ::: "memory");
1850 CALL_FN_W_W(result, fn, name);
1851 return result;
1852}
1853
1854
1855/*---------------------- setenv ----------------------*/
1856
1857/* setenv */
1858int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1859 (const char* name, const char* value, int overwrite);
1860int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1861 (const char* name, const char* value, int overwrite)
1862{
1863 OrigFn fn;
1864 Word result;
1865 const HChar* p;
1866 VALGRIND_GET_ORIG_FN(fn);
1867 /* Now by walking over the string we magically produce
1868 traces when hitting undefined memory. */
1869 if (name)
1870 for (p = name; *p; p++)
1871 __asm__ __volatile__("" ::: "memory");
1872 if (value)
1873 for (p = value; *p; p++)
1874 __asm__ __volatile__("" ::: "memory");
1875 (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
1876 CALL_FN_W_WWW(result, fn, name, value, overwrite);
1877 return result;
1878}
1879
1880#endif /* defined(VGO_linux) */
1881
1882/*--------------------------------------------------------------------*/
1883/*--- end ---*/
1884/*--------------------------------------------------------------------*/