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-2013 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) || defined(VGPV_mips32_linux_android) 120 __asm__ __volatile__(".word 0xFFFFFFFF"); 121 while (1) {} 122 # elif defined(VGPV_x86_linux_android) 123 __asm__ __volatile__("ud2"); 124 while (1) {} 125 # else 126 extern __attribute__ ((__noreturn__)) void _exit(int status); 127 _exit(x); 128 # endif 129 } 130 131 /* Same problem with getpagesize. */ 132 static inline int my_getpagesize ( void ) 133 { 134 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ 135 || defined(VGPV_mips32_linux_android) 136 return 4096; /* kludge - link failure on Android, for some reason */ 137 # else 138 extern int getpagesize (void); 139 return getpagesize(); 140 # endif 141 } 142 143 144 /* Compute the high word of the double-length unsigned product of U 145 and V. This is for calloc argument overflow checking; see comments 146 below. Algorithm as described in Hacker's Delight, chapter 8. */ 147 static UWord umulHW ( UWord u, UWord v ) 148 { 149 UWord u0, v0, w0, rHi; 150 UWord u1, v1, w1,w2,t; 151 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF 152 : (UWord)0xFFFFFFFFULL; 153 UWord halfShift = sizeof(UWord)==4 ? 16 : 32; 154 u0 = u & halfMask; 155 u1 = u >> halfShift; 156 v0 = v & halfMask; 157 v1 = v >> halfShift; 158 w0 = u0 * v0; 159 t = u1 * v0 + (w0 >> halfShift); 160 w1 = t & halfMask; 161 w2 = t >> halfShift; 162 w1 = u0 * v1 + w1; 163 rHi = u1 * v1 + w2 + (w1 >> halfShift); 164 return rHi; 165 } 166 167 168 /*------------------------------------------------------------*/ 169 /*--- Replacing malloc() et al ---*/ 170 /*------------------------------------------------------------*/ 171 172 /* This struct is initially empty. Before the first use of any of 173 these functions, we make a client request which fills in the 174 fields. 175 */ 176 static struct vg_mallocfunc_info info; 177 static int init_done; 178 #define DO_INIT if (UNLIKELY(!init_done)) init() 179 180 /* Startup hook - called as init section */ 181 __attribute__((constructor)) 182 static void init(void); 183 184 #define MALLOC_TRACE(format, args...) \ 185 if (info.clo_trace_malloc) { \ 186 VALGRIND_INTERNAL_PRINTF(format, ## args ); } 187 188 /* Below are new versions of malloc, __builtin_new, free, 189 __builtin_delete, calloc, realloc, memalign, and friends. 190 191 None of these functions are called directly - they are not meant to 192 be found by the dynamic linker. But ALL client calls to malloc() 193 and friends wind up here eventually. They get called because 194 vg_replace_malloc installs a bunch of code redirects which causes 195 Valgrind to use these functions rather than the ones they're 196 replacing. 197 */ 198 199 /* The replacement functions are running on the simulated CPU. 200 The code on the simulated CPU does not necessarily use 201 all arguments. E.g. args can be ignored and/or only given 202 to a NON SIMD call. 203 The definedness of such 'unused' arguments will not be verified 204 by memcheck. 205 A call to 'trigger_memcheck_error_if_undefined' allows 206 memcheck to detect such errors for the otherwise unused args. 207 Apart of allowing memcheck to detect an error, the function 208 trigger_memcheck_error_if_undefined has no effect and 209 has a minimal cost for other tools replacing malloc functions. 210 */ 211 static inline void trigger_memcheck_error_if_undefined ( ULong x ) 212 { 213 if (x == 0) __asm__ __volatile__( "" ::: "memory" ); 214 } 215 216 /*---------------------- malloc ----------------------*/ 217 218 /* Generate a replacement for 'fnname' in object 'soname', which calls 219 'vg_replacement' to allocate memory. If that fails, return NULL. 220 */ 221 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \ 222 \ 223 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \ 224 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \ 225 { \ 226 void* v; \ 227 \ 228 DO_INIT; \ 229 trigger_memcheck_error_if_undefined((ULong)n ); \ 230 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ 231 \ 232 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 233 MALLOC_TRACE(" = %p\n", v ); \ 234 return v; \ 235 } 236 237 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \ 238 \ 239 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \ 240 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \ 241 { \ 242 void* v; \ 243 \ 244 DO_INIT; \ 245 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \ 246 trigger_memcheck_error_if_undefined((ULong) n); \ 247 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \ 248 \ 249 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 250 MALLOC_TRACE(" = %p\n", v ); \ 251 return v; \ 252 } 253 254 255 /* Generate a replacement for 'fnname' in object 'soname', which calls 256 'vg_replacement' to allocate memory. If that fails, it bombs the 257 system. 258 */ 259 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \ 260 \ 261 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \ 262 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \ 263 { \ 264 void* v; \ 265 \ 266 DO_INIT; \ 267 trigger_memcheck_error_if_undefined((ULong) n); \ 268 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ 269 \ 270 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ 271 MALLOC_TRACE(" = %p\n", v ); \ 272 if (NULL == v) { \ 273 VALGRIND_PRINTF( \ 274 "new/new[] failed and should throw an exception, but Valgrind\n"); \ 275 VALGRIND_PRINTF_BACKTRACE( \ 276 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \ 277 my_exit(1); \ 278 } \ 279 return v; \ 280 } 281 282 // Each of these lines generates a replacement function: 283 // (from_so, from_fn, v's replacement) 284 // For some lines, we will also define a replacement function 285 // whose only purpose is to be a soname synonym place holder 286 // that can be replaced using --soname-synonyms. 287 #define SO_SYN_MALLOC VG_SO_SYN(somalloc) 288 289 // malloc 290 #if defined(VGO_linux) 291 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc); 292 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc); 293 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc); 294 295 #elif defined(VGO_darwin) 296 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc); 297 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc); 298 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc); 299 ZONEALLOC_or_NULL(SO_SYN_MALLOC, malloc_zone_malloc, malloc); 300 301 #endif 302 303 304 /*---------------------- new ----------------------*/ 305 306 #if defined(VGO_linux) 307 // operator new(unsigned int), not mangled (for gcc 2.96) 308 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new); 309 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new); 310 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new); 311 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new); 312 // operator new(unsigned int), GNU mangling 313 #if VG_WORDSIZE == 4 314 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); 315 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new); 316 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new); 317 #endif 318 // operator new(unsigned long), GNU mangling 319 #if VG_WORDSIZE == 8 320 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); 321 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new); 322 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new); 323 #endif 324 325 #elif defined(VGO_darwin) 326 // operator new(unsigned int), GNU mangling 327 #if VG_WORDSIZE == 4 328 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); 329 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new); 330 #endif 331 // operator new(unsigned long), GNU mangling 332 #if 1 // FIXME: is this right? 333 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); 334 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new); 335 #endif 336 337 #endif 338 339 340 /*---------------------- new nothrow ----------------------*/ 341 342 #if defined(VGO_linux) 343 // operator new(unsigned, std::nothrow_t const&), GNU mangling 344 #if VG_WORDSIZE == 4 345 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 346 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 347 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new); 348 #endif 349 // operator new(unsigned long, std::nothrow_t const&), GNU mangling 350 #if VG_WORDSIZE == 8 351 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 352 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 353 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new); 354 #endif 355 356 #elif defined(VGO_darwin) 357 // operator new(unsigned, std::nothrow_t const&), GNU mangling 358 #if VG_WORDSIZE == 4 359 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 360 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); 361 #endif 362 // operator new(unsigned long, std::nothrow_t const&), GNU mangling 363 #if 1 // FIXME: is this right? 364 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 365 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); 366 #endif 367 368 #endif 369 370 371 /*---------------------- new [] ----------------------*/ 372 373 #if defined(VGO_linux) 374 // operator new[](unsigned int), not mangled (for gcc 2.96) 375 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new ); 376 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new ); 377 // operator new[](unsigned int), GNU mangling 378 #if VG_WORDSIZE == 4 379 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); 380 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new ); 381 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new ); 382 #endif 383 // operator new[](unsigned long), GNU mangling 384 #if VG_WORDSIZE == 8 385 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); 386 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new ); 387 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new ); 388 #endif 389 390 #elif defined(VGO_darwin) 391 // operator new[](unsigned int), GNU mangling 392 #if VG_WORDSIZE == 4 393 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); 394 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new ); 395 #endif 396 // operator new[](unsigned long), GNU mangling 397 #if 1 // FIXME: is this right? 398 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); 399 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new ); 400 #endif 401 402 #endif 403 404 405 /*---------------------- new [] nothrow ----------------------*/ 406 407 #if defined(VGO_linux) 408 // operator new[](unsigned, std::nothrow_t const&), GNU mangling 409 #if VG_WORDSIZE == 4 410 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 411 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 412 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 413 #endif 414 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling 415 #if VG_WORDSIZE == 8 416 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 417 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 418 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 419 #endif 420 421 #elif defined(VGO_darwin) 422 // operator new[](unsigned, std::nothrow_t const&), GNU mangling 423 #if VG_WORDSIZE == 4 424 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 425 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); 426 #endif 427 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling 428 #if 1 // FIXME: is this right? 429 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 430 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); 431 #endif 432 433 #endif 434 435 436 /*---------------------- free ----------------------*/ 437 438 /* Generate a replacement for 'fnname' in object 'soname', which calls 439 'vg_replacement' to free previously allocated memory. 440 */ 441 #define ZONEFREE(soname, fnname, vg_replacement) \ 442 \ 443 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \ 444 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \ 445 { \ 446 DO_INIT; \ 447 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \ 448 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \ 449 if (p == NULL) \ 450 return; \ 451 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ 452 } 453 454 #define FREE(soname, fnname, vg_replacement) \ 455 \ 456 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \ 457 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \ 458 { \ 459 DO_INIT; \ 460 MALLOC_TRACE(#fnname "(%p)\n", p ); \ 461 if (p == NULL) \ 462 return; \ 463 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ 464 } 465 466 467 #if defined(VGO_linux) 468 FREE(VG_Z_LIBSTDCXX_SONAME, free, free ); 469 FREE(VG_Z_LIBC_SONAME, free, free ); 470 FREE(SO_SYN_MALLOC, free, free ); 471 472 #elif defined(VGO_darwin) 473 FREE(VG_Z_LIBC_SONAME, free, free ); 474 FREE(SO_SYN_MALLOC, free, free ); 475 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free ); 476 ZONEFREE(SO_SYN_MALLOC, malloc_zone_free, free ); 477 478 #endif 479 480 481 /*---------------------- cfree ----------------------*/ 482 483 // cfree 484 #if defined(VGO_linux) 485 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free ); 486 FREE(VG_Z_LIBC_SONAME, cfree, free ); 487 FREE(SO_SYN_MALLOC, cfree, free ); 488 489 #elif defined(VGO_darwin) 490 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free ); 491 //FREE(VG_Z_LIBC_SONAME, cfree, free ); 492 493 #endif 494 495 496 /*---------------------- delete ----------------------*/ 497 498 #if defined(VGO_linux) 499 // operator delete(void*), not mangled (for gcc 2.96) 500 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete ); 501 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete ); 502 // operator delete(void*), GNU mangling 503 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete ); 504 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete ); 505 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete ); 506 507 #elif defined(VGO_darwin) 508 // operator delete(void*), GNU mangling 509 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete ); 510 //FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete ); 511 512 #endif 513 514 515 /*---------------------- delete nothrow ----------------------*/ 516 517 #if defined(VGO_linux) 518 // operator delete(void*, std::nothrow_t const&), GNU mangling 519 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 520 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 521 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 522 523 #elif defined(VGO_darwin) 524 // operator delete(void*, std::nothrow_t const&), GNU mangling 525 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 526 //FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); 527 528 #endif 529 530 531 /*---------------------- delete [] ----------------------*/ 532 533 #if defined(VGO_linux) 534 // operator delete[](void*), not mangled (for gcc 2.96) 535 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 536 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 537 // operator delete[](void*), GNU mangling 538 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); 539 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete ); 540 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete ); 541 542 #elif defined(VGO_darwin) 543 // operator delete[](void*), not mangled (for gcc 2.96) 544 //FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 545 //FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete ); 546 // operator delete[](void*), GNU mangling 547 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); 548 //FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete ); 549 550 #endif 551 552 553 /*---------------------- delete [] nothrow ----------------------*/ 554 555 #if defined(VGO_linux) 556 // operator delete[](void*, std::nothrow_t const&), GNU mangling 557 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 558 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 559 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 560 561 #elif defined(VGO_darwin) 562 // operator delete[](void*, std::nothrow_t const&), GNU mangling 563 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 564 //FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); 565 566 #endif 567 568 569 /*---------------------- calloc ----------------------*/ 570 571 #define ZONECALLOC(soname, fnname) \ 572 \ 573 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \ 574 ( void *zone, SizeT nmemb, SizeT size ); \ 575 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \ 576 ( void *zone, SizeT nmemb, SizeT size ) \ 577 { \ 578 void* v; \ 579 \ 580 DO_INIT; \ 581 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \ 582 trigger_memcheck_error_if_undefined((ULong) nmemb); \ 583 trigger_memcheck_error_if_undefined((ULong) size); \ 584 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \ 585 \ 586 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ 587 MALLOC_TRACE(" = %p\n", v ); \ 588 return v; \ 589 } 590 591 #define CALLOC(soname, fnname) \ 592 \ 593 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \ 594 ( SizeT nmemb, SizeT size ); \ 595 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \ 596 ( SizeT nmemb, SizeT size ) \ 597 { \ 598 void* v; \ 599 \ 600 DO_INIT; \ 601 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \ 602 \ 603 /* Protect against overflow. See bug 24078. (that bug number is 604 invalid. Which one really?) */ \ 605 /* But don't use division, since that produces an external symbol 606 reference on ARM, in the form of a call to __aeabi_uidiv. It's 607 normally OK, because ld.so manages to resolve it to something in the 608 executable, or one of its shared objects. But that isn't guaranteed 609 to be the case, and it has been observed to fail in rare cases, eg: 610 echo x | valgrind /bin/sed -n "s/.*-\>\ //p" 611 So instead compute the high word of the product and check it is zero. */ \ 612 if (umulHW(size, nmemb) != 0) return NULL; \ 613 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ 614 MALLOC_TRACE(" = %p\n", v ); \ 615 return v; \ 616 } 617 618 #if defined(VGO_linux) 619 CALLOC(VG_Z_LIBC_SONAME, calloc); 620 CALLOC(SO_SYN_MALLOC, calloc); 621 622 #elif defined(VGO_darwin) 623 CALLOC(VG_Z_LIBC_SONAME, calloc); 624 CALLOC(SO_SYN_MALLOC, calloc); 625 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); 626 ZONECALLOC(SO_SYN_MALLOC, malloc_zone_calloc); 627 628 #endif 629 630 631 /*---------------------- realloc ----------------------*/ 632 633 #define ZONEREALLOC(soname, fnname) \ 634 \ 635 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \ 636 ( void *zone, void* ptrV, SizeT new_size ); \ 637 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \ 638 ( void *zone, void* ptrV, SizeT new_size ) \ 639 { \ 640 void* v; \ 641 \ 642 DO_INIT; \ 643 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \ 644 \ 645 if (ptrV == NULL) \ 646 /* We need to call a malloc-like function; so let's use \ 647 one which we know exists. GrP fixme use zonemalloc instead? */ \ 648 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \ 649 (new_size); \ 650 if (new_size <= 0) { \ 651 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ 652 MALLOC_TRACE(" = 0\n"); \ 653 return NULL; \ 654 } \ 655 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ 656 MALLOC_TRACE(" = %p\n", v ); \ 657 return v; \ 658 } 659 660 #define REALLOC(soname, fnname) \ 661 \ 662 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \ 663 ( void* ptrV, SizeT new_size );\ 664 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \ 665 ( void* ptrV, SizeT new_size ) \ 666 { \ 667 void* v; \ 668 \ 669 DO_INIT; \ 670 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \ 671 \ 672 if (ptrV == NULL) \ 673 /* We need to call a malloc-like function; so let's use \ 674 one which we know exists. */ \ 675 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \ 676 (new_size); \ 677 if (new_size <= 0) { \ 678 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ 679 MALLOC_TRACE(" = 0\n"); \ 680 return NULL; \ 681 } \ 682 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ 683 MALLOC_TRACE(" = %p\n", v ); \ 684 return v; \ 685 } 686 687 #if defined(VGO_linux) 688 REALLOC(VG_Z_LIBC_SONAME, realloc); 689 REALLOC(SO_SYN_MALLOC, realloc); 690 691 #elif defined(VGO_darwin) 692 REALLOC(VG_Z_LIBC_SONAME, realloc); 693 REALLOC(SO_SYN_MALLOC, realloc); 694 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc); 695 ZONEREALLOC(SO_SYN_MALLOC, malloc_zone_realloc); 696 697 #endif 698 699 700 /*---------------------- memalign ----------------------*/ 701 702 #define ZONEMEMALIGN(soname, fnname) \ 703 \ 704 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ 705 ( void *zone, SizeT alignment, SizeT n ); \ 706 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ 707 ( void *zone, SizeT alignment, SizeT n ) \ 708 { \ 709 void* v; \ 710 \ 711 DO_INIT; \ 712 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \ 713 trigger_memcheck_error_if_undefined((ULong) n); \ 714 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \ 715 zone, (ULong)alignment, (ULong)n ); \ 716 \ 717 /* Round up to minimum alignment if necessary. */ \ 718 if (alignment < VG_MIN_MALLOC_SZB) \ 719 alignment = VG_MIN_MALLOC_SZB; \ 720 \ 721 /* Round up to nearest power-of-two if necessary (like glibc). */ \ 722 while (0 != (alignment & (alignment - 1))) alignment++; \ 723 \ 724 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ 725 MALLOC_TRACE(" = %p\n", v ); \ 726 return v; \ 727 } 728 729 #define MEMALIGN(soname, fnname) \ 730 \ 731 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ 732 ( SizeT alignment, SizeT n ); \ 733 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ 734 ( SizeT alignment, SizeT n ) \ 735 { \ 736 void* v; \ 737 \ 738 DO_INIT; \ 739 trigger_memcheck_error_if_undefined((ULong) n); \ 740 MALLOC_TRACE("memalign(al %llu, size %llu)", \ 741 (ULong)alignment, (ULong)n ); \ 742 \ 743 /* Round up to minimum alignment if necessary. */ \ 744 if (alignment < VG_MIN_MALLOC_SZB) \ 745 alignment = VG_MIN_MALLOC_SZB; \ 746 \ 747 /* Round up to nearest power-of-two if necessary (like glibc). */ \ 748 while (0 != (alignment & (alignment - 1))) alignment++; \ 749 \ 750 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ 751 MALLOC_TRACE(" = %p\n", v ); \ 752 return v; \ 753 } 754 755 #if defined(VGO_linux) 756 MEMALIGN(VG_Z_LIBC_SONAME, memalign); 757 MEMALIGN(SO_SYN_MALLOC, memalign); 758 759 #elif defined(VGO_darwin) 760 MEMALIGN(VG_Z_LIBC_SONAME, memalign); 761 MEMALIGN(SO_SYN_MALLOC, memalign); 762 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign); 763 ZONEMEMALIGN(SO_SYN_MALLOC, malloc_zone_memalign); 764 765 #endif 766 767 768 /*---------------------- valloc ----------------------*/ 769 770 #define VALLOC(soname, fnname) \ 771 \ 772 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \ 773 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \ 774 { \ 775 static int pszB = 0; \ 776 if (pszB == 0) \ 777 pszB = my_getpagesize(); \ 778 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ 779 ((SizeT)pszB, size); \ 780 } 781 782 #define ZONEVALLOC(soname, fnname) \ 783 \ 784 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \ 785 ( void *zone, SizeT size ); \ 786 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \ 787 ( void *zone, SizeT size ) \ 788 { \ 789 static int pszB = 0; \ 790 if (pszB == 0) \ 791 pszB = my_getpagesize(); \ 792 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \ 793 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ 794 ((SizeT)pszB, size); \ 795 } 796 797 #if defined(VGO_linux) 798 VALLOC(VG_Z_LIBC_SONAME, valloc); 799 VALLOC(SO_SYN_MALLOC, valloc); 800 801 #elif defined(VGO_darwin) 802 VALLOC(VG_Z_LIBC_SONAME, valloc); 803 VALLOC(SO_SYN_MALLOC, valloc); 804 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc); 805 ZONEVALLOC(SO_SYN_MALLOC, malloc_zone_valloc); 806 807 #endif 808 809 810 /*---------------------- mallopt ----------------------*/ 811 812 /* Various compatibility wrapper functions, for glibc and libstdc++. */ 813 814 #define MALLOPT(soname, fnname) \ 815 \ 816 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \ 817 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \ 818 { \ 819 /* In glibc-2.2.4, 1 denotes a successful return value for \ 820 mallopt */ \ 821 trigger_memcheck_error_if_undefined((ULong) cmd); \ 822 trigger_memcheck_error_if_undefined((ULong) value); \ 823 return 1; \ 824 } 825 826 #if defined(VGO_linux) 827 MALLOPT(VG_Z_LIBC_SONAME, mallopt); 828 MALLOPT(SO_SYN_MALLOC, mallopt); 829 830 #elif defined(VGO_darwin) 831 //MALLOPT(VG_Z_LIBC_SONAME, mallopt); 832 833 #endif 834 835 836 /*---------------------- malloc_trim ----------------------*/ 837 // Documentation says: 838 // malloc_trim(size_t pad); 839 // 840 // If possible, gives memory back to the system (via negative arguments to 841 // sbrk) if there is unused memory at the `high' end of the malloc pool. 842 // You can call this after freeing large blocks of memory to potentially 843 // reduce the system-level memory requirements of a program. However, it 844 // cannot guarantee to reduce memory. Under some allocation patterns, 845 // some large free blocks of memory will be locked between two used 846 // chunks, so they cannot be given back to the system. 847 // 848 // The `pad' argument to malloc_trim represents the amount of free 849 // trailing space to leave untrimmed. If this argument is zero, only the 850 // minimum amount of memory to maintain internal data structures will be 851 // left (one page or less). Non-zero arguments can be supplied to maintain 852 // enough trailing space to service future expected allocations without 853 // having to re-obtain memory from the system. 854 // 855 // Malloc_trim returns 1 if it actually released any memory, else 0. On 856 // systems that do not support "negative sbrks", it will always return 0. 857 // 858 // For simplicity, we always return 0. 859 #define MALLOC_TRIM(soname, fnname) \ 860 \ 861 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \ 862 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \ 863 { \ 864 /* 0 denotes that malloc_trim() either wasn't able \ 865 to do anything, or was not implemented */ \ 866 trigger_memcheck_error_if_undefined((ULong) pad); \ 867 return 0; \ 868 } 869 870 #if defined(VGO_linux) 871 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); 872 MALLOC_TRIM(SO_SYN_MALLOC, malloc_trim); 873 874 #elif defined(VGO_darwin) 875 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); 876 877 #endif 878 879 880 /*---------------------- posix_memalign ----------------------*/ 881 882 #define POSIX_MEMALIGN(soname, fnname) \ 883 \ 884 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \ 885 ( void **memptr, SizeT alignment, SizeT size ); \ 886 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \ 887 ( void **memptr, SizeT alignment, SizeT size ) \ 888 { \ 889 void *mem; \ 890 \ 891 /* Test whether the alignment argument is valid. It must be \ 892 a power of two multiple of sizeof (void *). */ \ 893 if (alignment % sizeof (void *) != 0 \ 894 || (alignment & (alignment - 1)) != 0) \ 895 return VKI_EINVAL; \ 896 \ 897 mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ 898 (alignment, size); \ 899 \ 900 if (mem != NULL) { \ 901 *memptr = mem; \ 902 return 0; \ 903 } \ 904 \ 905 return VKI_ENOMEM; \ 906 } 907 908 #if defined(VGO_linux) 909 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); 910 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign); 911 912 #elif defined(VGO_darwin) 913 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); 914 915 #endif 916 917 918 /*---------------------- malloc_usable_size ----------------------*/ 919 920 #define MALLOC_USABLE_SIZE(soname, fnname) \ 921 \ 922 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \ 923 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \ 924 { \ 925 SizeT pszB; \ 926 \ 927 DO_INIT; \ 928 MALLOC_TRACE("malloc_usable_size(%p)", p ); \ 929 if (NULL == p) \ 930 return 0; \ 931 \ 932 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \ 933 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \ 934 \ 935 return pszB; \ 936 } 937 938 #if defined(VGO_linux) 939 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size); 940 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_usable_size); 941 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size); 942 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size); 943 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ 944 || defined(VGPV_mips32_linux_android) 945 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size); 946 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, dlmalloc_usable_size); 947 # endif 948 949 #elif defined(VGO_darwin) 950 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size); 951 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size); 952 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size); 953 954 #endif 955 956 957 /*---------------------- (unimplemented) ----------------------*/ 958 959 /* Bomb out if we get any of these. */ 960 961 static void panic(const char *str) 962 { 963 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str); 964 my_exit(99); 965 *(volatile int *)0 = 'x'; 966 } 967 968 #define PANIC(soname, fnname) \ 969 \ 970 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \ 971 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \ 972 { \ 973 panic(#fnname); \ 974 } 975 976 #if defined(VGO_linux) 977 PANIC(VG_Z_LIBC_SONAME, pvalloc); 978 PANIC(VG_Z_LIBC_SONAME, malloc_get_state); 979 PANIC(VG_Z_LIBC_SONAME, malloc_set_state); 980 981 #elif defined(VGO_darwin) 982 PANIC(VG_Z_LIBC_SONAME, pvalloc); 983 PANIC(VG_Z_LIBC_SONAME, malloc_get_state); 984 PANIC(VG_Z_LIBC_SONAME, malloc_set_state); 985 986 #endif 987 988 989 #define MALLOC_STATS(soname, fnname) \ 990 \ 991 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \ 992 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \ 993 { \ 994 /* Valgrind's malloc_stats implementation does nothing. */ \ 995 } 996 997 #if defined(VGO_linux) 998 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats); 999 MALLOC_STATS(SO_SYN_MALLOC, malloc_stats); 1000 1001 #elif defined(VGO_darwin) 1002 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats); 1003 1004 #endif 1005 1006 1007 /*---------------------- mallinfo ----------------------*/ 1008 1009 // mi must be static; if it is auto then Memcheck thinks it is 1010 // uninitialised when used by the caller of this function, because Memcheck 1011 // doesn't know that the call to mallinfo fills in mi. 1012 #define MALLINFO(soname, fnname) \ 1013 \ 1014 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \ 1015 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \ 1016 { \ 1017 static struct vg_mallinfo mi; \ 1018 DO_INIT; \ 1019 MALLOC_TRACE("mallinfo()\n"); \ 1020 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \ 1021 return mi; \ 1022 } 1023 1024 #if defined(VGO_linux) 1025 MALLINFO(VG_Z_LIBC_SONAME, mallinfo); 1026 MALLINFO(SO_SYN_MALLOC, mallinfo); 1027 1028 #elif defined(VGO_darwin) 1029 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo); 1030 1031 #endif 1032 1033 1034 /*------------------ Darwin zone stuff ------------------*/ 1035 1036 #if defined(VGO_darwin) 1037 1038 static size_t my_malloc_size ( void* zone, void* ptr ) 1039 { 1040 /* Implement "malloc_size" by handing the request through to the 1041 tool's .tl_usable_size method. */ 1042 DO_INIT; 1043 trigger_memcheck_error_if_undefined((ULong)(UWord) zone); 1044 trigger_memcheck_error_if_undefined((ULong)(UWord) ptr); 1045 size_t res = (size_t)VALGRIND_NON_SIMD_CALL1( 1046 info.tl_malloc_usable_size, ptr); 1047 return res; 1048 } 1049 1050 /* Note that the (void*) casts below are a kludge which stops 1051 compilers complaining about the fact that the the replacement 1052 functions aren't really of the right type. */ 1053 static vki_malloc_zone_t vg_default_zone = { 1054 NULL, // reserved1 1055 NULL, // reserved2 1056 (void*)my_malloc_size, // JRS fixme: is this right? 1057 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc), 1058 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc), 1059 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc), 1060 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free), 1061 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc), 1062 NULL, // GrP fixme: destroy 1063 "ValgrindMallocZone", 1064 NULL, // batch_malloc 1065 NULL, // batch_free 1066 NULL, // GrP fixme: introspect 1067 2, // version (GrP fixme 3?) 1068 NULL, /* memalign */ // DDD: this field exists in Mac OS 10.6, but not 10.5. 1069 NULL, /* free_definite_size */ 1070 NULL, /* pressure_relief */ 1071 }; 1072 1073 1074 #define DEFAULT_ZONE(soname, fnname) \ 1075 \ 1076 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \ 1077 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \ 1078 { \ 1079 return &vg_default_zone; \ 1080 } 1081 1082 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone); 1083 DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_zone); 1084 1085 1086 #define ZONE_FROM_PTR(soname, fnname) \ 1087 \ 1088 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \ 1089 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ) \ 1090 { \ 1091 return &vg_default_zone; \ 1092 } 1093 1094 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr); 1095 ZONE_FROM_PTR(SO_SYN_MALLOC, malloc_zone_from_ptr); 1096 1097 1098 // GrP fixme bypass libc's use of zone->introspect->check 1099 #define ZONE_CHECK(soname, fnname) \ 1100 \ 1101 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \ 1102 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone) \ 1103 { \ 1104 trigger_memcheck_error_if_undefined((ULong) zone); \ 1105 return 1; \ 1106 } 1107 1108 //ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check); 1109 1110 #endif /* defined(VGO_darwin) */ 1111 1112 1113 /*------------------ (startup related) ------------------*/ 1114 1115 /* All the code in here is unused until this function is called */ 1116 1117 __attribute__((constructor)) 1118 static void init(void) 1119 { 1120 // This doesn't look thread-safe, but it should be ok... Bart says: 1121 // 1122 // Every program I know of calls malloc() at least once before calling 1123 // pthread_create(). So init_done gets initialized before any thread is 1124 // created, and is only read when multiple threads are active 1125 // simultaneously. Such an access pattern is safe. 1126 // 1127 // If the assignment to the variable init_done would be triggering a race 1128 // condition, both DRD and Helgrind would report this race. 1129 // 1130 // By the way, although the init() function in 1131 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared 1132 // __attribute__((constructor)), it is not safe to remove the variable 1133 // init_done. This is because it is possible that malloc() and hence 1134 // init() gets called before shared library initialization finished. 1135 // 1136 if (init_done) 1137 return; 1138 1139 init_done = 1; 1140 1141 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info, 1142 0, 0, 0, 0); 1143 } 1144 1145 /*--------------------------------------------------------------------*/ 1146 /*--- end ---*/ 1147 /*--------------------------------------------------------------------*/ 1148