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 (at) 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 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__)) 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 (at) 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); 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); 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); 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