2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for malloc() et al, which run on the simulated ---*/
4 /*--- CPU. vg_replace_malloc.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2010 Julian Seward
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.
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.
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
29 The GNU General Public License is contained in the file COPYING.
32 /* ---------------------------------------------------------------------
33 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
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.
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'.
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.
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.
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
61 to see all the undefined symbols in all the preload shared objects.
62 ------------------------------------------------------------------ */
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"
74 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
75 mangling, could be supported properly by the redirects in this
76 module. Except we can't because it doesn't put its allocation
77 functions in libpgc.so but instead hardwires them into the
78 compilation unit holding main(), which makes them impossible to
79 intercept directly. Fortunately those fns seem to route everything
80 through to malloc/free.
82 mid-06: could be improved, since we can now intercept in the main
86 __attribute__ ((__noreturn__))
87 extern void _exit(int);
89 /* Apparently it is necessary to make ourselves free of any dependency
90 on memcpy() on ppc32-aix5; else programs linked with -brtl fail.
91 memcpy() is used by gcc for a struct assignment in mallinfo()
92 below. Add the following conservative implementation (memmove,
94 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
96 void *memcpy(void *destV, const void *srcV, unsigned long n)
98 unsigned char* src = (unsigned char*)srcV;
99 unsigned char* dest = (unsigned char*)destV;
102 for (i = 0; i < n; i++)
106 for (i = n; i > 0; i--)
107 dest[i-1] = src[i-1];
114 /* Compute the high word of the double-length unsigned product of U
115 and V. This is for calloc argument overflow checking; see comments
116 below. Algorithm as described in Hacker's Delight, chapter 8. */
117 static UWord umulHW ( UWord u, UWord v )
119 UWord u0, v0, w0, rHi;
120 UWord u1, v1, w1,w2,t;
121 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF
122 : (UWord)0xFFFFFFFFULL;
123 UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
129 t = u1 * v0 + (w0 >> halfShift);
133 rHi = u1 * v1 + w2 + (w1 >> halfShift);
138 /*------------------------------------------------------------*/
139 /*--- Replacing malloc() et al ---*/
140 /*------------------------------------------------------------*/
142 /* This struct is initially empty. Before the first use of any of
143 these functions, we make a client request which fills in the
146 static struct vg_mallocfunc_info info;
147 static int init_done;
149 /* Startup hook - called as init section */
150 __attribute__((constructor))
151 static void init(void);
153 #define MALLOC_TRACE(format, args...) \
154 if (info.clo_trace_malloc) { \
155 VALGRIND_INTERNAL_PRINTF(format, ## args ); }
157 /* Below are new versions of malloc, __builtin_new, free,
158 __builtin_delete, calloc, realloc, memalign, and friends.
160 None of these functions are called directly - they are not meant to
161 be found by the dynamic linker. But ALL client calls to malloc()
162 and friends wind up here eventually. They get called because
163 vg_replace_malloc installs a bunch of code redirects which causes
164 Valgrind to use these functions rather than the ones they're
169 /*---------------------- malloc ----------------------*/
171 /* Generate a replacement for 'fnname' in object 'soname', which calls
172 'vg_replacement' to allocate memory. If that fails, return NULL.
174 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
176 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
177 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
181 if (!init_done) init(); \
182 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
184 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
185 MALLOC_TRACE(" = %p\n", v ); \
189 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
191 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n); \
192 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n) \
196 if (!init_done) init(); \
197 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
199 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
200 MALLOC_TRACE(" = %p\n", v ); \
205 /* Generate a replacement for 'fnname' in object 'soname', which calls
206 'vg_replacement' to allocate memory. If that fails, it bombs the
209 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
211 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
212 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
216 if (!init_done) init(); \
217 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
219 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
220 MALLOC_TRACE(" = %p\n", v ); \
222 VALGRIND_PRINTF_BACKTRACE( \
223 "new/new[] failed and should throw an exception, but Valgrind\n"); \
224 VALGRIND_PRINTF_BACKTRACE( \
225 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \
231 // Each of these lines generates a replacement function:
232 // (from_so, from_fn, v's replacement)
235 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
236 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
237 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
238 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_common, malloc);
239 #elif defined(VGO_darwin)
240 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
244 /*---------------------- new ----------------------*/
246 // operator new(unsigned int), not mangled (for gcc 2.96)
247 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
248 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
250 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
251 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
253 // operator new(unsigned int), GNU mangling
255 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
256 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
259 // operator new(unsigned long), GNU mangling
260 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGO_darwin)
261 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
262 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
265 // operator new(unsigned long), ARM/cfront mangling
266 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
267 ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __nw__FUl, __builtin_new);
271 /*---------------------- new nothrow ----------------------*/
273 // operator new(unsigned, std::nothrow_t const&), GNU mangling
275 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
276 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
279 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
280 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
281 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
282 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
285 // operator new(unsigned long, std::nothrow_t const&), ARM/cfront mangling
286 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
287 ALLOC_or_NULL(VG_Z_LIBC_DOT_A, __nw__FUlRCQ2_3std9nothrow_t, __builtin_new);
291 /*---------------------- new [] ----------------------*/
293 // operator new[](unsigned int), not mangled (for gcc 2.96)
294 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
295 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
297 // operator new[](unsigned int), GNU mangling
299 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
300 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
303 // operator new[](unsigned long), GNU mangling
304 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
305 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
306 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
309 // operator new[](unsigned long), ARM/cfront mangling
310 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
311 ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __vn__FUl, __builtin_vec_new);
315 /*---------------------- new [] nothrow ----------------------*/
317 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
319 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
320 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
323 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
324 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
325 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
326 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
329 // operator new [](unsigned long, std::nothrow_t const&), ARM/cfront mangling
330 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
331 ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __vn__FUlRCQ2_3std9nothrow_t, __builtin_vec_new );
335 /*---------------------- free ----------------------*/
337 /* Generate a replacement for 'fnname' in object 'soname', which calls
338 'vg_replacement' to free previously allocated memory.
340 #define ZONEFREE(soname, fnname, vg_replacement) \
342 void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p); \
343 void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p) \
345 if (!init_done) init(); \
346 MALLOC_TRACE(#vg_replacement "(%p, %p)\n", zone, p ); \
349 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
352 #define FREE(soname, fnname, vg_replacement) \
354 void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p); \
355 void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p) \
357 if (!init_done) init(); \
358 MALLOC_TRACE(#vg_replacement "(%p)\n", p ); \
361 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
365 FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
366 FREE(VG_Z_LIBC_SONAME, free, free );
367 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
368 FREE(VG_Z_LIBC_SONAME, free_common, free );
369 #elif defined(VGO_darwin)
370 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
374 /*---------------------- cfree ----------------------*/
377 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
378 FREE(VG_Z_LIBC_SONAME, cfree, free );
381 /*---------------------- delete ----------------------*/
382 // operator delete(void*), not mangled (for gcc 2.96)
383 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
384 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
386 // operator delete(void*), GNU mangling
387 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
388 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
390 // operator delete(void*), ARM/cfront mangling
391 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
392 FREE(VG_Z_LIBC_DOT_A, __dl__FPv, __builtin_delete );
396 /*---------------------- delete nothrow ----------------------*/
398 // operator delete(void*, std::nothrow_t const&), GNU mangling
399 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
400 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
403 /*---------------------- delete [] ----------------------*/
404 // operator delete[](void*), not mangled (for gcc 2.96)
405 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
406 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
408 // operator delete[](void*), GNU mangling
409 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
410 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
412 // operator delete[](void*), ARM/cfront mangling
413 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
414 FREE(VG_Z_LIBC_DOT_A, __vd__FPv, __builtin_vec_delete );
418 /*---------------------- delete [] nothrow ----------------------*/
420 // operator delete[](void*, std::nothrow_t const&), GNU mangling
421 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
422 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
425 /*---------------------- calloc ----------------------*/
427 #define ZONECALLOC(soname, fnname) \
429 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size ); \
430 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size ) \
434 if (!init_done) init(); \
435 MALLOC_TRACE("calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
437 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
438 MALLOC_TRACE(" = %p\n", v ); \
442 #define CALLOC(soname, fnname) \
444 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ); \
445 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ) \
449 if (!init_done) init(); \
450 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
452 /* Protect against overflow. See bug 24078. (that bug number is
453 invalid. Which one really?) */ \
454 /* But don't use division, since that produces an external symbol
455 reference on ARM, in the form of a call to __aeabi_uidiv. It's
456 normally OK, because ld.so manages to resolve it to something in the
457 executable, or one of its shared objects. But that isn't guaranteed
458 to be the case, and it has been observed to fail in rare cases, eg:
459 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
460 So instead compute the high word of the product and check it is zero. */ \
461 if (umulHW(size, nmemb) != 0) return NULL; \
462 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
463 MALLOC_TRACE(" = %p\n", v ); \
467 CALLOC(VG_Z_LIBC_SONAME, calloc);
468 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
469 CALLOC(VG_Z_LIBC_SONAME, calloc_common);
470 #elif defined(VGO_darwin)
471 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
475 /*---------------------- realloc ----------------------*/
477 #define ZONEREALLOC(soname, fnname) \
479 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size );\
480 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size ) \
484 if (!init_done) init(); \
485 MALLOC_TRACE("realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
488 /* We need to call a malloc-like function; so let's use \
489 one which we know exists. GrP fixme use zonemalloc instead? */ \
490 return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
491 if (new_size <= 0) { \
492 VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
493 MALLOC_TRACE(" = 0\n"); \
496 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
497 MALLOC_TRACE(" = %p\n", v ); \
501 #define REALLOC(soname, fnname) \
503 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size );\
504 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size ) \
508 if (!init_done) init(); \
509 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
512 /* We need to call a malloc-like function; so let's use \
513 one which we know exists. */ \
514 return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
515 if (new_size <= 0) { \
516 VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
517 MALLOC_TRACE(" = 0\n"); \
520 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
521 MALLOC_TRACE(" = %p\n", v ); \
525 REALLOC(VG_Z_LIBC_SONAME, realloc);
526 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
527 REALLOC(VG_Z_LIBC_SONAME, realloc_common);
528 #elif defined(VGO_darwin)
529 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
533 /*---------------------- memalign ----------------------*/
535 #define ZONEMEMALIGN(soname, fnname) \
537 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ); \
538 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ) \
542 if (!init_done) init(); \
543 MALLOC_TRACE("memalign(%p, al %llu, size %llu)", \
544 zone, (ULong)alignment, (ULong)n ); \
546 /* Round up to minimum alignment if necessary. */ \
547 if (alignment < VG_MIN_MALLOC_SZB) \
548 alignment = VG_MIN_MALLOC_SZB; \
550 /* Round up to nearest power-of-two if necessary (like glibc). */ \
551 while (0 != (alignment & (alignment - 1))) alignment++; \
553 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
554 MALLOC_TRACE(" = %p\n", v ); \
558 #define MEMALIGN(soname, fnname) \
560 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ); \
561 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ) \
565 if (!init_done) init(); \
566 MALLOC_TRACE("memalign(al %llu, size %llu)", \
567 (ULong)alignment, (ULong)n ); \
569 /* Round up to minimum alignment if necessary. */ \
570 if (alignment < VG_MIN_MALLOC_SZB) \
571 alignment = VG_MIN_MALLOC_SZB; \
573 /* Round up to nearest power-of-two if necessary (like glibc). */ \
574 while (0 != (alignment & (alignment - 1))) alignment++; \
576 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
577 MALLOC_TRACE(" = %p\n", v ); \
581 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
582 #if defined(VGO_darwin)
583 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
587 /*---------------------- valloc ----------------------*/
589 static int local__getpagesize ( void ) {
590 # if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
591 return 4096; /* kludge - toc problems prevent calling getpagesize() */
593 extern int getpagesize (void);
594 return getpagesize();
598 #define VALLOC(soname, fnname) \
600 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
601 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ) \
603 static int pszB = 0; \
605 pszB = local__getpagesize(); \
606 return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
607 ((SizeT)pszB, size); \
610 #define ZONEVALLOC(soname, fnname) \
612 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size ); \
613 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size ) \
615 static int pszB = 0; \
616 extern int getpagesize (void); \
618 pszB = getpagesize(); \
619 return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
620 ((SizeT)pszB, size); \
623 VALLOC(VG_Z_LIBC_SONAME, valloc);
624 #if defined(VGO_darwin)
625 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
629 /*---------------------- mallopt ----------------------*/
631 /* Various compatibility wrapper functions, for glibc and libstdc++. */
633 #define MALLOPT(soname, fnname) \
635 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ); \
636 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ) \
638 /* In glibc-2.2.4, 1 denotes a successful return value for \
643 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
646 /*---------------------- malloc_trim ----------------------*/
647 // Documentation says:
648 // malloc_trim(size_t pad);
650 // If possible, gives memory back to the system (via negative arguments to
651 // sbrk) if there is unused memory at the `high' end of the malloc pool.
652 // You can call this after freeing large blocks of memory to potentially
653 // reduce the system-level memory requirements of a program. However, it
654 // cannot guarantee to reduce memory. Under some allocation patterns,
655 // some large free blocks of memory will be locked between two used
656 // chunks, so they cannot be given back to the system.
658 // The `pad' argument to malloc_trim represents the amount of free
659 // trailing space to leave untrimmed. If this argument is zero, only the
660 // minimum amount of memory to maintain internal data structures will be
661 // left (one page or less). Non-zero arguments can be supplied to maintain
662 // enough trailing space to service future expected allocations without
663 // having to re-obtain memory from the system.
665 // Malloc_trim returns 1 if it actually released any memory, else 0. On
666 // systems that do not support "negative sbrks", it will always return 0.
668 // For simplicity, we always return 0.
669 #define MALLOC_TRIM(soname, fnname) \
671 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ); \
672 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ) \
674 /* 0 denotes that malloc_trim() either wasn't able \
675 to do anything, or was not implemented */ \
679 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
682 /*---------------------- posix_memalign ----------------------*/
684 #define POSIX_MEMALIGN(soname, fnname) \
686 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
687 SizeT alignment, SizeT size ); \
688 int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
689 SizeT alignment, SizeT size ) \
693 /* Test whether the alignment argument is valid. It must be \
694 a power of two multiple of sizeof (void *). */ \
695 if (alignment % sizeof (void *) != 0 \
696 || (alignment & (alignment - 1)) != 0) \
699 mem = VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign)(alignment, size); \
709 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
710 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
711 /* 27 Nov 07: it appears that xlc links into executables, a
712 posix_memalign, which calls onwards to memalign_common, with the
714 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, memalign_common);
718 /*---------------------- malloc_usable_size ----------------------*/
720 #define MALLOC_USABLE_SIZE(soname, fnname) \
722 SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ); \
723 SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ) \
727 if (!init_done) init(); \
728 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
732 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
733 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
738 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
739 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
742 /*---------------------- (unimplemented) ----------------------*/
744 /* Bomb out if we get any of these. */
746 static void panic(const char *str)
748 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
753 #define PANIC(soname, fnname) \
755 void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
756 void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
761 PANIC(VG_Z_LIBC_SONAME, pvalloc);
762 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
763 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
765 #define MALLOC_STATS(soname, fnname) \
767 void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
768 void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
770 /* Valgrind's malloc_stats implementation does nothing. */ \
773 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
776 /*---------------------- mallinfo ----------------------*/
778 // mi must be static; if it is auto then Memcheck thinks it is
779 // uninitialised when used by the caller of this function, because Memcheck
780 // doesn't know that the call to mallinfo fills in mi.
781 #define MALLINFO(soname, fnname) \
783 struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
784 struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
786 static struct vg_mallinfo mi; \
787 if (!init_done) init(); \
788 MALLOC_TRACE("mallinfo()\n"); \
789 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
793 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
796 #if defined(VGO_darwin)
798 static vki_malloc_zone_t vg_default_zone = {
801 NULL, // GrP fixme malloc_size
802 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_malloc),
803 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_calloc),
804 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_valloc),
805 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_free),
806 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_realloc),
807 NULL, // GrP fixme destroy
808 "ValgrindMallocZone",
809 NULL, // batch_malloc
811 NULL, // GrP fixme introspect
812 2, // version (GrP fixme 3?)
813 // DDD: this field exists in Mac OS 10.6, but not 10.5.
815 (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_memalign)
819 #define DEFAULT_ZONE(soname, fnname) \
821 void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
822 void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
824 return &vg_default_zone; \
827 #if defined(VGO_darwin)
828 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
829 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
832 // GrP fixme bypass libc's use of zone->introspect->check
833 #define ZONE_CHECK(soname, fnname) \
835 int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone); \
836 int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone) \
841 #if defined(VGO_darwin)
842 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
848 /* All the code in here is unused until this function is called */
850 __attribute__((constructor))
851 static void init(void)
855 // This doesn't look thread-safe, but it should be ok... Bart says:
857 // Every program I know of calls malloc() at least once before calling
858 // pthread_create(). So init_done gets initialized before any thread is
859 // created, and is only read when multiple threads are active
860 // simultaneously. Such an access pattern is safe.
862 // If the assignment to the variable init_done would be triggering a race
863 // condition, both DRD and Helgrind would report this race.
865 // By the way, although the init() function in
866 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
867 // __attribute__((constructor)), it is not safe to remove the variable
868 // init_done. This is because it is possible that malloc() and hence
869 // init() gets called before shared library initialization finished.
876 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
880 /*--------------------------------------------------------------------*/
882 /*--------------------------------------------------------------------*/