1 2 /*--------------------------------------------------------------------*/ 3 /*--- Replacements for malloc() et al, which run on the simulated ---*/ 4 /*--- CPU. vg_replace_malloc.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2011 Julian Seward 12 jseward (at) acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 /* --------------------------------------------------------------------- 33 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. 34 35 These functions are drop-in replacements for malloc() and friends. 36 They have global scope, but are not intended to be called directly. 37 See pub_core_redir.h for the gory details. 38 39 This file can be linked into the vg_preload_<tool>.so file for any tool 40 that wishes to know about calls to malloc(). The tool must define all 41 the functions that will be called via 'info'. 42 43 It is called vg_replace_malloc.c because this filename appears in stack 44 traces, so we want the name to be (hopefully!) meaningful to users. 45 46 IMPORTANT: this file must not contain any floating point code, nor 47 any integer division. This is because on ARM these can cause calls 48 to helper functions, which will be unresolved within this .so. 49 Although it is usually the case that the client's ld.so instance 50 can bind them at runtime to the relevant functions in the client 51 executable, there is no guarantee of this; and so the client may 52 die via a runtime link failure. Hence the only safe approach is to 53 avoid such function calls in the first place. See "#define CALLOC" 54 below for a specific example. 55 56 A useful command is 57 for f in `find . -name "*preload*.so*"` ; \ 58 do nm -A $f | grep " U " ; \ 59 done 60 61 to see all the undefined symbols in all the preload shared objects. 62 ------------------------------------------------------------------ */ 63 64 #include "pub_core_basics.h" 65 #include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM 66 #include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF, 67 // VALGRIND_NON_SIMD_CALL[12] 68 #include "pub_core_debuginfo.h" // needed for pub_core_redir.h :( 69 #include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT 70 #include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_* 71 #include "pub_core_replacemalloc.h" 72 73 /* Assignment of behavioural equivalence class tags: 1NNNP is intended 74 to be reserved for the Valgrind core. Current usage: 75 76 10010 ALLOC_or_NULL 77 10020 ZONEALLOC_or_NULL 78 10030 ALLOC_or_BOMB 79 10040 ZONEFREE 80 10050 FREE 81 10060 ZONECALLOC 82 10070 CALLOC 83 10080 ZONEREALLOC 84 10090 REALLOC 85 10100 ZONEMEMALIGN 86 10110 MEMALIGN 87 10120 VALLOC 88 10130 ZONEVALLOC 89 10140 MALLOPT 90 10150 MALLOC_TRIM 91 10160 POSIX_MEMALIGN 92 10170 MALLOC_USABLE_SIZE 93 10180 PANIC 94 10190 MALLOC_STATS 95 10200 MALLINFO 96 10210 DEFAULT_ZONE 97 10220 ZONE_CHECK 98 */ 99 100 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style 101 mangling, could be supported properly by the redirects in this 102 module. Except we can't because it doesn't put its allocation 103 functions in libpgc.so but instead hardwires them into the 104 compilation unit holding main(), which makes them impossible to 105 intercept directly. Fortunately those fns seem to route everything 106 through to malloc/free. 107 108 mid-06: could be improved, since we can now intercept in the main 109 executable too. 110 */ 111 112 113 114 /* Call here to exit if we can't continue. On Android we can't call 115 _exit for some reason, so we have to blunt-instrument it. */ 116 __attribute__ ((__noreturn__)) 117 static inline void my_exit ( int x ) 118 { 119 # if defined(VGPV_arm_linux_android) 120 __asm__ __volatile__(".word 0xFFFFFFFF"); 121 while (1) {} 122 # else 123 extern __attribute__ ((__noreturn__)) void _exit(int status); 124 _exit(x); 125 # endif 126 } 127 128 /* Same problem with getpagesize. */ 129 static inline int my_getpagesize ( void ) 130 { 131 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 132 return 4096; /* kludge - link failure on Android, for some reason */ 133 # else 134 extern int getpagesize (void); 135 return getpagesize(); 136 # endif 137 } 138 139 140 /* Compute the high word of the double-length unsigned product of U 141 and V. This is for calloc argument overflow checking; see comments 142 below. Algorithm as described in Hacker's Delight, chapter 8. */ 143 static UWord umulHW ( UWord u, UWord v ) 144 { 145 UWord u0, v0, w0, rHi; 146 UWord u1, v1, w1,w2,t; 147 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF 148 : (UWord)0xFFFFFFFFULL; 149 UWord halfShift = sizeof(UWord)==4 ? 16 : 32; 150 u0 = u & halfMask; 151 u1 = u >> halfShift; 152 v0 = v & halfMask; 153 v1 = v >> halfShift; 154 w0 = u0 * v0; 155 t = u1 * v0 + (w0 >> halfShift); 156 w1 = t & halfMask; 157 w2 = t >> halfShift; 158 w1 = u0 * v1 + w1; 159 rHi = u1 * v1 + w2 + (w1 >> halfShift); 160 return rHi; 161 } 162 163 164 /*------------------------------------------------------------*/ 165 /*--- Replacing malloc() et al ---*/ 166 /*------------------------------------------------------------*/ 167 168 /* This struct is initially empty. Before the first use of any of 169 these functions, we make a client request which fills in the 170 fields. 171 */ 172 static struct vg_mallocfunc_info info; 173 static int init_done; 174 175 /* Startup hook - called as init section */ 176 __attribute__((constructor)) 177 static void init(void); 178 179 #define MALLOC_TRACE(format, args...) \ 180 if (info.clo_trace_malloc) { \ 181 VALGRIND_INTERNAL_PRINTF(format, ## args ); } 182 183 /* Below are new versions of malloc, __builtin_new, free, 184 __builtin_delete, calloc, realloc, memalign, and friends. 185 186 None of these functions are called directly - they are not meant to 187 be found by the dynamic linker. But ALL client calls to malloc() 188 and friends wind up here eventually. They get called because 189 vg_replace_malloc installs a bunch of code redirects which causes 190 Valgrind to use these functions rather than the ones they're 191 replacing. 192 */ 193 194 195 /*---------------------- malloc ----------------------*/ 196 197 /* Generate a replacement for 'fnname' in object 'soname', which calls 198 'vg_replacement' to allocate memory. If that fails, return NULL. 199 */ 200 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \ 201 \ 202 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \ 203 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \ 204 { \ 205 void* v; \ 206 \ 207 if (!init_done) init(); \ 208 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ 209 \ 210 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 211 MALLOC_TRACE(" = %p\n", v ); \ 212 return v; \ 213 } 214 215 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \ 216 \ 217 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \ 218 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \ 219 { \ 220 void* v; \ 221 \ 222 if (!init_done) init(); \ 223 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \ 224 \ 225 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 226 MALLOC_TRACE(" = %p\n", v ); \ 227 return v; \ 228 } 229 230 231 /* Generate a replacement for 'fnname' in object 'soname', which calls 232 'vg_replacement' to allocate memory. If that fails, it bombs the 233 system. 234 */ 235 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \ 236 \ 237 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \ 238 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \ 239 { \ 240 void* v; \ 241 \ 242 if (!init_done) init(); \ 243 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ 244 \ 245 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 246 MALLOC_TRACE(" = %p\n", v ); \ 247 if (NULL == v) { \ 248 VALGRIND_PRINTF( \ 249 "new/new[] failed and should throw an exception, but Valgrind\n"); \ 250 VALGRIND_PRINTF_BACKTRACE( \ 251 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \ 252 my_exit(1); \ 253 } \ 254 return v; \ 255 } 256 257 // Each of these lines generates a replacement function: 258 // (from_so, from_fn, v's replacement) 259 260 // malloc 261 #if defined(VGO_linux) 262 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc); 263 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc); 264 265 #elif defined(VGO_darwin) 266 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc); 267 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc); 268 269 #endif 270 271 272 /*---------------------- new ----------------------*/ 273 274 #if defined(VGO_linux) 275 // operator new(unsigned int), not mangled (for gcc 2.96) 276 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new); 277 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new); 278 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new); 279 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new); 280 // operator new(unsigned int), GNU mangling 281 #if VG_WORDSIZE == 4 282 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); 283 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new); 284 #endif 285 // operator new(unsigned long), GNU mangling 286 #if VG_WORDSIZE == 8 287 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); 288 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new); 289 #endif 290 291 #elif defined(VGO_darwin) 292 // glider: hereafter we uncomment the interceptors for operator new 293 // and operator delete, see https://bugs.kde.org/show_bug.cgi?id=286849 294 // operator new(unsigned int), GNU mangling 295 #if VG_WORDSIZE == 4 296 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); 297 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new); 298 #endif 299 // operator new(unsigned long), GNU mangling 300 #if 1 // FIXME: is this right? 301 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); 302 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new); 303 #endif 304 305 #endif 306 307 /*---------------------- new nothrow ----------------------*/ 308 // operator new(unsigned, std::nothrow_t const&), GNU mangling 309 310 #if defined(VGO_linux) 311 // operator new(unsigned, std::nothrow_t const&), GNU mangling 312 #if VG_WORDSIZE == 4 313 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 314 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 315 #endif 316 // operator new(unsigned long, std::nothrow_t const&), GNU mangling 317 #if VG_WORDSIZE == 8 318 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 319 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 320 #endif 321 #elif defined(VGO_darwin) 322 // operator new(unsigned, std::nothrow_t const&), GNU mangling 323 #if VG_WORDSIZE == 4 324 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 325 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 326 #endif 327 // operator new(unsigned long, std::nothrow_t const&), GNU mangling 328 #if 1 // FIXME: is this right? 329 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 330 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 331 #endif 332 #endif 333 334 335 /*---------------------- new [] ----------------------*/ 336 337 #if defined(VGO_linux) 338 // operator new[](unsigned int), not mangled (for gcc 2.96) 339 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new ); 340 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new ); 341 // operator new[](unsigned int), GNU mangling 342 #if VG_WORDSIZE == 4 343 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); 344 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new ); 345 #endif 346 // operator new[](unsigned long), GNU mangling 347 #if VG_WORDSIZE == 8 348 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); 349 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new ); 350 #endif 351 352 #elif defined(VGO_darwin) 353 // operator new[](unsigned int), GNU mangling 354 #if VG_WORDSIZE == 4 355 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); 356 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new ); 357 #endif 358 // operator new[](unsigned long), GNU mangling 359 #if 1 // FIXME: is this right? 360 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); 361 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new ); 362 #endif 363 364 #endif 365 366 367 /*---------------------- new [] nothrow ----------------------*/ 368 369 #if defined(VGO_linux) 370 // operator new[](unsigned, std::nothrow_t const&), GNU mangling 371 #if VG_WORDSIZE == 4 372 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 373 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 374 #endif 375 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling 376 #if VG_WORDSIZE == 8 377 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 378 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 379 #endif 380 #elif defined(VGO_darwin) 381 // operator new[](unsigned, std::nothrow_t const&), GNU mangling 382 #if VG_WORDSIZE == 4 383 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 384 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 385 #endif 386 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling 387 #if 1 // FIXME: is this right? 388 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 389 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 390 #endif 391 392 #endif 393 394 395 /*---------------------- free ----------------------*/ 396 397 /* Generate a replacement for 'fnname' in object 'soname', which calls 398 'vg_replacement' to free previously allocated memory. 399 */ 400 #define ZONEFREE(soname, fnname, vg_replacement) \ 401 \ 402 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \ 403 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \ 404 { \ 405 if (!init_done) init(); \ 406 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \ 407 if (p == NULL) \ 408 return; \ 409 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ 410 } 411 412 #define FREE(soname, fnname, vg_replacement) \ 413 \ 414 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \ 415 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \ 416 { \ 417 if (!init_done) init(); \ 418 MALLOC_TRACE(#fnname "(%p)\n", p ); \ 419 if (p == NULL) \ 420 return; \ 421 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ 422 } 423 424 #if defined(VGO_linux) 425 FREE(VG_Z_LIBSTDCXX_SONAME, free, free ); 426 FREE(VG_Z_LIBC_SONAME, free, free ); 427 428 #elif defined(VGO_darwin) 429 FREE(VG_Z_LIBC_SONAME, free, free ); 430 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free ); 431 432 #endif 433 434 435 /*---------------------- cfree ----------------------*/ 436 437 // cfree 438 #if defined(VGO_linux) 439 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free ); 440 FREE(VG_Z_LIBC_SONAME, cfree, free ); 441 442 #elif defined(VGO_darwin) 443 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free ); 444 //FREE(VG_Z_LIBC_SONAME, cfree, free ); 445 446 #endif 447 448 449 /*---------------------- delete ----------------------*/ 450 451 #if defined(VGO_linux) 452 // operator delete(void*), not mangled (for gcc 2.96) 453 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete ); 454 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete ); 455 // operator delete(void*), GNU mangling 456 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete ); 457 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete ); 458 459 #elif defined(VGO_darwin) 460 // operator delete(void*), GNU mangling 461 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete ); 462 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete ); 463 464 #endif 465 466 467 /*---------------------- delete nothrow ----------------------*/ 468 469 #if defined(VGO_linux) 470 // operator delete(void*, std::nothrow_t const&), GNU mangling 471 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 472 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 473 474 #elif defined(VGO_darwin) 475 // operator delete(void*, std::nothrow_t const&), GNU mangling 476 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 477 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 478 479 #endif 480 481 482 /*---------------------- delete [] ----------------------*/ 483 484 #if defined(VGO_linux) 485 // operator delete[](void*), not mangled (for gcc 2.96) 486 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 487 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 488 // operator delete[](void*), GNU mangling 489 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); 490 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete ); 491 492 #elif defined(VGO_darwin) 493 // operator delete[](void*), not mangled (for gcc 2.96) 494 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 495 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 496 // operator delete[](void*), GNU mangling 497 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); 498 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete ); 499 500 #endif 501 502 503 /*---------------------- delete [] nothrow ----------------------*/ 504 505 #if defined(VGO_linux) 506 // operator delete[](void*, std::nothrow_t const&), GNU mangling 507 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 508 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 509 510 #elif defined(VGO_darwin) 511 // operator delete[](void*, std::nothrow_t const&), GNU mangling 512 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 513 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 514 515 #endif 516 517 518 /*---------------------- calloc ----------------------*/ 519 520 #define ZONECALLOC(soname, fnname) \ 521 \ 522 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \ 523 ( void *zone, SizeT nmemb, SizeT size ); \ 524 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \ 525 ( void *zone, SizeT nmemb, SizeT size ) \ 526 { \ 527 void* v; \ 528 \ 529 if (!init_done) init(); \ 530 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \ 531 \ 532 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ 533 MALLOC_TRACE(" = %p\n", v ); \ 534 return v; \ 535 } 536 537 #define CALLOC(soname, fnname) \ 538 \ 539 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \ 540 ( SizeT nmemb, SizeT size ); \ 541 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \ 542 ( SizeT nmemb, SizeT size ) \ 543 { \ 544 void* v; \ 545 \ 546 if (!init_done) init(); \ 547 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \ 548 \ 549 /* Protect against overflow. See bug 24078. (that bug number is 550 invalid. Which one really?) */ \ 551 /* But don't use division, since that produces an external symbol 552 reference on ARM, in the form of a call to __aeabi_uidiv. It's 553 normally OK, because ld.so manages to resolve it to something in the 554 executable, or one of its shared objects. But that isn't guaranteed 555 to be the case, and it has been observed to fail in rare cases, eg: 556 echo x | valgrind /bin/sed -n "s/.*-\>\ //p" 557 So instead compute the high word of the product and check it is zero. */ \ 558 if (umulHW(size, nmemb) != 0) return NULL; \ 559 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ 560 MALLOC_TRACE(" = %p\n", v ); \ 561 return v; \ 562 } 563 564 #if defined(VGO_linux) 565 CALLOC(VG_Z_LIBC_SONAME, calloc); 566 567 #elif defined(VGO_darwin) 568 CALLOC(VG_Z_LIBC_SONAME, calloc); 569 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); 570 571 #endif 572 573 574 /*---------------------- realloc ----------------------*/ 575 576 #define ZONEREALLOC(soname, fnname) \ 577 \ 578 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \ 579 ( void *zone, void* ptrV, SizeT new_size ); \ 580 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \ 581 ( void *zone, void* ptrV, SizeT new_size ) \ 582 { \ 583 void* v; \ 584 \ 585 if (!init_done) init(); \ 586 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \ 587 \ 588 if (ptrV == NULL) \ 589 /* We need to call a malloc-like function; so let's use \ 590 one which we know exists. GrP fixme use zonemalloc instead? */ \ 591 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \ 592 (new_size); \ 593 if (new_size <= 0) { \ 594 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ 595 MALLOC_TRACE(" = 0\n"); \ 596 return NULL; \ 597 } \ 598 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ 599 MALLOC_TRACE(" = %p\n", v ); \ 600 return v; \ 601 } 602 603 #define REALLOC(soname, fnname) \ 604 \ 605 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \ 606 ( void* ptrV, SizeT new_size );\ 607 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \ 608 ( void* ptrV, SizeT new_size ) \ 609 { \ 610 void* v; \ 611 \ 612 if (!init_done) init(); \ 613 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \ 614 \ 615 if (ptrV == NULL) \ 616 /* We need to call a malloc-like function; so let's use \ 617 one which we know exists. */ \ 618 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \ 619 (new_size); \ 620 if (new_size <= 0) { \ 621 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ 622 MALLOC_TRACE(" = 0\n"); \ 623 return NULL; \ 624 } \ 625 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ 626 MALLOC_TRACE(" = %p\n", v ); \ 627 return v; \ 628 } 629 630 #if defined(VGO_linux) 631 REALLOC(VG_Z_LIBC_SONAME, realloc); 632 633 #elif defined(VGO_darwin) 634 REALLOC(VG_Z_LIBC_SONAME, realloc); 635 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc); 636 637 #endif 638 639 640 /*---------------------- memalign ----------------------*/ 641 642 #define ZONEMEMALIGN(soname, fnname) \ 643 \ 644 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ 645 ( void *zone, SizeT alignment, SizeT n ); \ 646 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ 647 ( void *zone, SizeT alignment, SizeT n ) \ 648 { \ 649 void* v; \ 650 \ 651 if (!init_done) init(); \ 652 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \ 653 zone, (ULong)alignment, (ULong)n ); \ 654 \ 655 /* Round up to minimum alignment if necessary. */ \ 656 if (alignment < VG_MIN_MALLOC_SZB) \ 657 alignment = VG_MIN_MALLOC_SZB; \ 658 \ 659 /* Round up to nearest power-of-two if necessary (like glibc). */ \ 660 while (0 != (alignment & (alignment - 1))) alignment++; \ 661 \ 662 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ 663 MALLOC_TRACE(" = %p\n", v ); \ 664 return v; \ 665 } 666 667 #define MEMALIGN(soname, fnname) \ 668 \ 669 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ 670 ( SizeT alignment, SizeT n ); \ 671 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ 672 ( SizeT alignment, SizeT n ) \ 673 { \ 674 void* v; \ 675 \ 676 if (!init_done) init(); \ 677 MALLOC_TRACE("memalign(al %llu, size %llu)", \ 678 (ULong)alignment, (ULong)n ); \ 679 \ 680 /* Round up to minimum alignment if necessary. */ \ 681 if (alignment < VG_MIN_MALLOC_SZB) \ 682 alignment = VG_MIN_MALLOC_SZB; \ 683 \ 684 /* Round up to nearest power-of-two if necessary (like glibc). */ \ 685 while (0 != (alignment & (alignment - 1))) alignment++; \ 686 \ 687 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ 688 MALLOC_TRACE(" = %p\n", v ); \ 689 return v; \ 690 } 691 692 #if defined(VGO_linux) 693 MEMALIGN(VG_Z_LIBC_SONAME, memalign); 694 695 #elif defined(VGO_darwin) 696 MEMALIGN(VG_Z_LIBC_SONAME, memalign); 697 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign); 698 699 #endif 700 701 702 /*---------------------- valloc ----------------------*/ 703 704 #define VALLOC(soname, fnname) \ 705 \ 706 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \ 707 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \ 708 { \ 709 static int pszB = 0; \ 710 if (pszB == 0) \ 711 pszB = my_getpagesize(); \ 712 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ 713 ((SizeT)pszB, size); \ 714 } 715 716 #define ZONEVALLOC(soname, fnname) \ 717 \ 718 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \ 719 ( void *zone, SizeT size ); \ 720 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \ 721 ( void *zone, SizeT size ) \ 722 { \ 723 static int pszB = 0; \ 724 if (pszB == 0) \ 725 pszB = my_getpagesize(); \ 726 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ 727 ((SizeT)pszB, size); \ 728 } 729 730 #if defined(VGO_linux) 731 VALLOC(VG_Z_LIBC_SONAME, valloc); 732 733 #elif defined(VGO_darwin) 734 VALLOC(VG_Z_LIBC_SONAME, valloc); 735 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc); 736 737 #endif 738 739 740 /*---------------------- mallopt ----------------------*/ 741 742 /* Various compatibility wrapper functions, for glibc and libstdc++. */ 743 744 #define MALLOPT(soname, fnname) \ 745 \ 746 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \ 747 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \ 748 { \ 749 /* In glibc-2.2.4, 1 denotes a successful return value for \ 750 mallopt */ \ 751 return 1; \ 752 } 753 754 #if defined(VGO_linux) 755 MALLOPT(VG_Z_LIBC_SONAME, mallopt); 756 757 #elif defined(VGO_darwin) 758 MALLOPT(VG_Z_LIBC_SONAME, mallopt); 759 760 #endif 761 762 763 /*---------------------- malloc_trim ----------------------*/ 764 // Documentation says: 765 // malloc_trim(size_t pad); 766 // 767 // If possible, gives memory back to the system (via negative arguments to 768 // sbrk) if there is unused memory at the `high' end of the malloc pool. 769 // You can call this after freeing large blocks of memory to potentially 770 // reduce the system-level memory requirements of a program. However, it 771 // cannot guarantee to reduce memory. Under some allocation patterns, 772 // some large free blocks of memory will be locked between two used 773 // chunks, so they cannot be given back to the system. 774 // 775 // The `pad' argument to malloc_trim represents the amount of free 776 // trailing space to leave untrimmed. If this argument is zero, only the 777 // minimum amount of memory to maintain internal data structures will be 778 // left (one page or less). Non-zero arguments can be supplied to maintain 779 // enough trailing space to service future expected allocations without 780 // having to re-obtain memory from the system. 781 // 782 // Malloc_trim returns 1 if it actually released any memory, else 0. On 783 // systems that do not support "negative sbrks", it will always return 0. 784 // 785 // For simplicity, we always return 0. 786 #define MALLOC_TRIM(soname, fnname) \ 787 \ 788 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \ 789 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \ 790 { \ 791 /* 0 denotes that malloc_trim() either wasn't able \ 792 to do anything, or was not implemented */ \ 793 return 0; \ 794 } 795 796 #if defined(VGO_linux) 797 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); 798 799 #elif defined(VGO_darwin) 800 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); 801 802 #endif 803 804 805 /*---------------------- posix_memalign ----------------------*/ 806 807 #define POSIX_MEMALIGN(soname, fnname) \ 808 \ 809 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \ 810 ( void **memptr, SizeT alignment, SizeT size ); \ 811 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \ 812 ( void **memptr, SizeT alignment, SizeT size ) \ 813 { \ 814 void *mem; \ 815 \ 816 /* Test whether the alignment argument is valid. It must be \ 817 a power of two multiple of sizeof (void *). */ \ 818 if (alignment % sizeof (void *) != 0 \ 819 || (alignment & (alignment - 1)) != 0) \ 820 return VKI_EINVAL; \ 821 \ 822 /* Round up to minimum alignment if necessary. */ \ 823 if (alignment < VG_MIN_MALLOC_SZB) \ 824 alignment = VG_MIN_MALLOC_SZB; \ 825 \ 826 mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size); \ 827 \ 828 if (mem != NULL) { \ 829 *memptr = mem; \ 830 return 0; \ 831 } \ 832 \ 833 return VKI_ENOMEM; \ 834 } 835 836 #if defined(VGO_linux) 837 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); 838 839 #elif defined(VGO_darwin) 840 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); 841 842 #endif 843 844 845 /*---------------------- malloc_usable_size ----------------------*/ 846 847 #define MALLOC_USABLE_SIZE(soname, fnname) \ 848 \ 849 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \ 850 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \ 851 { \ 852 SizeT pszB; \ 853 \ 854 if (!init_done) init(); \ 855 MALLOC_TRACE("malloc_usable_size(%p)", p ); \ 856 if (NULL == p) \ 857 return 0; \ 858 \ 859 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \ 860 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \ 861 \ 862 return pszB; \ 863 } 864 865 #if defined(VGO_linux) 866 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size); 867 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size); 868 869 #elif defined(VGO_darwin) 870 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size); 871 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size); 872 873 #endif 874 875 876 /*---------------------- (unimplemented) ----------------------*/ 877 878 /* Bomb out if we get any of these. */ 879 880 static void panic(const char *str) 881 { 882 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str); 883 my_exit(99); 884 *(volatile int *)0 = 'x'; 885 } 886 887 #define PANIC(soname, fnname) \ 888 \ 889 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \ 890 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \ 891 { \ 892 panic(#fnname); \ 893 } 894 895 #if defined(VGO_linux) 896 PANIC(VG_Z_LIBC_SONAME, pvalloc); 897 PANIC(VG_Z_LIBC_SONAME, malloc_get_state); 898 PANIC(VG_Z_LIBC_SONAME, malloc_set_state); 899 900 #elif defined(VGO_darwin) 901 PANIC(VG_Z_LIBC_SONAME, pvalloc); 902 PANIC(VG_Z_LIBC_SONAME, malloc_get_state); 903 PANIC(VG_Z_LIBC_SONAME, malloc_set_state); 904 905 #endif 906 907 908 #define MALLOC_STATS(soname, fnname) \ 909 \ 910 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \ 911 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \ 912 { \ 913 /* Valgrind's malloc_stats implementation does nothing. */ \ 914 } 915 916 #if defined(VGO_linux) 917 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats); 918 919 #elif defined(VGO_darwin) 920 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats); 921 922 #endif 923 924 925 /*---------------------- mallinfo ----------------------*/ 926 927 // mi must be static; if it is auto then Memcheck thinks it is 928 // uninitialised when used by the caller of this function, because Memcheck 929 // doesn't know that the call to mallinfo fills in mi. 930 #define MALLINFO(soname, fnname) \ 931 \ 932 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \ 933 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \ 934 { \ 935 static struct vg_mallinfo mi; \ 936 if (!init_done) init(); \ 937 MALLOC_TRACE("mallinfo()\n"); \ 938 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \ 939 return mi; \ 940 } 941 942 #if defined(VGO_linux) 943 MALLINFO(VG_Z_LIBC_SONAME, mallinfo); 944 945 #elif defined(VGO_darwin) 946 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo); 947 948 #endif 949 950 951 /*------------------ Darwin zone stuff ------------------*/ 952 953 954 #if defined(VGO_darwin) 955 956 static vki_malloc_zone_t vg_default_zone = { 957 NULL, // reserved1 958 NULL, // reserved2 959 NULL, // GrP fixme: malloc_size 960 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc), 961 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc), 962 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc), 963 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free), 964 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc), 965 NULL, // GrP fixme: destroy 966 "ValgrindMallocZone", 967 NULL, // batch_malloc 968 NULL, // batch_free 969 NULL, // GrP fixme: introspect 970 2, // version (GrP fixme 3?) 971 NULL, /* memalign */ // DDD: this field exists in Mac OS 10.6, but not 10.5. 972 NULL, /* free_definite_size */ 973 NULL, /* pressure_relief */ 974 }; 975 976 #define DEFAULT_ZONE(soname, fnname) \ 977 \ 978 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \ 979 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \ 980 { \ 981 return &vg_default_zone; \ 982 } 983 984 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone); 985 986 #define ZONE_FROM_PTR(soname, fnname) \ 987 \ 988 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \ 989 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ) \ 990 { \ 991 return &vg_default_zone; \ 992 } 993 994 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr); 995 996 997 // GrP fixme bypass libc's use of zone->introspect->check 998 #define ZONE_CHECK(soname, fnname) \ 999 \ 1000 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \ 1001 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone) \ 1002 { \ 1003 return 1; \ 1004 } 1005 1006 //ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check); 1007 1008 #endif /* defined(VGO_darwin) */ 1009 1010 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start); 1011 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start) { 1012 OrigFn fn; 1013 VALGRIND_GET_ORIG_FN(fn); 1014 CALL_FN_v_W(fn, mem_start); 1015 int res; 1016 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MEM_START, mem_start, 0, 0, 0, 0); 1017 } 1018 1019 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file); 1020 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file) { 1021 OrigFn fn; 1022 int ret; 1023 VALGRIND_GET_ORIG_FN(fn); 1024 CALL_FN_W_W(ret, fn, file); 1025 int res; 1026 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_FILE, file, 0, 0, 0, 0); 1027 return ret; 1028 } 1029 1030 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset); 1031 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset) { 1032 OrigFn fn; 1033 VALGRIND_GET_ORIG_FN(fn); 1034 CALL_FN_v_WWW(fn, vma, size, file_offset); 1035 int res; 1036 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MMAP, vma, size, file_offset, 0, 0); 1037 } 1038 1039 /* Handle tcmalloc (http://code.google.com/p/google-perftools/) */ 1040 1041 /* tc_ functions (used when tcmalloc is running in release mode) */ 1042 ALLOC_or_NULL(NONE,tc_malloc,malloc); 1043 ALLOC_or_BOMB(NONE,tc_new,__builtin_new); 1044 ALLOC_or_NULL(NONE,tc_new_nothrow,__builtin_new); 1045 ALLOC_or_BOMB(NONE,tc_newarray,__builtin_vec_new); 1046 ALLOC_or_NULL(NONE,tc_newarray_nothrow,__builtin_vec_new); 1047 FREE(NONE,tc_free,free); 1048 FREE(NONE,tc_cfree,free); 1049 FREE(NONE,tc_delete,__builtin_delete); 1050 FREE(NONE,tc_delete_nothrow,__builtin_delete); 1051 FREE(NONE,tc_deletearray,__builtin_vec_delete); 1052 FREE(NONE,tc_deletearray_nothrow,__builtin_vec_delete); 1053 CALLOC(NONE,tc_calloc); 1054 REALLOC(NONE,tc_realloc); 1055 VALLOC(NONE,tc_valloc); 1056 MEMALIGN(NONE,tc_memalign); 1057 MALLOPT(NONE,tc_mallopt); 1058 POSIX_MEMALIGN(NONE,tc_posix_memalign); 1059 MALLOC_USABLE_SIZE(NONE,tc_malloc_size); 1060 MALLINFO(NONE,tc_mallinfo); 1061 1062 /* Python */ 1063 ALLOC_or_NULL(NONE, PyObject_Malloc, malloc); 1064 FREE(NONE, PyObject_Free, free); 1065 REALLOC(NONE, PyObject_Realloc); 1066 1067 /* Interceptors for custom malloc functions in user code 1068 (NONE, malloc). We need these to intercept tcmalloc in debug builds. 1069 TODO(kcc): get rid of these once we have tc_malloc/tc_new/etc 1070 in tcmalloc's debugallocation.cc 1071 */ 1072 ALLOC_or_NULL(NONE, malloc, malloc); 1073 ALLOC_or_BOMB(NONE, _Znwj, __builtin_new); 1074 ALLOC_or_BOMB(NONE, _Znwm, __builtin_new); 1075 ALLOC_or_NULL(NONE, _ZnwjRKSt9nothrow_t, __builtin_new); 1076 ALLOC_or_NULL(NONE, _ZnwmRKSt9nothrow_t, __builtin_new); 1077 ALLOC_or_BOMB(NONE, _Znaj, __builtin_vec_new); 1078 ALLOC_or_BOMB(NONE, _Znam, __builtin_vec_new); 1079 ALLOC_or_NULL(NONE, _ZnajRKSt9nothrow_t, __builtin_vec_new); 1080 ALLOC_or_NULL(NONE, _ZnamRKSt9nothrow_t, __builtin_vec_new); 1081 FREE(NONE, free, free ); 1082 FREE(NONE, cfree, free ); 1083 FREE(NONE, _ZdlPv, __builtin_delete ); 1084 FREE(NONE, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 1085 FREE(NONE, _ZdaPv, __builtin_vec_delete ); 1086 FREE(NONE, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 1087 CALLOC(NONE, calloc); 1088 REALLOC(NONE, realloc); 1089 MEMALIGN(NONE, memalign); 1090 VALLOC(NONE, valloc); 1091 MALLOPT(NONE, mallopt); 1092 MALLOC_TRIM(NONE, malloc_trim); 1093 POSIX_MEMALIGN(NONE, posix_memalign); 1094 MALLOC_USABLE_SIZE(NONE, malloc_usable_size); 1095 MALLINFO(NONE, mallinfo); 1096 1097 // TODO(kcc): these are interceptors for bash's malloc. 1098 // The bash interpretor has functions malloc() and sh_malloc() 1099 // as well as free() and sh_free(). And sometimes they are called 1100 // inconsistently (malloc, then sh_free). 1101 // So, if we intercept malloc/free, we also need to intercept 1102 // sh_malloc/sh_free. 1103 // 1104 // Standard valgrind does not intercept user's malloc, so it does not have this 1105 // problem. 1106 // 1107 // Get rid of these once we are able to intercept tcmalloc 1108 // w/o intercepting (NONE,malloc) 1109 ALLOC_or_NULL(NONE, sh_malloc, malloc); 1110 FREE(NONE, sh_free, free ); 1111 FREE(NONE, sh_cfree, free ); 1112 CALLOC(NONE, sh_calloc); 1113 REALLOC(NONE, sh_realloc); 1114 MEMALIGN(NONE, sh_memalign); 1115 VALLOC(NONE, sh_valloc); 1116 1117 /*------- alternative to RUNNING_ON_VALGRIND client request -----*/ 1118 1119 #define ANN_FUNC0(ret_ty, f) \ 1120 ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void); \ 1121 ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void) 1122 1123 ANN_FUNC0(int, RunningOnValgrind) { return 1; } 1124 1125 /*------------------ (startup related) ------------------*/ 1126 1127 /* All the code in here is unused until this function is called */ 1128 1129 __attribute__((constructor)) 1130 static void init(void) 1131 { 1132 1133 // This doesn't look thread-safe, but it should be ok... Bart says: 1134 // 1135 // Every program I know of calls malloc() at least once before calling 1136 // pthread_create(). So init_done gets initialized before any thread is 1137 // created, and is only read when multiple threads are active 1138 // simultaneously. Such an access pattern is safe. 1139 // 1140 // If the assignment to the variable init_done would be triggering a race 1141 // condition, both DRD and Helgrind would report this race. 1142 // 1143 // By the way, although the init() function in 1144 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared 1145 // __attribute__((constructor)), it is not safe to remove the variable 1146 // init_done. This is because it is possible that malloc() and hence 1147 // init() gets called before shared library initialization finished. 1148 // 1149 if (init_done) 1150 return; 1151 1152 init_done = 1; 1153 1154 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info, 1155 0, 0, 0, 0); 1156 } 1157 1158 /*--------------------------------------------------------------------*/ 1159 /*--- end ---*/ 1160 /*--------------------------------------------------------------------*/ 1161