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-2010 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_hashtable.h" 35 #include "pub_tool_redir.h" 36 #include "pub_tool_tooliface.h" 37 #include "valgrind.h" 38 39 #include "mc_include.h" 40 #include "memcheck.h" 41 42 /* --------------------------------------------------------------------- 43 We have our own versions of these functions for two reasons: 44 (a) it allows us to do overlap checking 45 (b) some of the normal versions are hyper-optimised, which fools 46 Memcheck and cause spurious value warnings. Our versions are 47 simpler. 48 49 Note that overenthusiastic use of PLT bypassing by the glibc people also 50 means that we need to patch multiple versions of some of the functions to 51 our own implementations. 52 53 THEY RUN ON THE SIMD CPU! 54 ------------------------------------------------------------------ */ 55 56 /* Figure out if [dst .. dst+dstlen-1] overlaps with 57 [src .. src+srclen-1]. 58 We assume that the address ranges do not wrap around 59 (which is safe since on Linux addresses >= 0xC0000000 60 are not accessible and the program will segfault in this 61 circumstance, presumably). 62 */ 63 static __inline__ 64 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen ) 65 { 66 Addr loS, hiS, loD, hiD; 67 68 if (dstlen == 0 || srclen == 0) 69 return False; 70 71 loS = (Addr)src; 72 loD = (Addr)dst; 73 hiS = loS + srclen - 1; 74 hiD = loD + dstlen - 1; 75 76 /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */ 77 if (loS < loD) { 78 return !(hiS < loD); 79 } 80 else if (loD < loS) { 81 return !(hiD < loS); 82 } 83 else { 84 /* They start at same place. Since we know neither of them has 85 zero length, they must overlap. */ 86 return True; 87 } 88 } 89 90 // This is a macro rather than a function because we don't want to have an 91 // extra function in the stack trace. 92 #define RECORD_OVERLAP_ERROR(s, src, dst, len) \ 93 { \ 94 Word unused_res; \ 95 VALGRIND_DO_CLIENT_REQUEST(unused_res, 0, \ 96 _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR, \ 97 s, src, dst, len, 0); \ 98 } 99 100 101 #define STRRCHR(soname, fnname) \ 102 char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \ 103 char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \ 104 { \ 105 UChar ch = (UChar)((UInt)c); \ 106 UChar* p = (UChar*)s; \ 107 UChar* last = NULL; \ 108 while (True) { \ 109 if (*p == ch) last = p; \ 110 if (*p == 0) return last; \ 111 p++; \ 112 } \ 113 } 114 115 // Apparently rindex() is the same thing as strrchr() 116 STRRCHR(VG_Z_LIBC_SONAME, strrchr) 117 STRRCHR(VG_Z_LIBC_SONAME, rindex) 118 #if defined(VGO_linux) 119 STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr) 120 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex) 121 #elif defined(VGO_darwin) 122 STRRCHR(VG_Z_DYLD, strrchr) 123 STRRCHR(VG_Z_DYLD, rindex) 124 #endif 125 126 127 #define STRCHR(soname, fnname) \ 128 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \ 129 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \ 130 { \ 131 UChar ch = (UChar)((UInt)c); \ 132 UChar* p = (UChar*)s; \ 133 while (True) { \ 134 if (*p == ch) return p; \ 135 if (*p == 0) return NULL; \ 136 p++; \ 137 } \ 138 } 139 140 // Apparently index() is the same thing as strchr() 141 STRCHR(VG_Z_LIBC_SONAME, strchr) 142 STRCHR(VG_Z_LIBC_SONAME, index) 143 #if defined(VGO_linux) 144 STRCHR(VG_Z_LIBC_SONAME, __GI_strchr) 145 STRCHR(VG_Z_LD_LINUX_SO_2, strchr) 146 STRCHR(VG_Z_LD_LINUX_SO_2, index) 147 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr) 148 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index) 149 #elif defined(VGO_darwin) 150 STRCHR(VG_Z_DYLD, strchr) 151 STRCHR(VG_Z_DYLD, index) 152 #endif 153 154 155 #define STRCAT(soname, fnname) \ 156 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \ 157 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \ 158 { \ 159 const Char* src_orig = src; \ 160 Char* dst_orig = dst; \ 161 while (*dst) dst++; \ 162 while (*src) *dst++ = *src++; \ 163 *dst = 0; \ 164 \ 165 /* This is a bit redundant, I think; any overlap and the strcat will */ \ 166 /* go forever... or until a seg fault occurs. */ \ 167 if (is_overlap(dst_orig, \ 168 src_orig, \ 169 (Addr)dst-(Addr)dst_orig+1, \ 170 (Addr)src-(Addr)src_orig+1)) \ 171 RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \ 172 \ 173 return dst_orig; \ 174 } 175 176 STRCAT(VG_Z_LIBC_SONAME, strcat) 177 #if defined(VGO_linux) 178 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat) 179 #endif 180 181 #define STRNCAT(soname, fnname) \ 182 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 183 ( char* dst, const char* src, SizeT n ); \ 184 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 185 ( char* dst, const char* src, SizeT n ) \ 186 { \ 187 const Char* src_orig = src; \ 188 Char* dst_orig = dst; \ 189 SizeT m = 0; \ 190 \ 191 while (*dst) dst++; \ 192 while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \ 193 *dst = 0; /* always add null */ \ 194 \ 195 /* This checks for overlap after copying, unavoidable without */ \ 196 /* pre-counting lengths... should be ok */ \ 197 if (is_overlap(dst_orig, \ 198 src_orig, \ 199 (Addr)dst-(Addr)dst_orig+1, \ 200 (Addr)src-(Addr)src_orig+1)) \ 201 RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \ 202 \ 203 return dst_orig; \ 204 } 205 206 STRNCAT(VG_Z_LIBC_SONAME, strncat) 207 #if defined(VGO_darwin) 208 STRNCAT(VG_Z_DYLD, strncat) 209 #endif 210 211 212 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed 213 to be nul-terminated after the copy, unless n <= strlen(dst_orig). 214 Returns min(n, strlen(dst_orig)) + strlen(src_orig). 215 Truncation occurred if retval >= n. 216 */ 217 #define STRLCAT(soname, fnname) \ 218 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 219 ( char* dst, const char* src, SizeT n ); \ 220 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 221 ( char* dst, const char* src, SizeT n ) \ 222 { \ 223 const Char* src_orig = src; \ 224 Char* dst_orig = dst; \ 225 SizeT m = 0; \ 226 \ 227 while (m < n && *dst) { m++; dst++; } \ 228 if (m < n) { \ 229 /* Fill as far as dst_orig[n-2], then nul-terminate. */ \ 230 while (m < n-1 && *src) { m++; *dst++ = *src++; } \ 231 *dst = 0; \ 232 } else { \ 233 /* No space to copy anything to dst. m == n */ \ 234 } \ 235 /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \ 236 while (*src) { m++; src++; } \ 237 /* This checks for overlap after copying, unavoidable without */ \ 238 /* pre-counting lengths... should be ok */ \ 239 if (is_overlap(dst_orig, \ 240 src_orig, \ 241 (Addr)dst-(Addr)dst_orig+1, \ 242 (Addr)src-(Addr)src_orig+1)) \ 243 RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \ 244 \ 245 return m; \ 246 } 247 248 #if defined(VGO_darwin) 249 STRLCAT(VG_Z_LIBC_SONAME, strlcat) 250 STRLCAT(VG_Z_DYLD, strlcat) 251 #endif 252 253 254 #define STRNLEN(soname, fnname) \ 255 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \ 256 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \ 257 { \ 258 SizeT i = 0; \ 259 while (i < n && str[i] != 0) i++; \ 260 return i; \ 261 } 262 263 STRNLEN(VG_Z_LIBC_SONAME, strnlen) 264 #if defined(VGO_linux) 265 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen) 266 #endif 267 268 269 // Note that this replacement often doesn't get used because gcc inlines 270 // calls to strlen() with its own built-in version. This can be very 271 // confusing if you aren't expecting it. Other small functions in this file 272 // may also be inline by gcc. 273 #define STRLEN(soname, fnname) \ 274 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \ 275 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \ 276 { \ 277 SizeT i = 0; \ 278 while (str[i] != 0) i++; \ 279 return i; \ 280 } 281 282 STRLEN(VG_Z_LIBC_SONAME, strlen) 283 #if defined(VGO_linux) 284 STRLEN(VG_Z_LIBC_SONAME, __GI_strlen) 285 STRLEN(VG_Z_LD_LINUX_SO_2, strlen) 286 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen) 287 #endif 288 289 290 #define STRCPY(soname, fnname) \ 291 char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \ 292 char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \ 293 { \ 294 const Char* src_orig = src; \ 295 Char* dst_orig = dst; \ 296 \ 297 while (*src) *dst++ = *src++; \ 298 *dst = 0; \ 299 \ 300 /* This checks for overlap after copying, unavoidable without */ \ 301 /* pre-counting length... should be ok */ \ 302 if (is_overlap(dst_orig, \ 303 src_orig, \ 304 (Addr)dst-(Addr)dst_orig+1, \ 305 (Addr)src-(Addr)src_orig+1)) \ 306 RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \ 307 \ 308 return dst_orig; \ 309 } 310 311 STRCPY(VG_Z_LIBC_SONAME, strcpy) 312 #if defined(VGO_linux) 313 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy) 314 #elif defined(VGO_darwin) 315 STRCPY(VG_Z_DYLD, strcpy) 316 #endif 317 318 319 #define STRNCPY(soname, fnname) \ 320 char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \ 321 ( char* dst, const char* src, SizeT n ); \ 322 char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \ 323 ( char* dst, const char* src, SizeT n ) \ 324 { \ 325 const Char* src_orig = src; \ 326 Char* dst_orig = dst; \ 327 SizeT m = 0; \ 328 \ 329 while (m < n && *src) { m++; *dst++ = *src++; } \ 330 /* Check for overlap after copying; all n bytes of dst are relevant, */ \ 331 /* but only m+1 bytes of src if terminator was found */ \ 332 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \ 333 RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \ 334 while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \ 335 \ 336 return dst_orig; \ 337 } 338 339 STRNCPY(VG_Z_LIBC_SONAME, strncpy) 340 #if defined(VGO_linux) 341 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy) 342 #elif defined(VGO_darwin) 343 STRNCPY(VG_Z_DYLD, strncpy) 344 #endif 345 346 347 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0. 348 Returns strlen(src). Does not zero-fill the remainder of dst. */ 349 #define STRLCPY(soname, fnname) \ 350 SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \ 351 ( char* dst, const char* src, SizeT n ); \ 352 SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \ 353 ( char* dst, const char* src, SizeT n ) \ 354 { \ 355 const char* src_orig = src; \ 356 char* dst_orig = dst; \ 357 SizeT m = 0; \ 358 \ 359 while (m < n-1 && *src) { m++; *dst++ = *src++; } \ 360 /* m non-nul bytes have now been copied, and m <= n-1. */ \ 361 /* Check for overlap after copying; all n bytes of dst are relevant, */ \ 362 /* but only m+1 bytes of src if terminator was found */ \ 363 if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \ 364 RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \ 365 /* Nul-terminate dst. */ \ 366 if (n > 0) *dst = 0; \ 367 /* Finish counting strlen(src). */ \ 368 while (*src) src++; \ 369 return src - src_orig; \ 370 } 371 372 #if defined(VGO_darwin) 373 STRLCPY(VG_Z_LIBC_SONAME, strlcpy) 374 STRLCPY(VG_Z_DYLD, strlcpy) 375 #endif 376 377 378 #define STRNCMP(soname, fnname) \ 379 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 380 ( const char* s1, const char* s2, SizeT nmax ); \ 381 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 382 ( const char* s1, const char* s2, SizeT nmax ) \ 383 { \ 384 SizeT n = 0; \ 385 while (True) { \ 386 if (n >= nmax) return 0; \ 387 if (*s1 == 0 && *s2 == 0) return 0; \ 388 if (*s1 == 0) return -1; \ 389 if (*s2 == 0) return 1; \ 390 \ 391 if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \ 392 if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \ 393 \ 394 s1++; s2++; n++; \ 395 } \ 396 } 397 398 STRNCMP(VG_Z_LIBC_SONAME, strncmp) 399 #if defined(VGO_linux) 400 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp) 401 #elif defined(VGO_darwin) 402 STRNCMP(VG_Z_DYLD, strncmp) 403 #endif 404 405 406 #define STRCASECMP(soname, fnname) \ 407 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 408 ( const char* s1, const char* s2 ); \ 409 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 410 ( const char* s1, const char* s2 ) \ 411 { \ 412 extern int tolower(int); \ 413 register unsigned char c1; \ 414 register unsigned char c2; \ 415 while (True) { \ 416 c1 = tolower(*(unsigned char *)s1); \ 417 c2 = tolower(*(unsigned char *)s2); \ 418 if (c1 != c2) break; \ 419 if (c1 == 0) break; \ 420 s1++; s2++; \ 421 } \ 422 if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 423 if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 424 return 0; \ 425 } 426 427 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp) 428 #if defined(VGO_linux) 429 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp) 430 #endif 431 432 433 #define STRNCASECMP(soname, fnname) \ 434 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 435 ( const char* s1, const char* s2, SizeT nmax ); \ 436 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 437 ( const char* s1, const char* s2, SizeT nmax ) \ 438 { \ 439 extern int tolower(int); \ 440 SizeT n = 0; \ 441 while (True) { \ 442 if (n >= nmax) return 0; \ 443 if (*s1 == 0 && *s2 == 0) return 0; \ 444 if (*s1 == 0) return -1; \ 445 if (*s2 == 0) return 1; \ 446 \ 447 if (tolower(*(unsigned char*)s1) < tolower(*(unsigned char*)s2)) return -1; \ 448 if (tolower(*(unsigned char*)s1) > tolower(*(unsigned char*)s2)) return 1; \ 449 \ 450 s1++; s2++; n++; \ 451 } \ 452 } 453 454 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp) 455 #if defined(VGO_linux) 456 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp) 457 #elif defined(VGO_darwin) 458 STRNCASECMP(VG_Z_DYLD, strncasecmp) 459 #endif 460 461 462 #define STRCASECMP_L(soname, fnname) \ 463 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 464 ( const char* s1, const char* s2, void* locale ); \ 465 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 466 ( const char* s1, const char* s2, void* locale ) \ 467 { \ 468 extern int tolower_l(int, void*) __attribute__((weak)); \ 469 register unsigned char c1; \ 470 register unsigned char c2; \ 471 while (True) { \ 472 c1 = tolower_l(*(unsigned char *)s1, locale); \ 473 c2 = tolower_l(*(unsigned char *)s2, locale); \ 474 if (c1 != c2) break; \ 475 if (c1 == 0) break; \ 476 s1++; s2++; \ 477 } \ 478 if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 479 if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 480 return 0; \ 481 } 482 483 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l) 484 #if defined(VGO_linux) 485 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l) 486 #endif 487 488 489 #define STRNCASECMP_L(soname, fnname) \ 490 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 491 ( const char* s1, const char* s2, SizeT nmax, void* locale ); \ 492 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 493 ( const char* s1, const char* s2, SizeT nmax, void* locale ) \ 494 { \ 495 extern int tolower_l(int, void*) __attribute__((weak)); \ 496 SizeT n = 0; \ 497 while (True) { \ 498 if (n >= nmax) return 0; \ 499 if (*s1 == 0 && *s2 == 0) return 0; \ 500 if (*s1 == 0) return -1; \ 501 if (*s2 == 0) return 1; \ 502 \ 503 if (tolower_l(*(unsigned char*)s1, locale) < tolower_l(*(unsigned char*)s2, locale)) return -1; \ 504 if (tolower_l(*(unsigned char*)s1, locale) > tolower_l(*(unsigned char*)s2, locale)) return 1; \ 505 \ 506 s1++; s2++; n++; \ 507 } \ 508 } 509 510 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l) 511 #if defined(VGO_linux) 512 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l) 513 #elif defined(VGO_darwin) 514 STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l) 515 #endif 516 517 518 #define STRCMP(soname, fnname) \ 519 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 520 ( const char* s1, const char* s2 ); \ 521 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 522 ( const char* s1, const char* s2 ) \ 523 { \ 524 register unsigned char c1; \ 525 register unsigned char c2; \ 526 while (True) { \ 527 c1 = *(unsigned char *)s1; \ 528 c2 = *(unsigned char *)s2; \ 529 if (c1 != c2) break; \ 530 if (c1 == 0) break; \ 531 s1++; s2++; \ 532 } \ 533 if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 534 if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 535 return 0; \ 536 } 537 538 STRCMP(VG_Z_LIBC_SONAME, strcmp) 539 #if defined(VGO_linux) 540 STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp) 541 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp) 542 STRCMP(VG_Z_LD64_SO_1, strcmp) 543 #endif 544 545 546 #define MEMCHR(soname, fnname) \ 547 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \ 548 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \ 549 { \ 550 SizeT i; \ 551 UChar c0 = (UChar)c; \ 552 UChar* p = (UChar*)s; \ 553 for (i = 0; i < n; i++) \ 554 if (p[i] == c0) return (void*)(&p[i]); \ 555 return NULL; \ 556 } 557 558 MEMCHR(VG_Z_LIBC_SONAME, memchr) 559 #if defined(VGO_darwin) 560 MEMCHR(VG_Z_DYLD, memchr) 561 #endif 562 563 564 #define MEMCPY(soname, fnname) \ 565 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 566 ( void *dst, const void *src, SizeT len ); \ 567 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 568 ( void *dst, const void *src, SizeT len ) \ 569 { \ 570 if (is_overlap(dst, src, len, len)) \ 571 RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \ 572 \ 573 const Addr WS = sizeof(UWord); /* 8 or 4 */ \ 574 const Addr WM = WS - 1; /* 7 or 3 */ \ 575 \ 576 if (dst < src) { \ 577 \ 578 /* Copying backwards. */ \ 579 SizeT n = len; \ 580 Addr d = (Addr)dst; \ 581 Addr s = (Addr)src; \ 582 \ 583 if (((s^d) & WM) == 0) { \ 584 /* s and d have same UWord alignment. */ \ 585 /* Pull up to a UWord boundary. */ \ 586 while ((s & WM) != 0 && n >= 1) \ 587 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \ 588 /* Copy UWords. */ \ 589 while (n >= WS) \ 590 { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \ 591 if (n == 0) \ 592 return dst; \ 593 } \ 594 if (((s|d) & 1) == 0) { \ 595 /* Both are 16-aligned; copy what we can thusly. */ \ 596 while (n >= 2) \ 597 { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \ 598 } \ 599 /* Copy leftovers, or everything if misaligned. */ \ 600 while (n >= 1) \ 601 { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \ 602 \ 603 } else if (dst > src) { \ 604 \ 605 SizeT n = len; \ 606 Addr d = ((Addr)dst) + n; \ 607 Addr s = ((Addr)src) + n; \ 608 \ 609 /* Copying forwards. */ \ 610 if (((s^d) & WM) == 0) { \ 611 /* s and d have same UWord alignment. */ \ 612 /* Back down to a UWord boundary. */ \ 613 while ((s & WM) != 0 && n >= 1) \ 614 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \ 615 /* Copy UWords. */ \ 616 while (n >= WS) \ 617 { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \ 618 if (n == 0) \ 619 return dst; \ 620 } \ 621 if (((s|d) & 1) == 0) { \ 622 /* Both are 16-aligned; copy what we can thusly. */ \ 623 while (n >= 2) \ 624 { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \ 625 } \ 626 /* Copy leftovers, or everything if misaligned. */ \ 627 while (n >= 1) \ 628 { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \ 629 \ 630 } \ 631 \ 632 return dst; \ 633 } 634 635 MEMCPY(VG_Z_LIBC_SONAME, memcpy) 636 #if defined(VGO_linux) 637 MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */ 638 MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */ 639 #elif defined(VGO_darwin) 640 MEMCPY(VG_Z_DYLD, memcpy) 641 #endif 642 /* icc9 blats these around all over the place. Not only in the main 643 executable but various .so's. They are highly tuned and read 644 memory beyond the source boundary (although work correctly and 645 never go across page boundaries), so give errors when run natively, 646 at least for misaligned source arg. Just intercepting in the exe 647 only until we understand more about the problem. See 648 http://bugs.kde.org/show_bug.cgi?id=139776 649 */ 650 MEMCPY(NONE, _intel_fast_memcpy) 651 652 653 #define MEMCMP(soname, fnname) \ 654 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 655 ( const void *s1V, const void *s2V, SizeT n ); \ 656 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 657 ( const void *s1V, const void *s2V, SizeT n ) \ 658 { \ 659 int res; \ 660 unsigned char a0; \ 661 unsigned char b0; \ 662 unsigned char* s1 = (unsigned char*)s1V; \ 663 unsigned char* s2 = (unsigned char*)s2V; \ 664 \ 665 while (n != 0) { \ 666 a0 = s1[0]; \ 667 b0 = s2[0]; \ 668 s1 += 1; \ 669 s2 += 1; \ 670 res = ((int)a0) - ((int)b0); \ 671 if (res != 0) \ 672 return res; \ 673 n -= 1; \ 674 } \ 675 return 0; \ 676 } 677 678 MEMCMP(VG_Z_LIBC_SONAME, memcmp) 679 MEMCMP(VG_Z_LIBC_SONAME, bcmp) 680 #if defined(VGO_linux) 681 MEMCMP(VG_Z_LD_SO_1, bcmp) 682 #elif defined(VGO_darwin) 683 MEMCMP(VG_Z_DYLD, memcmp) 684 MEMCMP(VG_Z_DYLD, bcmp) 685 #endif 686 687 688 /* Copy SRC to DEST, returning the address of the terminating '\0' in 689 DEST. (minor variant of strcpy) */ 690 #define STPCPY(soname, fnname) \ 691 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \ 692 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \ 693 { \ 694 const Char* src_orig = src; \ 695 Char* dst_orig = dst; \ 696 \ 697 while (*src) *dst++ = *src++; \ 698 *dst = 0; \ 699 \ 700 /* This checks for overlap after copying, unavoidable without */ \ 701 /* pre-counting length... should be ok */ \ 702 if (is_overlap(dst_orig, \ 703 src_orig, \ 704 (Addr)dst-(Addr)dst_orig+1, \ 705 (Addr)src-(Addr)src_orig+1)) \ 706 RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \ 707 \ 708 return dst; \ 709 } 710 711 STPCPY(VG_Z_LIBC_SONAME, stpcpy) 712 #if defined(VGO_linux) 713 STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy) 714 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy) 715 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy) 716 #elif defined(VGO_darwin) 717 STPCPY(VG_Z_DYLD, stpcpy) 718 #endif 719 720 721 #define MEMSET(soname, fnname) \ 722 void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n); \ 723 void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n) \ 724 { \ 725 Addr a = (Addr)s; \ 726 UInt c4 = (c & 0xFF); \ 727 c4 = (c4 << 8) | c4; \ 728 c4 = (c4 << 16) | c4; \ 729 while ((a & 3) != 0 && n >= 1) \ 730 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \ 731 while (n >= 4) \ 732 { *(UInt*)a = c4; a += 4; n -= 4; } \ 733 while (n >= 1) \ 734 { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \ 735 return s; \ 736 } 737 738 MEMSET(VG_Z_LIBC_SONAME, memset) 739 #if defined(VGO_darwin) 740 MEMSET(VG_Z_DYLD, memset) 741 #endif 742 743 744 #define MEMMOVE(soname, fnname) \ 745 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 746 (void *dstV, const void *srcV, SizeT n); \ 747 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 748 (void *dstV, const void *srcV, SizeT n) \ 749 { \ 750 SizeT i; \ 751 Char* dst = (Char*)dstV; \ 752 Char* src = (Char*)srcV; \ 753 if (dst < src) { \ 754 for (i = 0; i < n; i++) \ 755 dst[i] = src[i]; \ 756 } \ 757 else \ 758 if (dst > src) { \ 759 for (i = 0; i < n; i++) \ 760 dst[n-i-1] = src[n-i-1]; \ 761 } \ 762 return dst; \ 763 } 764 765 MEMMOVE(VG_Z_LIBC_SONAME, memmove) 766 #if defined(VGO_darwin) 767 MEMMOVE(VG_Z_DYLD, memmove) 768 #endif 769 770 771 #define BCOPY(soname, fnname) \ 772 void VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 773 (const void *srcV, void *dstV, SizeT n); \ 774 void VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 775 (const void *srcV, void *dstV, SizeT n) \ 776 { \ 777 SizeT i; \ 778 Char* dst = (Char*)dstV; \ 779 Char* src = (Char*)srcV; \ 780 if (dst < src) { \ 781 for (i = 0; i < n; i++) \ 782 dst[i] = src[i]; \ 783 } \ 784 else \ 785 if (dst > src) { \ 786 for (i = 0; i < n; i++) \ 787 dst[n-i-1] = src[n-i-1]; \ 788 } \ 789 } 790 791 BCOPY(VG_Z_LIBC_SONAME, bcopy) 792 #if defined(VGO_darwin) 793 BCOPY(VG_Z_DYLD, bcopy) 794 #endif 795 796 797 /* glibc 2.5 variant of memmove which checks the dest is big enough. 798 There is no specific part of glibc that this is copied from. */ 799 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \ 800 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 801 (void *dstV, const void *srcV, SizeT n, SizeT destlen); \ 802 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 803 (void *dstV, const void *srcV, SizeT n, SizeT destlen) \ 804 { \ 805 extern void _exit(int status); \ 806 SizeT i; \ 807 Char* dst = (Char*)dstV; \ 808 Char* src = (Char*)srcV; \ 809 if (destlen < n) \ 810 goto badness; \ 811 if (dst < src) { \ 812 for (i = 0; i < n; i++) \ 813 dst[i] = src[i]; \ 814 } \ 815 else \ 816 if (dst > src) { \ 817 for (i = 0; i < n; i++) \ 818 dst[n-i-1] = src[n-i-1]; \ 819 } \ 820 return dst; \ 821 badness: \ 822 VALGRIND_PRINTF_BACKTRACE( \ 823 "*** memmove_chk: buffer overflow detected ***: " \ 824 "program terminated\n"); \ 825 _exit(127); \ 826 /*NOTREACHED*/ \ 827 return NULL; \ 828 } 829 830 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk) 831 832 833 /* Find the first occurrence of C in S or the final NUL byte. */ 834 #define GLIBC232_STRCHRNUL(soname, fnname) \ 835 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \ 836 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \ 837 { \ 838 unsigned char c = (unsigned char) c_in; \ 839 unsigned char* char_ptr = (unsigned char *)s; \ 840 while (1) { \ 841 if (*char_ptr == 0) return char_ptr; \ 842 if (*char_ptr == c) return char_ptr; \ 843 char_ptr++; \ 844 } \ 845 } 846 847 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul) 848 849 850 /* Find the first occurrence of C in S. */ 851 #define GLIBC232_RAWMEMCHR(soname, fnname) \ 852 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \ 853 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \ 854 { \ 855 unsigned char c = (unsigned char) c_in; \ 856 unsigned char* char_ptr = (unsigned char *)s; \ 857 while (1) { \ 858 if (*char_ptr == c) return char_ptr; \ 859 char_ptr++; \ 860 } \ 861 } 862 863 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr) 864 #if defined (VGO_linux) 865 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr) 866 #endif 867 868 /* glibc variant of strcpy that checks the dest is big enough. 869 Copied from glibc-2.5/debug/test-strcpy_chk.c. */ 870 #define GLIBC25___STRCPY_CHK(soname,fnname) \ 871 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 872 (char* dst, const char* src, SizeT len); \ 873 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 874 (char* dst, const char* src, SizeT len) \ 875 { \ 876 extern void _exit(int status); \ 877 char* ret = dst; \ 878 if (! len) \ 879 goto badness; \ 880 while ((*dst++ = *src++) != '\0') \ 881 if (--len == 0) \ 882 goto badness; \ 883 return ret; \ 884 badness: \ 885 VALGRIND_PRINTF_BACKTRACE( \ 886 "*** strcpy_chk: buffer overflow detected ***: " \ 887 "program terminated\n"); \ 888 _exit(127); \ 889 /*NOTREACHED*/ \ 890 return NULL; \ 891 } 892 893 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk) 894 895 896 /* glibc variant of stpcpy that checks the dest is big enough. 897 Copied from glibc-2.5/debug/test-stpcpy_chk.c. */ 898 #define GLIBC25___STPCPY_CHK(soname,fnname) \ 899 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 900 (char* dst, const char* src, SizeT len); \ 901 char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 902 (char* dst, const char* src, SizeT len) \ 903 { \ 904 extern void _exit(int status); \ 905 if (! len) \ 906 goto badness; \ 907 while ((*dst++ = *src++) != '\0') \ 908 if (--len == 0) \ 909 goto badness; \ 910 return dst - 1; \ 911 badness: \ 912 VALGRIND_PRINTF_BACKTRACE( \ 913 "*** stpcpy_chk: buffer overflow detected ***: " \ 914 "program terminated\n"); \ 915 _exit(127); \ 916 /*NOTREACHED*/ \ 917 return NULL; \ 918 } 919 920 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk) 921 922 923 /* mempcpy */ 924 #define GLIBC25_MEMPCPY(soname, fnname) \ 925 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 926 ( void *dst, const void *src, SizeT len ); \ 927 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 928 ( void *dst, const void *src, SizeT len ) \ 929 { \ 930 register char *d; \ 931 register char *s; \ 932 SizeT len_saved = len; \ 933 \ 934 if (len == 0) \ 935 return dst; \ 936 \ 937 if (is_overlap(dst, src, len, len)) \ 938 RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \ 939 \ 940 if ( dst > src ) { \ 941 d = (char *)dst + len - 1; \ 942 s = (char *)src + len - 1; \ 943 while ( len-- ) { \ 944 *d-- = *s--; \ 945 } \ 946 } else if ( dst < src ) { \ 947 d = (char *)dst; \ 948 s = (char *)src; \ 949 while ( len-- ) { \ 950 *d++ = *s++; \ 951 } \ 952 } \ 953 return (void*)( ((char*)dst) + len_saved ); \ 954 } 955 956 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy) 957 #if defined(VGO_linux) 958 GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */ 959 #endif 960 961 962 #define GLIBC26___MEMCPY_CHK(soname, fnname) \ 963 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 964 (void* dst, const void* src, SizeT len, SizeT dstlen ); \ 965 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 966 (void* dst, const void* src, SizeT len, SizeT dstlen ) \ 967 { \ 968 extern void _exit(int status); \ 969 register char *d; \ 970 register char *s; \ 971 \ 972 if (dstlen < len) goto badness; \ 973 \ 974 if (len == 0) \ 975 return dst; \ 976 \ 977 if (is_overlap(dst, src, len, len)) \ 978 RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \ 979 \ 980 if ( dst > src ) { \ 981 d = (char *)dst + len - 1; \ 982 s = (char *)src + len - 1; \ 983 while ( len-- ) { \ 984 *d-- = *s--; \ 985 } \ 986 } else if ( dst < src ) { \ 987 d = (char *)dst; \ 988 s = (char *)src; \ 989 while ( len-- ) { \ 990 *d++ = *s++; \ 991 } \ 992 } \ 993 return dst; \ 994 badness: \ 995 VALGRIND_PRINTF_BACKTRACE( \ 996 "*** memcpy_chk: buffer overflow detected ***: " \ 997 "program terminated\n"); \ 998 _exit(127); \ 999 /*NOTREACHED*/ \ 1000 return NULL; \ 1001 } 1002 1003 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk) 1004 1005 1006 #define STRSTR(soname, fnname) \ 1007 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1008 (void* haystack, void* needle); \ 1009 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1010 (void* haystack, void* needle) \ 1011 { \ 1012 UChar* h = (UChar*)haystack; \ 1013 UChar* n = (UChar*)needle; \ 1014 \ 1015 /* find the length of n, not including terminating zero */ \ 1016 UWord nlen = 0; \ 1017 while (n[nlen]) nlen++; \ 1018 \ 1019 /* if n is the empty string, match immediately. */ \ 1020 if (nlen == 0) return h; \ 1021 \ 1022 /* assert(nlen >= 1); */ \ 1023 UChar n0 = n[0]; \ 1024 \ 1025 while (1) { \ 1026 UChar hh = *h; \ 1027 if (hh == 0) return NULL; \ 1028 if (hh != n0) { h++; continue; } \ 1029 \ 1030 UWord i; \ 1031 for (i = 0; i < nlen; i++) { \ 1032 if (n[i] != h[i]) \ 1033 break; \ 1034 } \ 1035 /* assert(i >= 0 && i <= nlen); */ \ 1036 if (i == nlen) \ 1037 return h; \ 1038 \ 1039 h++; \ 1040 } \ 1041 } 1042 1043 #if defined(VGO_linux) 1044 STRSTR(VG_Z_LIBC_SONAME, strstr) 1045 #endif 1046 1047 1048 #define STRPBRK(soname, fnname) \ 1049 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1050 (void* sV, void* acceptV); \ 1051 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1052 (void* sV, void* acceptV) \ 1053 { \ 1054 UChar* s = (UChar*)sV; \ 1055 UChar* accept = (UChar*)acceptV; \ 1056 \ 1057 /* find the length of 'accept', not including terminating zero */ \ 1058 UWord nacc = 0; \ 1059 while (accept[nacc]) nacc++; \ 1060 \ 1061 /* if n is the empty string, fail immediately. */ \ 1062 if (nacc == 0) return NULL; \ 1063 \ 1064 /* assert(nacc >= 1); */ \ 1065 while (1) { \ 1066 UWord i; \ 1067 UChar sc = *s; \ 1068 if (sc == 0) \ 1069 break; \ 1070 for (i = 0; i < nacc; i++) { \ 1071 if (sc == accept[i]) \ 1072 return s; \ 1073 } \ 1074 s++; \ 1075 } \ 1076 \ 1077 return NULL; \ 1078 } 1079 1080 #if defined(VGO_linux) 1081 STRPBRK(VG_Z_LIBC_SONAME, strpbrk) 1082 #endif 1083 1084 1085 #define STRCSPN(soname, fnname) \ 1086 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1087 (void* sV, void* rejectV); \ 1088 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \ 1089 (void* sV, void* rejectV) \ 1090 { \ 1091 UChar* s = (UChar*)sV; \ 1092 UChar* reject = (UChar*)rejectV; \ 1093 \ 1094 /* find the length of 'reject', not including terminating zero */ \ 1095 UWord nrej = 0; \ 1096 while (reject[nrej]) nrej++; \ 1097 \ 1098 UWord len = 0; \ 1099 while (1) { \ 1100 UWord i; \ 1101 UChar sc = *s; \ 1102 if (sc == 0) \ 1103 break; \ 1104 for (i = 0; i < nrej; i++) { \ 1105 if (sc == reject[i]) \ 1106 break; \ 1107 } \ 1108 /* assert(i >= 0 && i <= nrej); */ \ 1109 if (i < nrej) \ 1110 break; \ 1111 s++; \ 1112 len++; \ 1113 } \ 1114 \ 1115 return len; \ 1116 } 1117 1118 #if defined(VGO_linux) 1119 STRCSPN(VG_Z_LIBC_SONAME, strcspn) 1120 #endif 1121 1122 1123 // And here's a validated strspn replacement, should it 1124 // become necessary. 1125 //UWord mystrspn( UChar* s, UChar* accept ) 1126 //{ 1127 // /* find the length of 'accept', not including terminating zero */ 1128 // UWord nacc = 0; 1129 // while (accept[nacc]) nacc++; 1130 // if (nacc == 0) return 0; 1131 // 1132 // UWord len = 0; 1133 // while (1) { 1134 // UWord i; 1135 // UChar sc = *s; 1136 // if (sc == 0) 1137 // break; 1138 // for (i = 0; i < nacc; i++) { 1139 // if (sc == accept[i]) 1140 // break; 1141 // } 1142 // assert(i >= 0 && i <= nacc); 1143 // if (i == nacc) 1144 // break; 1145 // s++; 1146 // len++; 1147 // } 1148 // 1149 // return len; 1150 //} 1151 1152 1153 /*------------------------------------------------------------*/ 1154 /*--- Improve definedness checking of process environment ---*/ 1155 /*------------------------------------------------------------*/ 1156 1157 #if defined(VGO_linux) 1158 1159 /* putenv */ 1160 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string); 1161 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string) 1162 { 1163 OrigFn fn; 1164 Word result; 1165 const char* p = string; 1166 VALGRIND_GET_ORIG_FN(fn); 1167 /* Now by walking over the string we magically produce 1168 traces when hitting undefined memory. */ 1169 if (p) 1170 while (*p++) 1171 ; 1172 CALL_FN_W_W(result, fn, string); 1173 return result; 1174 } 1175 1176 /* unsetenv */ 1177 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name); 1178 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name) 1179 { 1180 OrigFn fn; 1181 Word result; 1182 const char* p = name; 1183 VALGRIND_GET_ORIG_FN(fn); 1184 /* Now by walking over the string we magically produce 1185 traces when hitting undefined memory. */ 1186 if (p) 1187 while (*p++) 1188 ; 1189 CALL_FN_W_W(result, fn, name); 1190 return result; 1191 } 1192 1193 /* setenv */ 1194 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv) 1195 (const char* name, const char* value, int overwrite); 1196 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv) 1197 (const char* name, const char* value, int overwrite) 1198 { 1199 OrigFn fn; 1200 Word result; 1201 const char* p; 1202 VALGRIND_GET_ORIG_FN(fn); 1203 /* Now by walking over the string we magically produce 1204 traces when hitting undefined memory. */ 1205 if (name) 1206 for (p = name; *p; p++) 1207 ; 1208 if (value) 1209 for (p = value; *p; p++) 1210 ; 1211 VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite); 1212 CALL_FN_W_WWW(result, fn, name, value, overwrite); 1213 return result; 1214 } 1215 1216 #endif /* defined(VGO_linux) */ 1217 1218 1219 /*------------------------------------------------------------*/ 1220 /*--- AIX stuff only after this point ---*/ 1221 /*------------------------------------------------------------*/ 1222 1223 /* Generate replacements for strcat, strncat, strcpy, strncpy, strcmp 1224 in the given soname. */ 1225 #define Str5FNs(_soname) \ 1226 STRCAT(_soname, strcat) \ 1227 STRNCAT(_soname, strncat) \ 1228 STRCPY(_soname, strcpy) \ 1229 STRNCPY(_soname, strncpy) \ 1230 STRCMP(_soname, strcmp) 1231 1232 #if defined(VGP_ppc32_aix5) 1233 Str5FNs(NONE) /* in main exe */ 1234 Str5FNs(libCZdaZLshrcoreZdoZR) /* libC.a(shrcore.o) */ 1235 Str5FNs(libX11ZdaZLshr4ZdoZR) /* libX11.a(shr4.o) */ 1236 Str5FNs(libXmZdaZLshrZaZdoZR) /* libXm.a(shr*.o) */ 1237 Str5FNs(libXtZdaZLshr4ZdoZR) /* libXt.a(shr4.o) */ 1238 Str5FNs(libppeZurZdaZLdynamicZdoZR) /* libppe_r.a(dynamic.o) */ 1239 Str5FNs(libodmZdaZLshrZdoZR) /* libodm.a(shr.o) */ 1240 Str5FNs(libmpiZurZdaZLmpicoreZurZdoZR) /* libmpi_r.a(mpicore_r.o) */ 1241 Str5FNs(libmpiZurZdaZLmpipoeZurZdoZR) /* libmpi_r.a(mpipoe_r.o) */ 1242 Str5FNs(libmpiZurZdaZLmpciZurZdoZR) /* libmpi_r.a(mpci_r.o) */ 1243 Str5FNs(libslurmZdso) /* libslurm.so */ 1244 Str5FNs(libglibZdso) /* libglib.so */ 1245 Str5FNs(libIMZdaZLshrZdoZR) /* libIM.a(shr.o) */ 1246 Str5FNs(libiconvZdaZLshr4ZdoZR) /* libiconv.a(shr4.o) */ 1247 Str5FNs(libGLZdaZLshrZdoZR) /* libGL.a(shr.o) */ 1248 Str5FNs(libgdkZdso) /* libgdk.so */ 1249 Str5FNs(libcursesZdaZLshr42ZdoZR) /* libcurses.a(shr42.o) */ 1250 Str5FNs(libqtZda) /* libqt.a */ 1251 Str5FNs(ZaZLlibglibZhZaZdsoZaZR) /* *(libglib-*.so*) */ 1252 Str5FNs(ZaZLlibfontconfigZdsoZaZR) /* *(libfontconfig.so*) */ 1253 Str5FNs(libQtZaa) /* libQt*.a */ 1254 #endif 1255 #if defined(VGP_ppc64_aix5) 1256 Str5FNs(NONE) /* in main exe */ 1257 Str5FNs(libX11ZdaZLshrZu64ZdoZR) /* libX11.a(shr_64.o) */ 1258 Str5FNs(libiconvZdaZLshr4Zu64ZdoZR) /* libiconv.a(shr4_64.o) */ 1259 Str5FNs(libGLZdaZLshrZu64ZdoZR) /* libGL.a(shr_64.o) */ 1260 Str5FNs(libppeZurZdaZLdynamic64ZdoZR) /* libppe_r.a(dynamic64.o) */ 1261 Str5FNs(libodmZdaZLshrZu64ZdoZR) /* libodm.a(shr_64.o) */ 1262 Str5FNs(libmpiZurZdaZLmpicore64ZurZdoZR) /* libmpi_r.a(mpicore64_r.o) */ 1263 Str5FNs(libmpiZurZdaZLmpipoe64ZurZdoZR) /* libmpi_r.a(mpipoe64_r.o) */ 1264 Str5FNs(libCZdaZLshrcoreZu64ZdoZR) /* libC.a(shrcore_64.o) */ 1265 Str5FNs(libmpiZurZdaZLmpci64ZurZdoZR) /* libmpi_r.a(mpci64_r.o) */ 1266 Str5FNs(libqtZda) /* libqt.a */ 1267 Str5FNs(ZaZLlibglibZhZaZdsoZaZR) /* *(libglib-*.so*) */ 1268 Str5FNs(ZaZLlibfontconfigZdsoZaZR) /* *(libfontconfig.so*) */ 1269 Str5FNs(libQtZaa) /* libQt*.a */ 1270 #endif 1271 1272 1273 /* AIX's libm contains a sqrt implementation which does a nasty thing: 1274 it loads the initial estimate of the root into a FP register, but 1275 only the upper half of the number is initialised data. Hence the 1276 least significant 32 mantissa bits are undefined, and it then uses 1277 Newton-Raphson iteration to compute the final, defined result. 1278 This fools memcheck completely; the only solution I can think of is 1279 provide our own substitute. The _FAST variant is almost right 1280 except the result is not correctly rounded. The _EXACT variant, 1281 which is selected by default, is always right; but it's also pretty 1282 darn slow. */ 1283 1284 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) 1285 #define SQRT_FAST(soname, fnname) \ 1286 double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \ 1287 double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \ 1288 { \ 1289 static UInt T1[32] = \ 1290 { 0, 1024, 3062, 5746, 9193, 13348, \ 1291 18162, 23592, 29598, 36145, 43202, 50740, \ 1292 58733, 67158, 75992, 85215, 83599, 71378, \ 1293 60428, 50647, 41945, 34246, 27478, 21581, \ 1294 16499, 12183, 8588, 5674, 3403, 1742, \ 1295 661, 130 }; \ 1296 UInt x0, x1, sign, expo, mant0, bIGENDIAN = 1; \ 1297 union { UInt w[2]; double d; } u; \ 1298 u.d = x; \ 1299 x0 = u.w[1 - bIGENDIAN]; /* high half */ \ 1300 x1 = u.w[bIGENDIAN]; /* low half */ \ 1301 sign = x0 >> 31; \ 1302 expo = (x0 >> 20) & 0x7FF; \ 1303 mant0 = x0 & 0xFFFFF; \ 1304 if ( (sign == 0 && expo >= 1 && expo <= 0x7FE) /* +normal */ \ 1305 || (sign == 0 && expo == 0 \ 1306 && (mant0 | x1) > 0) /* +denorm */) { \ 1307 /* common case; do Newton-Raphson */ \ 1308 /* technically k should be signed int32, but since we're \ 1309 always entering here with x > 0, doesn't matter that it's \ 1310 unsigned. */ \ 1311 double y; \ 1312 UInt k = (x0>>1) + 0x1ff80000; \ 1313 u.w[1 - bIGENDIAN] = k - T1[31&(k>>15)]; \ 1314 u.w[bIGENDIAN] = 0; \ 1315 y = u.d; \ 1316 y = (y+x/y)/2.0 ; \ 1317 y = (y+x/y)/2.0 ; \ 1318 y = y-(y-x/y)/2.0 ; \ 1319 return y; \ 1320 } \ 1321 if ( (sign == 1 && expo >= 1 && expo <= 0x7FE) /* -normal */ \ 1322 || (sign == 1 && expo == 0 \ 1323 && (mant0 | x1) > 0) /* -denorm */) { \ 1324 u.w[1 - bIGENDIAN] = 0xFFF00000; \ 1325 u.w[bIGENDIAN] = 0x1; \ 1326 return u.d; /* -Inf -> NaN */ \ 1327 } \ 1328 if ((expo | mant0 | x1) == 0) \ 1329 return x; /* +/-zero -> self */ \ 1330 if (expo == 0x7FF && (mant0 | x1) == 0) { \ 1331 if (sign == 0) \ 1332 return x; /* +Inf -> self */ \ 1333 u.w[1 - bIGENDIAN] = 0xFFF00000; \ 1334 u.w[bIGENDIAN] = 0x1; \ 1335 return u.d; /* -Inf -> NaN */ \ 1336 } \ 1337 /* must be +/- NaN */ \ 1338 return x; /* +/-NaN -> self */ \ 1339 } 1340 1341 #define SQRT_EXACT(soname, fnname) \ 1342 /* \ 1343 * ==================================================== \ 1344 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. \ 1345 * \ 1346 * Developed at SunPro, a Sun Microsystems, Inc. business. \ 1347 * Permission to use, copy, modify, and distribute this \ 1348 * software is freely granted, provided that this notice \ 1349 * is preserved. \ 1350 * ==================================================== \ 1351 */ \ 1352 /* \ 1353 * Return correctly rounded sqrt. \ 1354 * ------------------------------------------ \ 1355 * | Use the hardware sqrt if you have one | \ 1356 * ------------------------------------------ \ 1357 * Method: \ 1358 * Bit by bit method using integer arithmetic. (Slow, but portable) \ 1359 * 1. Normalization \ 1360 * Scale x to y in [1,4) with even powers of 2: \ 1361 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then \ 1362 * sqrt(x) = 2^k * sqrt(y) \ 1363 * 2. Bit by bit computation \ 1364 * Let q = sqrt(y) truncated to i bit after binary point (q = 1), \ 1365 * i 0 \ 1366 * i+1 2 \ 1367 * s = 2*q , and y = 2 * ( y - q ). (1) \ 1368 * i i i i \ 1369 * \ 1370 * To compute q from q , one checks whether \ 1371 * i+1 i \ 1372 * \ 1373 * -(i+1) 2 \ 1374 * (q + 2 ) <= y. (2) \ 1375 * i \ 1376 * -(i+1) \ 1377 * If (2) is false, then q = q ; otherwise q = q + 2 . \ 1378 * i+1 i i+1 i \ 1379 * \ 1380 * With some algebric manipulation, it is not difficult to see \ 1381 * that (2) is equivalent to \ 1382 * -(i+1) \ 1383 * s + 2 <= y (3) \ 1384 * i i \ 1385 * \ 1386 * The advantage of (3) is that s and y can be computed by \ 1387 * i i \ 1388 * the following recurrence formula: \ 1389 * if (3) is false \ 1390 * \ 1391 * s = s , y = y ; (4) \ 1392 * i+1 i i+1 i \ 1393 * \ 1394 * otherwise, \ 1395 * -i -(i+1) \ 1396 * s = s + 2 , y = y - s - 2 (5) \ 1397 * i+1 i i+1 i i \ 1398 * \ 1399 * \ 1400 * One may easily use induction to prove (4) and (5). \ 1401 * Note. Since the left hand side of (3) contain only i+2 bits, \ 1402 * it does not necessary to do a full (53-bit) comparison \ 1403 * in (3). \ 1404 * 3. Final rounding \ 1405 * After generating the 53 bits result, we compute one more bit. \ 1406 * Together with the remainder, we can decide whether the \ 1407 * result is exact, bigger than 1/2ulp, or less than 1/2ulp \ 1408 * (it will never equal to 1/2ulp). \ 1409 * The rounding mode can be detected by checking whether \ 1410 * huge + tiny is equal to huge, and whether huge - tiny is \ 1411 * equal to huge for some floating point number "huge" and "tiny". \ 1412 * \ 1413 * Special cases: \ 1414 * sqrt(+-0) = +-0 ... exact \ 1415 * sqrt(inf) = inf \ 1416 * sqrt(-ve) = NaN ... with invalid signal \ 1417 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN \ 1418 * \ 1419 */ \ 1420 double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \ 1421 double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \ 1422 { \ 1423 const Int bIGENDIAN = 1; \ 1424 const double one = 1.0, tiny=1.0e-300; \ 1425 double z; \ 1426 Int sign = (Int)0x80000000; \ 1427 Int ix0,s0,q,m,t,i; \ 1428 UInt r,t1,s1,ix1,q1; \ 1429 union { UInt w[2]; double d; } u; \ 1430 u.d = x; \ 1431 ix0 = u.w[1-bIGENDIAN]; \ 1432 ix1 = u.w[bIGENDIAN]; \ 1433 \ 1434 /* take care of Inf and NaN */ \ 1435 if((ix0&0x7ff00000)==0x7ff00000) { \ 1436 return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf \ 1437 sqrt(-inf)=sNaN */ \ 1438 } \ 1439 /* take care of zero */ \ 1440 if(ix0<=0) { \ 1441 if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ \ 1442 else if(ix0<0) \ 1443 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ \ 1444 } \ 1445 /* normalize x */ \ 1446 m = (ix0>>20); \ 1447 if(m==0) { /* subnormal x */ \ 1448 while(ix0==0) { \ 1449 m -= 21; \ 1450 ix0 |= (ix1>>11); ix1 <<= 21; \ 1451 } \ 1452 for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; \ 1453 m -= i-1; \ 1454 ix0 |= (ix1>>(32-i)); \ 1455 ix1 <<= i; \ 1456 } \ 1457 m -= 1023; /* unbias exponent */ \ 1458 ix0 = (ix0&0x000fffff)|0x00100000; \ 1459 if(m&1){ /* odd m, double x to make it even */ \ 1460 ix0 += ix0 + ((ix1&sign)>>31); \ 1461 ix1 += ix1; \ 1462 } \ 1463 m >>= 1; /* m = [m/2] */ \ 1464 /* generate sqrt(x) bit by bit */ \ 1465 ix0 += ix0 + ((ix1&sign)>>31); \ 1466 ix1 += ix1; \ 1467 q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ \ 1468 r = 0x00200000; /* r = moving bit from right to left */ \ 1469 while(r!=0) { \ 1470 t = s0+r; \ 1471 if(t<=ix0) { \ 1472 s0 = t+r; \ 1473 ix0 -= t; \ 1474 q += r; \ 1475 } \ 1476 ix0 += ix0 + ((ix1&sign)>>31); \ 1477 ix1 += ix1; \ 1478 r>>=1; \ 1479 } \ 1480 r = sign; \ 1481 while(r!=0) { \ 1482 t1 = s1+r; \ 1483 t = s0; \ 1484 if((t<ix0)||((t==ix0)&&(t1<=ix1))) { \ 1485 s1 = t1+r; \ 1486 if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1; \ 1487 ix0 -= t; \ 1488 if (ix1 < t1) ix0 -= 1; \ 1489 ix1 -= t1; \ 1490 q1 += r; \ 1491 } \ 1492 ix0 += ix0 + ((ix1&sign)>>31); \ 1493 ix1 += ix1; \ 1494 r>>=1; \ 1495 } \ 1496 /* use floating add to find out rounding direction */ \ 1497 if((ix0|ix1)!=0) { \ 1498 z = one-tiny; /* trigger inexact flag */ \ 1499 if (z>=one) { \ 1500 z = one+tiny; \ 1501 if (q1==(UInt)0xffffffff) { q1=0; q += 1;} \ 1502 else if (z>one) { \ 1503 if (q1==(UInt)0xfffffffe) q+=1; \ 1504 q1+=2; \ 1505 } else \ 1506 q1 += (q1&1); \ 1507 } \ 1508 } \ 1509 ix0 = (q>>1)+0x3fe00000; \ 1510 ix1 = q1>>1; \ 1511 if ((q&1)==1) ix1 |= sign; \ 1512 ix0 += (m <<20); \ 1513 ix0 = u.w[1-bIGENDIAN] = ix0; \ 1514 ix1 = u.w[bIGENDIAN] = ix1; \ 1515 z = u.d; \ 1516 return z; \ 1517 } 1518 1519 #if 0 1520 SQRT_FAST(NONE, sqrt) /* xlC generates these */ 1521 SQRT_FAST(NONE, _sqrt) /* xlf generates these */ 1522 #else 1523 SQRT_EXACT(NONE, sqrt) /* xlC generates these */ 1524 SQRT_EXACT(NONE, _sqrt) /* xlf generates these */ 1525 #endif 1526 1527 #endif /* defined(VGP_ppc32_aix5) */ 1528 1529 /*--------------------------------------------------------------------*/ 1530 /*--- end ---*/ 1531 /*--------------------------------------------------------------------*/ 1532