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