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