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