1
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 MemCheck, a heavyweight Valgrind tool for
10 detecting memory errors.
11
12 Copyright (C) 2000-2012 Julian Seward
13 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31 */
32
33 #include "pub_tool_basics.h"
34 #include "pub_tool_poolalloc.h"
35 #include "pub_tool_hashtable.h"
36 #include "pub_tool_redir.h"
37 #include "pub_tool_tooliface.h"
38 #include "valgrind.h"
39
40 #include "mc_include.h"
41 #include "memcheck.h"
42
43 /* ---------------------------------------------------------------------
44 We have our own versions of these functions for two reasons:
45 (a) it allows us to do overlap checking
46 (b) some of the normal versions are hyper-optimised, which fools
47 Memcheck and cause spurious value warnings. Our versions are
48 simpler.
49
50 Note that overenthusiastic use of PLT bypassing by the glibc people also
51 means that we need to patch multiple versions of some of the functions to
52 our own implementations.
53
54 THEY RUN ON THE SIMD CPU!
55 ------------------------------------------------------------------ */
56
57 /* Assignment of behavioural equivalence class tags: 2NNNP is intended
58 to be reserved for Memcheck. Current usage:
59
60 20010 STRRCHR
61 20020 STRCHR
62 20030 STRCAT
63 20040 STRNCAT
64 20050 STRLCAT
65 20060 STRNLEN
66 20070 STRLEN
67 20080 STRCPY
68 20090 STRNCPY
69 20100 STRLCPY
70 20110 STRNCMP
71 20120 STRCASECMP
72 20130 STRNCASECMP
73 20140 STRCASECMP_L
74 20150 STRNCASECMP_L
75 20160 STRCMP
76 20170 MEMCHR
77
78 20180 MEMCPY if there's a conflict between memcpy and
79 20181 MEMMOVE memmove, prefer memmove
80
81 20190 MEMCMP
82 20200 STPCPY
83 20210 MEMSET
84 2022P unused (was previously MEMMOVE)
85 20230 BCOPY
86 20240 GLIBC25___MEMMOVE_CHK
87 20250 GLIBC232_STRCHRNUL
88 20260 GLIBC232_RAWMEMCHR
89 20270 GLIBC25___STRCPY_CHK
90 20280 GLIBC25___STPCPY_CHK
91 20290 GLIBC25_MEMPCPY
92 20300 GLIBC26___MEMCPY_CHK
93 20310 STRSTR
94 20320 STRPBRK
95 20330 STRCSPN
96 20340 STRSPN
97 20350 STRCASESTR
98 20360 MEMRCHR
99 20370 WCSLEN
100 */
101
102
103 /* Figure out if [dst .. dst+dstlen-1] overlaps with
104 [src .. src+srclen-1].
105 We assume that the address ranges do not wrap around
106 (which is safe since on Linux addresses >= 0xC0000000
107 are not accessible and the program will segfault in this
108 circumstance, presumably).
109 */
110 static inline
is_overlap(void * dst,const void * src,SizeT dstlen,SizeT srclen)111 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
112 {
113 Addr loS, hiS, loD, hiD;
114
115 if (dstlen == 0 || srclen == 0)
116 return False;
117
118 loS = (Addr)src;
119 loD = (Addr)dst;
120 hiS = loS + srclen - 1;
121 hiD = loD + dstlen - 1;
122
123 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
124 if (loS < loD) {
125 return !(hiS < loD);
126 }
127 else if (loD < loS) {
128 return !(hiD < loS);
129 }
130 else {
131 /* They start at same place. Since we know neither of them has
132 zero length, they must overlap. */
133 return True;
134 }
135 }
136
137
138 /* Call here to exit if we can't continue. On Android we can't call
139 _exit for some reason, so we have to blunt-instrument it. */
140 __attribute__ ((__noreturn__))
my_exit(int x)141 static inline void my_exit ( int x )
142 {
143 # if defined(VGPV_arm_linux_android)
144 __asm__ __volatile__(".word 0xFFFFFFFF");
145 while (1) {}
146 # elif defined(VGPV_x86_linux_android)
147 __asm__ __volatile__("ud2");
148 while (1) {}
149 # else
150 extern __attribute__ ((__noreturn__)) void _exit(int status);
151 _exit(x);
152 # endif
153 }
154
155
156 // This is a macro rather than a function because we don't want to have an
157 // extra function in the stack trace.
158 #define RECORD_OVERLAP_ERROR(s, src, dst, len) \
159 VALGRIND_DO_CLIENT_REQUEST_STMT( \
160 _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR, \
161 s, src, dst, len, 0)
162
163
164 /*---------------------- strrchr ----------------------*/
165
166 #define STRRCHR(soname, fnname) \
167 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
168 char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
169 { \
170 UChar ch = (UChar)((UInt)c); \
171 UChar* p = (UChar*)s; \
172 UChar* last = NULL; \
173 while (True) { \
174 if (*p == ch) last = p; \
175 if (*p == 0) return last; \
176 p++; \
177 } \
178 }
179
180 // Apparently rindex() is the same thing as strrchr()
181 #if defined(VGO_linux)
182 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
183 STRRCHR(VG_Z_LIBC_SONAME, rindex)
184 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
185 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
186 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
187 STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
188 #endif
189
190 #elif defined(VGO_darwin)
191 //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
192 //STRRCHR(VG_Z_LIBC_SONAME, rindex)
193 //STRRCHR(VG_Z_DYLD, strrchr)
194 //STRRCHR(VG_Z_DYLD, rindex)
195 STRRCHR(VG_Z_LIBC_SONAME, strrchr)
196
197 #endif
198
199
200 /*---------------------- strchr ----------------------*/
201
202 #define STRCHR(soname, fnname) \
203 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
204 char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
205 { \
206 UChar ch = (UChar)((UInt)c); \
207 UChar* p = (UChar*)s; \
208 while (True) { \
209 if (*p == ch) return p; \
210 if (*p == 0) return NULL; \
211 p++; \
212 } \
213 }
214
215 // Apparently index() is the same thing as strchr()
216 #if defined(VGO_linux)
217 STRCHR(VG_Z_LIBC_SONAME, strchr)
218 STRCHR(VG_Z_LIBC_SONAME, index)
219 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
220 # if !defined(VGP_x86_linux)
221 STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
222 STRCHR(VG_Z_LD_LINUX_SO_2, index)
223 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
224 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
225 # endif
226
227 #elif defined(VGO_darwin)
228 //STRCHR(VG_Z_LIBC_SONAME, strchr)
229 //STRCHR(VG_Z_LIBC_SONAME, index)
230 //STRCHR(VG_Z_DYLD, strchr)
231 //STRCHR(VG_Z_DYLD, index)
232 STRCHR(VG_Z_LIBC_SONAME, strchr)
233
234 #endif
235
236
237 /*---------------------- strcat ----------------------*/
238
239 #define STRCAT(soname, fnname) \
240 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
241 ( char* dst, const char* src ); \
242 char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
243 ( char* dst, const char* src ) \
244 { \
245 const Char* src_orig = src; \
246 Char* dst_orig = dst; \
247 while (*dst) dst++; \
248 while (*src) *dst++ = *src++; \
249 *dst = 0; \
250 \
251 /* This is a bit redundant, I think; any overlap and the strcat will */ \
252 /* go forever... or until a seg fault occurs. */ \
253 if (is_overlap(dst_orig, \
254 src_orig, \
255 (Addr)dst-(Addr)dst_orig+1, \
256 (Addr)src-(Addr)src_orig+1)) \
257 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
258 \
259 return dst_orig; \
260 }
261
262 #if defined(VGO_linux)
263 STRCAT(VG_Z_LIBC_SONAME, strcat)
264 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
265
266 #elif defined(VGO_darwin)
267 //STRCAT(VG_Z_LIBC_SONAME, strcat)
268
269 #endif
270
271
272 /*---------------------- strncat ----------------------*/
273
274 #define STRNCAT(soname, fnname) \
275 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
276 ( char* dst, const char* src, SizeT n ); \
277 char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
278 ( char* dst, const char* src, SizeT n ) \
279 { \
280 const Char* src_orig = src; \
281 Char* dst_orig = dst; \
282 SizeT m = 0; \
283 \
284 while (*dst) dst++; \
285 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
286 *dst = 0; /* always add null */ \
287 \
288 /* This checks for overlap after copying, unavoidable without */ \
289 /* pre-counting lengths... should be ok */ \
290 if (is_overlap(dst_orig, \
291 src_orig, \
292 (Addr)dst-(Addr)dst_orig+1, \
293 (Addr)src-(Addr)src_orig+1)) \
294 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
295 \
296 return dst_orig; \
297 }
298
299 #if defined(VGO_linux)
300 STRNCAT(VG_Z_LIBC_SONAME, strncat)
301
302 #elif defined(VGO_darwin)
303 //STRNCAT(VG_Z_LIBC_SONAME, strncat)
304 //STRNCAT(VG_Z_DYLD, strncat)
305
306 #endif
307
308
309 /*---------------------- strlcat ----------------------*/
310
311 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed
312 to be nul-terminated after the copy, unless n <= strlen(dst_orig).
313 Returns min(n, strlen(dst_orig)) + strlen(src_orig).
314 Truncation occurred if retval >= n.
315 */
316 #define STRLCAT(soname, fnname) \
317 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
318 ( char* dst, const char* src, SizeT n ); \
319 SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
320 ( char* dst, const char* src, SizeT n ) \
321 { \
322 const Char* src_orig = src; \
323 Char* dst_orig = dst; \
324 SizeT m = 0; \
325 \
326 while (m < n && *dst) { m++; dst++; } \
327 if (m < n) { \
328 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
329 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
330 *dst = 0; \
331 } else { \
332 /* No space to copy anything to dst. m == n */ \
333 } \
334 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
335 while (*src) { m++; src++; } \
336 /* This checks for overlap after copying, unavoidable without */ \
337 /* pre-counting lengths... should be ok */ \
338 if (is_overlap(dst_orig, \
339 src_orig, \
340 (Addr)dst-(Addr)dst_orig+1, \
341 (Addr)src-(Addr)src_orig+1)) \
342 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
343 \
344 return m; \
345 }
346
347 #if defined(VGO_linux)
348
349 #elif defined(VGO_darwin)
350 //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
351 //STRLCAT(VG_Z_DYLD, strlcat)
352 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
353
354 #endif
355
356
357 /*---------------------- strnlen ----------------------*/
358
359 #define STRNLEN(soname, fnname) \
360 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
361 ( const char* str, SizeT n ); \
362 SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
363 ( const char* str, SizeT n ) \
364 { \
365 SizeT i = 0; \
366 while (i < n && str[i] != 0) i++; \
367 return i; \
368 }
369
370 #if defined(VGO_linux)
371 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
372 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
373
374 #elif defined(VGO_darwin)
375 //STRNLEN(VG_Z_LIBC_SONAME, strnlen)
376
377 #endif
378
379
380 /*---------------------- strlen ----------------------*/
381
382 // Note that this replacement often doesn't get used because gcc inlines
383 // calls to strlen() with its own built-in version. This can be very
384 // confusing if you aren't expecting it. Other small functions in
385 // this file may also be inline by gcc.
386
387 #define STRLEN(soname, fnname) \
388 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
389 ( const char* str ); \
390 SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
391 ( const char* str ) \
392 { \
393 SizeT i = 0; \
394 while (str[i] != 0) i++; \
395 return i; \
396 }
397
398 #if defined(VGO_linux)
399 STRLEN(VG_Z_LIBC_SONAME, strlen)
400 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
401 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
402 STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
403 # endif
404
405 #elif defined(VGO_darwin)
406 //STRLEN(VG_Z_LIBC_SONAME, strlen)
407 STRLEN(VG_Z_LIBC_SONAME, strlen)
408
409 #endif
410
411
412 /*---------------------- strcpy ----------------------*/
413
414 #define STRCPY(soname, fnname) \
415 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
416 ( char* dst, const char* src ); \
417 char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
418 ( char* dst, const char* src ) \
419 { \
420 const Char* src_orig = src; \
421 Char* dst_orig = dst; \
422 \
423 while (*src) *dst++ = *src++; \
424 *dst = 0; \
425 \
426 /* This checks for overlap after copying, unavoidable without */ \
427 /* pre-counting length... should be ok */ \
428 if (is_overlap(dst_orig, \
429 src_orig, \
430 (Addr)dst-(Addr)dst_orig+1, \
431 (Addr)src-(Addr)src_orig+1)) \
432 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
433 \
434 return dst_orig; \
435 }
436
437 #if defined(VGO_linux)
438 STRCPY(VG_Z_LIBC_SONAME, strcpy)
439 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
440
441 #elif defined(VGO_darwin)
442 //STRCPY(VG_Z_LIBC_SONAME, strcpy)
443 //STRCPY(VG_Z_DYLD, strcpy)
444 STRCPY(VG_Z_LIBC_SONAME, strcpy)
445
446 #endif
447
448
449 /*---------------------- strncpy ----------------------*/
450
451 #define STRNCPY(soname, fnname) \
452 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
453 ( char* dst, const char* src, SizeT n ); \
454 char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
455 ( char* dst, const char* src, SizeT n ) \
456 { \
457 const Char* src_orig = src; \
458 Char* dst_orig = dst; \
459 SizeT m = 0; \
460 \
461 while (m < n && *src) { m++; *dst++ = *src++; } \
462 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
463 /* but only m+1 bytes of src if terminator was found */ \
464 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
465 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
466 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
467 \
468 return dst_orig; \
469 }
470
471 #if defined(VGO_linux)
472 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
473 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
474
475 #elif defined(VGO_darwin)
476 //STRNCPY(VG_Z_LIBC_SONAME, strncpy)
477 //STRNCPY(VG_Z_DYLD, strncpy)
478 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
479
480 #endif
481
482
483 /*---------------------- strlcpy ----------------------*/
484
485 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
486 Returns strlen(src). Does not zero-fill the remainder of dst. */
487 #define STRLCPY(soname, fnname) \
488 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
489 ( char* dst, const char* src, SizeT n ); \
490 SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
491 ( char* dst, const char* src, SizeT n ) \
492 { \
493 const char* src_orig = src; \
494 char* dst_orig = dst; \
495 SizeT m = 0; \
496 \
497 while (m < n-1 && *src) { m++; *dst++ = *src++; } \
498 /* m non-nul bytes have now been copied, and m <= n-1. */ \
499 /* Check for overlap after copying; all n bytes of dst are relevant, */ \
500 /* but only m+1 bytes of src if terminator was found */ \
501 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
502 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
503 /* Nul-terminate dst. */ \
504 if (n > 0) *dst = 0; \
505 /* Finish counting strlen(src). */ \
506 while (*src) src++; \
507 return src - src_orig; \
508 }
509
510 #if defined(VGO_linux)
511
512 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
513 STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
514 #endif
515
516 #elif defined(VGO_darwin)
517 //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
518 //STRLCPY(VG_Z_DYLD, strlcpy)
519 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
520
521 #endif
522
523
524 /*---------------------- strncmp ----------------------*/
525
526 #define STRNCMP(soname, fnname) \
527 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
528 ( const char* s1, const char* s2, SizeT nmax ); \
529 int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
530 ( const char* s1, const char* s2, SizeT nmax ) \
531 { \
532 SizeT n = 0; \
533 while (True) { \
534 if (n >= nmax) return 0; \
535 if (*s1 == 0 && *s2 == 0) return 0; \
536 if (*s1 == 0) return -1; \
537 if (*s2 == 0) return 1; \
538 \
539 if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
540 if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
541 \
542 s1++; s2++; n++; \
543 } \
544 }
545
546 #if defined(VGO_linux)
547 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
548 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
549
550 #elif defined(VGO_darwin)
551 //STRNCMP(VG_Z_LIBC_SONAME, strncmp)
552 //STRNCMP(VG_Z_DYLD, strncmp)
553 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
554
555 #endif
556
557
558 /*---------------------- strcasecmp ----------------------*/
559
560 #define STRCASECMP(soname, fnname) \
561 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
562 ( const char* s1, const char* s2 ); \
563 int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
564 ( const char* s1, const char* s2 ) \
565 { \
566 extern int tolower(int); \
567 register unsigned char c1; \
568 register unsigned char c2; \
569 while (True) { \
570 c1 = tolower(*(unsigned char *)s1); \
571 c2 = tolower(*(unsigned char *)s2); \
572 if (c1 != c2) break; \
573 if (c1 == 0) break; \
574 s1++; s2++; \
575 } \
576 if ((unsigned char)c1 < (unsigned char)c2) return -1; \
577 if ((unsigned char)c1 > (unsigned char)c2) return 1; \
578 return 0; \
579 }
580
581 #if defined(VGO_linux)
582 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
583 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
584 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
585 # endif
586
587 #elif defined(VGO_darwin)
588 //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
589
590 #endif
591
592
593 /*---------------------- strncasecmp ----------------------*/
594
595 #define STRNCASECMP(soname, fnname) \
596 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
597 ( const char* s1, const char* s2, SizeT nmax ); \
598 int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
599 ( const char* s1, const char* s2, SizeT nmax ) \
600 { \
601 extern int tolower(int); \
602 SizeT n = 0; \
603 while (True) { \
604 if (n >= nmax) return 0; \
605 if (*s1 == 0 && *s2 == 0) return 0; \
606 if (*s1 == 0) return -1; \
607 if (*s2 == 0) return 1; \
608 \
609 if (tolower(*(unsigned char*)s1) \
610 < tolower(*(unsigned char*)s2)) return -1; \
611 if (tolower(*(unsigned char*)s1) \
612 > tolower(*(unsigned char*)s2)) return 1; \
613 \
614 s1++; s2++; n++; \
615 } \
616 }
617
618 #if defined(VGO_linux)
619 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
620 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
621 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
622 # endif
623
624 #elif defined(VGO_darwin)
625 //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
626 //STRNCASECMP(VG_Z_DYLD, strncasecmp)
627
628 #endif
629
630
631 /*---------------------- strcasecmp_l ----------------------*/
632
633 #define STRCASECMP_L(soname, fnname) \
634 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
635 ( const char* s1, const char* s2, void* locale ); \
636 int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
637 ( const char* s1, const char* s2, void* locale ) \
638 { \
639 extern int tolower_l(int, void*) __attribute__((weak)); \
640 register unsigned char c1; \
641 register unsigned char c2; \
642 while (True) { \
643 c1 = tolower_l(*(unsigned char *)s1, locale); \
644 c2 = tolower_l(*(unsigned char *)s2, locale); \
645 if (c1 != c2) break; \
646 if (c1 == 0) break; \
647 s1++; s2++; \
648 } \
649 if ((unsigned char)c1 < (unsigned char)c2) return -1; \
650 if ((unsigned char)c1 > (unsigned char)c2) return 1; \
651 return 0; \
652 }
653
654 #if defined(VGO_linux)
655 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
656 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
657 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
658
659 #elif defined(VGO_darwin)
660 //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
661
662 #endif
663
664
665 /*---------------------- strncasecmp_l ----------------------*/
666
667 #define STRNCASECMP_L(soname, fnname) \
668 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
669 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
670 int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
671 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
672 { \
673 extern int tolower_l(int, void*) __attribute__((weak)); \
674 SizeT n = 0; \
675 while (True) { \
676 if (n >= nmax) return 0; \
677 if (*s1 == 0 && *s2 == 0) return 0; \
678 if (*s1 == 0) return -1; \
679 if (*s2 == 0) return 1; \
680 \
681 if (tolower_l(*(unsigned char*)s1, locale) \
682 < tolower_l(*(unsigned char*)s2, locale)) return -1; \
683 if (tolower_l(*(unsigned char*)s1, locale) \
684 > tolower_l(*(unsigned char*)s2, locale)) return 1; \
685 \
686 s1++; s2++; n++; \
687 } \
688 }
689
690 #if defined(VGO_linux)
691 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
692 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
693 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
694
695 #elif defined(VGO_darwin)
696 //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
697 //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
698
699 #endif
700
701
702 /*---------------------- strcmp ----------------------*/
703
704 #define STRCMP(soname, fnname) \
705 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
706 ( const char* s1, const char* s2 ); \
707 int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
708 ( const char* s1, const char* s2 ) \
709 { \
710 register unsigned char c1; \
711 register unsigned char c2; \
712 while (True) { \
713 c1 = *(unsigned char *)s1; \
714 c2 = *(unsigned char *)s2; \
715 if (c1 != c2) break; \
716 if (c1 == 0) break; \
717 s1++; s2++; \
718 } \
719 if ((unsigned char)c1 < (unsigned char)c2) return -1; \
720 if ((unsigned char)c1 > (unsigned char)c2) return 1; \
721 return 0; \
722 }
723
724 #if defined(VGO_linux)
725 STRCMP(VG_Z_LIBC_SONAME, strcmp)
726 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
727 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
728 STRCMP(VG_Z_LD64_SO_1, strcmp)
729 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
730 STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
731 # endif
732
733 #elif defined(VGO_darwin)
734 //STRCMP(VG_Z_LIBC_SONAME, strcmp)
735 STRCMP(VG_Z_LIBC_SONAME, strcmp)
736
737 #endif
738
739
740 /*---------------------- memchr ----------------------*/
741
742 #define MEMCHR(soname, fnname) \
743 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
744 (const void *s, int c, SizeT n); \
745 void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
746 (const void *s, int c, SizeT n) \
747 { \
748 SizeT i; \
749 UChar c0 = (UChar)c; \
750 UChar* p = (UChar*)s; \
751 for (i = 0; i < n; i++) \
752 if (p[i] == c0) return (void*)(&p[i]); \
753 return NULL; \
754 }
755
756 #if defined(VGO_linux)
757 MEMCHR(VG_Z_LIBC_SONAME, memchr)
758
759 #elif defined(VGO_darwin)
760 //MEMCHR(VG_Z_LIBC_SONAME, memchr)
761 //MEMCHR(VG_Z_DYLD, memchr)
762
763 #endif
764
765
766 /*---------------------- memrchr ----------------------*/
767
768 #define MEMRCHR(soname, fnname) \
769 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
770 (const void *s, int c, SizeT n); \
771 void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
772 (const void *s, int c, SizeT n) \
773 { \
774 SizeT i; \
775 UChar c0 = (UChar)c; \
776 UChar* p = (UChar*)s; \
777 for (i = 0; i < n; i++) \
778 if (p[n-1-i] == c0) return (void*)(&p[n-1-i]); \
779 return NULL; \
780 }
781
782 #if defined(VGO_linux)
783 MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
784
785 #elif defined(VGO_darwin)
786 //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
787 //MEMRCHR(VG_Z_DYLD, memrchr)
788
789 #endif
790
791
792 /*---------------------- memcpy ----------------------*/
793
794 #define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
795 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
796 ( void *dst, const void *src, SizeT len ); \
797 void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
798 ( void *dst, const void *src, SizeT len ) \
799 { \
800 if (do_ol_check && is_overlap(dst, src, len, len)) \
801 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
802 \
803 const Addr WS = sizeof(UWord); /* 8 or 4 */ \
804 const Addr WM = WS - 1; /* 7 or 3 */ \
805 \
806 if (len > 0) { \
807 if (dst < src) { \
808 \
809 /* Copying backwards. */ \
810 SizeT n = len; \
811 Addr d = (Addr)dst; \
812 Addr s = (Addr)src; \
813 \
814 if (((s^d) & WM) == 0) { \
815 /* s and d have same UWord alignment. */ \
816 /* Pull up to a UWord boundary. */ \
817 while ((s & WM) != 0 && n >= 1) \
818 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
819 /* Copy UWords. */ \
820 while (n >= WS) \
821 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
822 if (n == 0) \
823 return dst; \
824 } \
825 if (((s|d) & 1) == 0) { \
826 /* Both are 16-aligned; copy what we can thusly. */ \
827 while (n >= 2) \
828 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
829 } \
830 /* Copy leftovers, or everything if misaligned. */ \
831 while (n >= 1) \
832 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
833 \
834 } else if (dst > src) { \
835 \
836 SizeT n = len; \
837 Addr d = ((Addr)dst) + n; \
838 Addr s = ((Addr)src) + n; \
839 \
840 /* Copying forwards. */ \
841 if (((s^d) & WM) == 0) { \
842 /* s and d have same UWord alignment. */ \
843 /* Back down to a UWord boundary. */ \
844 while ((s & WM) != 0 && n >= 1) \
845 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
846 /* Copy UWords. */ \
847 while (n >= WS) \
848 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
849 if (n == 0) \
850 return dst; \
851 } \
852 if (((s|d) & 1) == 0) { \
853 /* Both are 16-aligned; copy what we can thusly. */ \
854 while (n >= 2) \
855 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
856 } \
857 /* Copy leftovers, or everything if misaligned. */ \
858 while (n >= 1) \
859 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
860 \
861 } \
862 } \
863 \
864 return dst; \
865 }
866
867 #define MEMMOVE(soname, fnname) \
868 MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
869
870 #define MEMCPY(soname, fnname) \
871 MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
872
873 #if defined(VGO_linux)
874 /* For older memcpy we have to use memmove-like semantics and skip
875 the overlap check; sigh; see #275284. */
876 MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
877 MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
878 MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
879 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
880 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
881 /* icc9 blats these around all over the place. Not only in the main
882 executable but various .so's. They are highly tuned and read
883 memory beyond the source boundary (although work correctly and
884 never go across page boundaries), so give errors when run
885 natively, at least for misaligned source arg. Just intercepting
886 in the exe only until we understand more about the problem. See
887 http://bugs.kde.org/show_bug.cgi?id=139776
888 */
889 MEMCPY(NONE, ZuintelZufastZumemcpy)
890
891 #elif defined(VGO_darwin)
892 # if DARWIN_VERS <= DARWIN_10_6
893 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
894 # endif
895 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
896 MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
897
898 #endif
899
900
901 /*---------------------- memcmp ----------------------*/
902
903 #define MEMCMP(soname, fnname) \
904 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
905 ( const void *s1V, const void *s2V, SizeT n ); \
906 int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
907 ( const void *s1V, const void *s2V, SizeT n ) \
908 { \
909 int res; \
910 unsigned char a0; \
911 unsigned char b0; \
912 unsigned char* s1 = (unsigned char*)s1V; \
913 unsigned char* s2 = (unsigned char*)s2V; \
914 \
915 while (n != 0) { \
916 a0 = s1[0]; \
917 b0 = s2[0]; \
918 s1 += 1; \
919 s2 += 1; \
920 res = ((int)a0) - ((int)b0); \
921 if (res != 0) \
922 return res; \
923 n -= 1; \
924 } \
925 return 0; \
926 }
927
928 #if defined(VGO_linux)
929 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
930 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
931 MEMCMP(VG_Z_LD_SO_1, bcmp)
932
933 #elif defined(VGO_darwin)
934 //MEMCMP(VG_Z_LIBC_SONAME, memcmp)
935 //MEMCMP(VG_Z_LIBC_SONAME, bcmp)
936 //MEMCMP(VG_Z_DYLD, memcmp)
937 //MEMCMP(VG_Z_DYLD, bcmp)
938
939 #endif
940
941
942 /*---------------------- stpcpy ----------------------*/
943
944 /* Copy SRC to DEST, returning the address of the terminating '\0' in
945 DEST. (minor variant of strcpy) */
946 #define STPCPY(soname, fnname) \
947 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
948 ( char* dst, const char* src ); \
949 char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
950 ( char* dst, const char* src ) \
951 { \
952 const Char* src_orig = src; \
953 Char* dst_orig = dst; \
954 \
955 while (*src) *dst++ = *src++; \
956 *dst = 0; \
957 \
958 /* This checks for overlap after copying, unavoidable without */ \
959 /* pre-counting length... should be ok */ \
960 if (is_overlap(dst_orig, \
961 src_orig, \
962 (Addr)dst-(Addr)dst_orig+1, \
963 (Addr)src-(Addr)src_orig+1)) \
964 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
965 \
966 return dst; \
967 }
968
969 #if defined(VGO_linux)
970 STPCPY(VG_Z_LIBC_SONAME, stpcpy)
971 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
972 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
973 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
974
975 #elif defined(VGO_darwin)
976 //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
977 //STPCPY(VG_Z_DYLD, stpcpy)
978
979 #endif
980
981
982 /*---------------------- memset ----------------------*/
983
984 /* Why are we bothering to intercept this? It seems entirely
985 pointless. */
986
987 #define MEMSET(soname, fnname) \
988 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
989 (void *s, Int c, SizeT n); \
990 void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
991 (void *s, Int c, SizeT n) \
992 { \
993 Addr a = (Addr)s; \
994 UInt c4 = (c & 0xFF); \
995 c4 = (c4 << 8) | c4; \
996 c4 = (c4 << 16) | c4; \
997 while ((a & 3) != 0 && n >= 1) \
998 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
999 while (n >= 4) \
1000 { *(UInt*)a = c4; a += 4; n -= 4; } \
1001 while (n >= 1) \
1002 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1003 return s; \
1004 }
1005
1006 #if defined(VGO_linux)
1007 MEMSET(VG_Z_LIBC_SONAME, memset)
1008
1009 #elif defined(VGO_darwin)
1010 //MEMSET(VG_Z_LIBC_SONAME, memset)
1011 //MEMSET(VG_Z_DYLD, memset)
1012 MEMSET(VG_Z_LIBC_SONAME, memset)
1013
1014 #endif
1015
1016
1017 /*---------------------- memmove ----------------------*/
1018
1019 /* memmove -- use the MEMMOVE defn above. */
1020
1021 #if defined(VGO_linux)
1022 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1023 MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1024
1025 #elif defined(VGO_darwin)
1026 # if DARWIN_VERS <= DARWIN_10_6
1027 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1028 # endif
1029 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
1030 MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1031
1032 #endif
1033
1034
1035 /*---------------------- bcopy ----------------------*/
1036
1037 #define BCOPY(soname, fnname) \
1038 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1039 (const void *srcV, void *dstV, SizeT n); \
1040 void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
1041 (const void *srcV, void *dstV, SizeT n) \
1042 { \
1043 SizeT i; \
1044 Char* dst = (Char*)dstV; \
1045 Char* src = (Char*)srcV; \
1046 if (dst < src) { \
1047 for (i = 0; i < n; i++) \
1048 dst[i] = src[i]; \
1049 } \
1050 else \
1051 if (dst > src) { \
1052 for (i = 0; i < n; i++) \
1053 dst[n-i-1] = src[n-i-1]; \
1054 } \
1055 }
1056
1057 #if defined(VGO_linux)
1058
1059 #elif defined(VGO_darwin)
1060 //BCOPY(VG_Z_LIBC_SONAME, bcopy)
1061 //BCOPY(VG_Z_DYLD, bcopy)
1062
1063 #endif
1064
1065
1066 /*-------------------- memmove_chk --------------------*/
1067
1068 /* glibc 2.5 variant of memmove which checks the dest is big enough.
1069 There is no specific part of glibc that this is copied from. */
1070 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
1071 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1072 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
1073 void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
1074 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
1075 { \
1076 SizeT i; \
1077 Char* dst = (Char*)dstV; \
1078 Char* src = (Char*)srcV; \
1079 if (destlen < n) \
1080 goto badness; \
1081 if (dst < src) { \
1082 for (i = 0; i < n; i++) \
1083 dst[i] = src[i]; \
1084 } \
1085 else \
1086 if (dst > src) { \
1087 for (i = 0; i < n; i++) \
1088 dst[n-i-1] = src[n-i-1]; \
1089 } \
1090 return dst; \
1091 badness: \
1092 VALGRIND_PRINTF_BACKTRACE( \
1093 "*** memmove_chk: buffer overflow detected ***: " \
1094 "program terminated\n"); \
1095 my_exit(127); \
1096 /*NOTREACHED*/ \
1097 return NULL; \
1098 }
1099
1100 #if defined(VGO_linux)
1101 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
1102
1103 #elif defined(VGO_darwin)
1104
1105 #endif
1106
1107
1108 /*-------------------- strchrnul --------------------*/
1109
1110 /* Find the first occurrence of C in S or the final NUL byte. */
1111 #define GLIBC232_STRCHRNUL(soname, fnname) \
1112 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1113 (const char* s, int c_in); \
1114 char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
1115 (const char* s, int c_in) \
1116 { \
1117 unsigned char c = (unsigned char) c_in; \
1118 unsigned char* char_ptr = (unsigned char *)s; \
1119 while (1) { \
1120 if (*char_ptr == 0) return char_ptr; \
1121 if (*char_ptr == c) return char_ptr; \
1122 char_ptr++; \
1123 } \
1124 }
1125
1126 #if defined(VGO_linux)
1127 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
1128
1129 #elif defined(VGO_darwin)
1130
1131 #endif
1132
1133
1134 /*---------------------- rawmemchr ----------------------*/
1135
1136 /* Find the first occurrence of C in S. */
1137 #define GLIBC232_RAWMEMCHR(soname, fnname) \
1138 char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1139 (const char* s, int c_in); \
1140 char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
1141 (const char* s, int c_in) \
1142 { \
1143 unsigned char c = (unsigned char) c_in; \
1144 unsigned char* char_ptr = (unsigned char *)s; \
1145 while (1) { \
1146 if (*char_ptr == c) return char_ptr; \
1147 char_ptr++; \
1148 } \
1149 }
1150
1151 #if defined (VGO_linux)
1152 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
1153 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
1154
1155 #elif defined(VGO_darwin)
1156
1157 #endif
1158
1159
1160 /*---------------------- strcpy_chk ----------------------*/
1161
1162 /* glibc variant of strcpy that checks the dest is big enough.
1163 Copied from glibc-2.5/debug/test-strcpy_chk.c. */
1164 #define GLIBC25___STRCPY_CHK(soname,fnname) \
1165 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1166 (char* dst, const char* src, SizeT len); \
1167 char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
1168 (char* dst, const char* src, SizeT len) \
1169 { \
1170 char* ret = dst; \
1171 if (! len) \
1172 goto badness; \
1173 while ((*dst++ = *src++) != '\0') \
1174 if (--len == 0) \
1175 goto badness; \
1176 return ret; \
1177 badness: \
1178 VALGRIND_PRINTF_BACKTRACE( \
1179 "*** strcpy_chk: buffer overflow detected ***: " \
1180 "program terminated\n"); \
1181 my_exit(127); \
1182 /*NOTREACHED*/ \
1183 return NULL; \
1184 }
1185
1186 #if defined(VGO_linux)
1187 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
1188
1189 #elif defined(VGO_darwin)
1190
1191 #endif
1192
1193
1194 /*---------------------- stpcpy_chk ----------------------*/
1195
1196 /* glibc variant of stpcpy that checks the dest is big enough.
1197 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
1198 #define GLIBC25___STPCPY_CHK(soname,fnname) \
1199 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1200 (char* dst, const char* src, SizeT len); \
1201 char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
1202 (char* dst, const char* src, SizeT len) \
1203 { \
1204 if (! len) \
1205 goto badness; \
1206 while ((*dst++ = *src++) != '\0') \
1207 if (--len == 0) \
1208 goto badness; \
1209 return dst - 1; \
1210 badness: \
1211 VALGRIND_PRINTF_BACKTRACE( \
1212 "*** stpcpy_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___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
1221
1222 #elif defined(VGO_darwin)
1223
1224 #endif
1225
1226
1227 /*---------------------- mempcpy ----------------------*/
1228
1229 /* mempcpy */
1230 #define GLIBC25_MEMPCPY(soname, fnname) \
1231 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1232 ( void *dst, const void *src, SizeT len ); \
1233 void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
1234 ( void *dst, const void *src, SizeT len ) \
1235 { \
1236 register char *d; \
1237 register char *s; \
1238 SizeT len_saved = len; \
1239 \
1240 if (len == 0) \
1241 return dst; \
1242 \
1243 if (is_overlap(dst, src, len, len)) \
1244 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
1245 \
1246 if ( dst > src ) { \
1247 d = (char *)dst + len - 1; \
1248 s = (char *)src + len - 1; \
1249 while ( len-- ) { \
1250 *d-- = *s--; \
1251 } \
1252 } else if ( dst < src ) { \
1253 d = (char *)dst; \
1254 s = (char *)src; \
1255 while ( len-- ) { \
1256 *d++ = *s++; \
1257 } \
1258 } \
1259 return (void*)( ((char*)dst) + len_saved ); \
1260 }
1261
1262 #if defined(VGO_linux)
1263 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1264 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
1265
1266 #elif defined(VGO_darwin)
1267 //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1268
1269 #endif
1270
1271
1272 /*-------------------- memcpy_chk --------------------*/
1273
1274 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
1275 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1276 (void* dst, const void* src, SizeT len, SizeT dstlen ); \
1277 void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
1278 (void* dst, const void* src, SizeT len, SizeT dstlen ) \
1279 { \
1280 register char *d; \
1281 register char *s; \
1282 \
1283 if (dstlen < len) goto badness; \
1284 \
1285 if (len == 0) \
1286 return dst; \
1287 \
1288 if (is_overlap(dst, src, len, len)) \
1289 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
1290 \
1291 if ( dst > src ) { \
1292 d = (char *)dst + len - 1; \
1293 s = (char *)src + len - 1; \
1294 while ( len-- ) { \
1295 *d-- = *s--; \
1296 } \
1297 } else if ( dst < src ) { \
1298 d = (char *)dst; \
1299 s = (char *)src; \
1300 while ( len-- ) { \
1301 *d++ = *s++; \
1302 } \
1303 } \
1304 return dst; \
1305 badness: \
1306 VALGRIND_PRINTF_BACKTRACE( \
1307 "*** memcpy_chk: buffer overflow detected ***: " \
1308 "program terminated\n"); \
1309 my_exit(127); \
1310 /*NOTREACHED*/ \
1311 return NULL; \
1312 }
1313
1314 #if defined(VGO_linux)
1315 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1316
1317 #elif defined(VGO_darwin)
1318
1319 #endif
1320
1321
1322 /*---------------------- strstr ----------------------*/
1323
1324 #define STRSTR(soname, fnname) \
1325 void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1326 (void* haystack, void* needle); \
1327 void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
1328 (void* haystack, void* needle) \
1329 { \
1330 UChar* h = (UChar*)haystack; \
1331 UChar* n = (UChar*)needle; \
1332 \
1333 /* find the length of n, not including terminating zero */ \
1334 UWord nlen = 0; \
1335 while (n[nlen]) nlen++; \
1336 \
1337 /* if n is the empty string, match immediately. */ \
1338 if (nlen == 0) return h; \
1339 \
1340 /* assert(nlen >= 1); */ \
1341 UChar n0 = n[0]; \
1342 \
1343 while (1) { \
1344 UChar hh = *h; \
1345 if (hh == 0) return NULL; \
1346 if (hh != n0) { h++; continue; } \
1347 \
1348 UWord i; \
1349 for (i = 0; i < nlen; i++) { \
1350 if (n[i] != h[i]) \
1351 break; \
1352 } \
1353 /* assert(i >= 0 && i <= nlen); */ \
1354 if (i == nlen) \
1355 return h; \
1356 \
1357 h++; \
1358 } \
1359 }
1360
1361 #if defined(VGO_linux)
1362 STRSTR(VG_Z_LIBC_SONAME, strstr)
1363
1364 #elif defined(VGO_darwin)
1365
1366 #endif
1367
1368
1369 /*---------------------- strpbrk ----------------------*/
1370
1371 #define STRPBRK(soname, fnname) \
1372 void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1373 (void* sV, void* acceptV); \
1374 void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
1375 (void* sV, void* acceptV) \
1376 { \
1377 UChar* s = (UChar*)sV; \
1378 UChar* accept = (UChar*)acceptV; \
1379 \
1380 /* find the length of 'accept', not including terminating zero */ \
1381 UWord nacc = 0; \
1382 while (accept[nacc]) nacc++; \
1383 \
1384 /* if n is the empty string, fail immediately. */ \
1385 if (nacc == 0) return NULL; \
1386 \
1387 /* assert(nacc >= 1); */ \
1388 while (1) { \
1389 UWord i; \
1390 UChar sc = *s; \
1391 if (sc == 0) \
1392 break; \
1393 for (i = 0; i < nacc; i++) { \
1394 if (sc == accept[i]) \
1395 return s; \
1396 } \
1397 s++; \
1398 } \
1399 \
1400 return NULL; \
1401 }
1402
1403 #if defined(VGO_linux)
1404 STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
1405
1406 #elif defined(VGO_darwin)
1407
1408 #endif
1409
1410
1411 /*---------------------- strcspn ----------------------*/
1412
1413 #define STRCSPN(soname, fnname) \
1414 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1415 (void* sV, void* rejectV); \
1416 SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
1417 (void* sV, void* rejectV) \
1418 { \
1419 UChar* s = (UChar*)sV; \
1420 UChar* reject = (UChar*)rejectV; \
1421 \
1422 /* find the length of 'reject', not including terminating zero */ \
1423 UWord nrej = 0; \
1424 while (reject[nrej]) nrej++; \
1425 \
1426 UWord len = 0; \
1427 while (1) { \
1428 UWord i; \
1429 UChar sc = *s; \
1430 if (sc == 0) \
1431 break; \
1432 for (i = 0; i < nrej; i++) { \
1433 if (sc == reject[i]) \
1434 break; \
1435 } \
1436 /* assert(i >= 0 && i <= nrej); */ \
1437 if (i < nrej) \
1438 break; \
1439 s++; \
1440 len++; \
1441 } \
1442 \
1443 return len; \
1444 }
1445
1446 #if defined(VGO_linux)
1447 STRCSPN(VG_Z_LIBC_SONAME, strcspn)
1448
1449 #elif defined(VGO_darwin)
1450
1451 #endif
1452
1453
1454 /*---------------------- strspn ----------------------*/
1455
1456 #define STRSPN(soname, fnname) \
1457 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1458 (void* sV, void* acceptV); \
1459 SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
1460 (void* sV, void* acceptV) \
1461 { \
1462 UChar* s = (UChar*)sV; \
1463 UChar* accept = (UChar*)acceptV; \
1464 \
1465 /* find the length of 'accept', not including terminating zero */ \
1466 UWord nacc = 0; \
1467 while (accept[nacc]) nacc++; \
1468 if (nacc == 0) return 0; \
1469 \
1470 UWord len = 0; \
1471 while (1) { \
1472 UWord i; \
1473 UChar sc = *s; \
1474 if (sc == 0) \
1475 break; \
1476 for (i = 0; i < nacc; i++) { \
1477 if (sc == accept[i]) \
1478 break; \
1479 } \
1480 /* assert(i >= 0 && i <= nacc); */ \
1481 if (i == nacc) \
1482 break; \
1483 s++; \
1484 len++; \
1485 } \
1486 \
1487 return len; \
1488 }
1489
1490 #if defined(VGO_linux)
1491 STRSPN(VG_Z_LIBC_SONAME, strspn)
1492
1493 #elif defined(VGO_darwin)
1494
1495 #endif
1496
1497
1498 /*---------------------- strcasestr ----------------------*/
1499
1500 #define STRCASESTR(soname, fnname) \
1501 void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1502 (void* haystack, void* needle); \
1503 void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
1504 (void* haystack, void* needle) \
1505 { \
1506 extern int tolower(int); \
1507 UChar* h = (UChar*)haystack; \
1508 UChar* n = (UChar*)needle; \
1509 \
1510 /* find the length of n, not including terminating zero */ \
1511 UWord nlen = 0; \
1512 while (n[nlen]) nlen++; \
1513 \
1514 /* if n is the empty string, match immediately. */ \
1515 if (nlen == 0) return h; \
1516 \
1517 /* assert(nlen >= 1); */ \
1518 UChar n0 = tolower(n[0]); \
1519 \
1520 while (1) { \
1521 UChar hh = tolower(*h); \
1522 if (hh == 0) return NULL; \
1523 if (hh != n0) { h++; continue; } \
1524 \
1525 UWord i; \
1526 for (i = 0; i < nlen; i++) { \
1527 if (tolower(n[i]) != tolower(h[i])) \
1528 break; \
1529 } \
1530 /* assert(i >= 0 && i <= nlen); */ \
1531 if (i == nlen) \
1532 return h; \
1533 \
1534 h++; \
1535 } \
1536 }
1537
1538 #if defined(VGO_linux)
1539 # if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
1540 STRCASESTR(VG_Z_LIBC_SONAME, strcasestr)
1541 # endif
1542
1543 #elif defined(VGO_darwin)
1544
1545 #endif
1546
1547
1548 /*---------------------- wcslen ----------------------*/
1549
1550 // This is a wchar_t equivalent to strlen. Unfortunately
1551 // we don't have wchar_t available here, but it looks like
1552 // a 32 bit int on Linux. I don't know if that is also
1553 // valid on MacOSX.
1554
1555 #define WCSLEN(soname, fnname) \
1556 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1557 ( const UInt* str ); \
1558 SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
1559 ( const UInt* str ) \
1560 { \
1561 SizeT i = 0; \
1562 while (str[i] != 0) i++; \
1563 return i; \
1564 }
1565
1566 #if defined(VGO_linux)
1567 WCSLEN(VG_Z_LIBC_SONAME, wcslen)
1568
1569 #elif defined(VGO_darwin)
1570
1571 #endif
1572
1573
1574 /*------------------------------------------------------------*/
1575 /*--- Improve definedness checking of process environment ---*/
1576 /*------------------------------------------------------------*/
1577
1578 #if defined(VGO_linux)
1579
1580 /* If these wind up getting generated via a macro, so that multiple
1581 versions of each function exist (as above), use the _EZU variants
1582 to assign equivalance class tags. */
1583
1584 /*---------------------- putenv ----------------------*/
1585
1586 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,putenv)1587 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1588 {
1589 OrigFn fn;
1590 Word result;
1591 const char* p = string;
1592 VALGRIND_GET_ORIG_FN(fn);
1593 /* Now by walking over the string we magically produce
1594 traces when hitting undefined memory. */
1595 if (p)
1596 while (*p++)
1597 __asm__ __volatile__("" ::: "memory");
1598 CALL_FN_W_W(result, fn, string);
1599 return result;
1600 }
1601
1602
1603 /*---------------------- unsetenv ----------------------*/
1604
1605 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,unsetenv)1606 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1607 {
1608 OrigFn fn;
1609 Word result;
1610 const char* p = name;
1611 VALGRIND_GET_ORIG_FN(fn);
1612 /* Now by walking over the string we magically produce
1613 traces when hitting undefined memory. */
1614 if (p)
1615 while (*p++)
1616 __asm__ __volatile__("" ::: "memory");
1617 CALL_FN_W_W(result, fn, name);
1618 return result;
1619 }
1620
1621
1622 /*---------------------- setenv ----------------------*/
1623
1624 /* setenv */
1625 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1626 (const char* name, const char* value, int overwrite);
VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME,setenv)1627 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1628 (const char* name, const char* value, int overwrite)
1629 {
1630 OrigFn fn;
1631 Word result;
1632 const char* p;
1633 VALGRIND_GET_ORIG_FN(fn);
1634 /* Now by walking over the string we magically produce
1635 traces when hitting undefined memory. */
1636 if (name)
1637 for (p = name; *p; p++)
1638 __asm__ __volatile__("" ::: "memory");
1639 if (value)
1640 for (p = value; *p; p++)
1641 __asm__ __volatile__("" ::: "memory");
1642 VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
1643 CALL_FN_W_WWW(result, fn, name, value, overwrite);
1644 return result;
1645 }
1646
1647 #endif /* defined(VGO_linux) */
1648
1649 /*--------------------------------------------------------------------*/
1650 /*--- end ---*/
1651 /*--------------------------------------------------------------------*/
1652