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