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-2017 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"
73 /* Assignment of behavioural equivalence class tags: 1NNNP is intended
74 to be reserved for the Valgrind core. Current usage:
77 10020 ZONEALLOC_or_NULL
92 10170 MALLOC_USABLE_SIZE
101 10260 ZONE_UNREGISTER
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.
114 mid-06: could be improved, since we can now intercept in the main
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
)
125 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
126 || defined(VGPV_arm64_linux_android)
127 __asm__
__volatile__(".word 0xFFFFFFFF");
129 # elif defined(VGPV_x86_linux_android)
130 __asm__
__volatile__("ud2");
133 extern __attribute__ ((__noreturn__
)) void _exit(int status
);
138 /* Same problem with getpagesize. */
139 static inline int my_getpagesize ( void )
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 */
147 extern int getpagesize (void);
148 return getpagesize();
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
)
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;
168 t
= u1
* v0
+ (w0
>> halfShift
);
172 rHi
= u1
* v1
+ w2
+ (w1
>> halfShift
);
177 /*------------------------------------------------------------*/
178 /*--- Replacing malloc() et al ---*/
179 /*------------------------------------------------------------*/
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
185 static struct vg_mallocfunc_info info
;
186 static int init_done
;
187 #define DO_INIT if (UNLIKELY(!init_done)) init()
189 /* Startup hook - called as init section */
190 __attribute__((constructor
))
191 static void init(void);
193 #define MALLOC_TRACE(format, args...) \
194 if (info.clo_trace_malloc) { \
195 VALGRIND_INTERNAL_PRINTF(format, ## args ); }
197 /* Below are new versions of malloc, __builtin_new, free,
198 __builtin_delete, calloc, realloc, memalign, and friends.
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
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
212 The definedness of such 'unused' arguments will not be verified
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.
220 #define TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(x) \
221 if ((ULong)x == 0) __asm__ __volatile__( "" ::: "memory" )
223 /*---------------------- malloc ----------------------*/
225 /* Generate a replacement for 'fnname' in object 'soname', which calls
226 'vg_replacement' to allocate memory. If that fails, return NULL.
228 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
230 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
231 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \
236 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
237 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
239 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
240 MALLOC_TRACE(" = %p\n", v ); \
244 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
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) \
252 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
253 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
254 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
256 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
257 MALLOC_TRACE(" = %p\n", v ); \
262 /* Generate a replacement for 'fnname' in object 'soname', which calls
263 'vg_replacement' to allocate memory. If that fails, it bombs the
266 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
268 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
269 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \
274 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
275 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
277 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
278 MALLOC_TRACE(" = %p\n", v ); \
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"); \
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.
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
);
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
);
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
);
316 /*---------------------- new ----------------------*/
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
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
);
330 // operator new(unsigned long), GNU mangling
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
);
337 #elif defined(VGO_darwin)
338 // operator new(unsigned int), GNU mangling
340 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
341 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
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);
349 #elif defined(VGO_solaris)
350 // operator new(unsigned int), GNU mangling
352 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME
, _Znwj
, __builtin_new
);
353 ALLOC_or_BOMB(SO_SYN_MALLOC
, _Znwj
, __builtin_new
);
355 // operator new(unsigned long), GNU mangling
357 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME
, _Znwm
, __builtin_new
);
358 ALLOC_or_BOMB(SO_SYN_MALLOC
, _Znwm
, __builtin_new
);
364 /*---------------------- new nothrow ----------------------*/
366 #if defined(VGO_linux)
367 // operator new(unsigned, std::nothrow_t const&), GNU mangling
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
);
373 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
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
);
380 #elif defined(VGO_darwin)
381 // operator new(unsigned, std::nothrow_t const&), GNU mangling
383 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
384 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
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);
392 #elif defined(VGO_solaris)
393 // operator new(unsigned, std::nothrow_t const&), GNU mangling
395 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME
, _ZnwjRKSt9nothrow_t
, __builtin_new
);
396 ALLOC_or_NULL(SO_SYN_MALLOC
, _ZnwjRKSt9nothrow_t
, __builtin_new
);
398 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
400 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME
, _ZnwmRKSt9nothrow_t
, __builtin_new
);
401 ALLOC_or_NULL(SO_SYN_MALLOC
, _ZnwmRKSt9nothrow_t
, __builtin_new
);
407 /*---------------------- new [] ----------------------*/
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
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
);
419 // operator new[](unsigned long), GNU mangling
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
);
426 #elif defined(VGO_darwin)
427 // operator new[](unsigned int), GNU mangling
429 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
430 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
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 );
438 #elif defined(VGO_solaris)
439 // operator new[](unsigned int), GNU mangling
441 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME
, _Znaj
, __builtin_vec_new
);
442 ALLOC_or_BOMB(SO_SYN_MALLOC
, _Znaj
, __builtin_vec_new
);
444 // operator new[](unsigned long), GNU mangling
446 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME
, _Znam
, __builtin_vec_new
);
447 ALLOC_or_BOMB(SO_SYN_MALLOC
, _Znam
, __builtin_vec_new
);
453 /*---------------------- new [] nothrow ----------------------*/
455 #if defined(VGO_linux)
456 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
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
);
462 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
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
);
469 #elif defined(VGO_darwin)
470 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
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 );
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 );
481 #elif defined(VGO_solaris)
482 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
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
);
487 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
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
);
496 /*---------------------- free ----------------------*/
498 /* Generate a replacement for 'fnname' in object 'soname', which calls
499 'vg_replacement' to free previously allocated memory.
501 #define ZONEFREE(soname, fnname, vg_replacement) \
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) \
507 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
508 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
511 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
514 #define FREE(soname, fnname, vg_replacement) \
516 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
517 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
520 MALLOC_TRACE(#fnname "(%p)\n", p ); \
523 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
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
);
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
);
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
);
546 /*---------------------- 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
);
554 #elif defined(VGO_darwin)
555 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
556 //FREE(VG_Z_LIBC_SONAME, cfree, free );
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
);
567 /*---------------------- delete ----------------------*/
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
);
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 );
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
);
591 /*---------------------- delete nothrow ----------------------*/
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
);
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 );
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
);
612 /*---------------------- delete [] ----------------------*/
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
);
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 );
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
);
639 /*---------------------- delete [] nothrow ----------------------*/
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
);
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 );
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
);
660 /*---------------------- calloc ----------------------*/
662 #define ZONECALLOC(soname, fnname) \
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 ) \
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 ); \
677 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
678 MALLOC_TRACE(" = %p\n", v ); \
682 #define CALLOC(soname, fnname) \
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 ) \
692 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
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 ); \
709 #if defined(VGO_linux)
710 CALLOC(VG_Z_LIBC_SONAME
, calloc
);
711 CALLOC(SO_SYN_MALLOC
, calloc
);
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
);
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
);
727 /*---------------------- realloc ----------------------*/
729 #define ZONEREALLOC(soname, fnname) \
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 ) \
739 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
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) \
746 if (new_size <= 0) { \
747 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
748 MALLOC_TRACE(" = 0\n"); \
751 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
752 MALLOC_TRACE(" = %p\n", v ); \
756 #define REALLOC(soname, fnname) \
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 ) \
766 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
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) \
773 if (new_size <= 0) { \
774 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
775 MALLOC_TRACE(" = 0\n"); \
778 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
779 MALLOC_TRACE(" = %p\n", v ); \
783 #if defined(VGO_linux)
784 REALLOC(VG_Z_LIBC_SONAME
, realloc
);
785 REALLOC(SO_SYN_MALLOC
, realloc
);
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
);
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
);
801 /*---------------------- memalign ----------------------*/
803 #define ZONEMEMALIGN(soname, fnname) \
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 ) \
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 ); \
818 /* Round up to minimum alignment if necessary. */ \
819 if (alignment < VG_MIN_MALLOC_SZB) \
820 alignment = VG_MIN_MALLOC_SZB; \
822 /* Round up to nearest power-of-two if necessary (like glibc). */ \
823 while (0 != (alignment & (alignment - 1))) alignment++; \
825 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
826 MALLOC_TRACE(" = %p\n", v ); \
830 #define MEMALIGN(soname, fnname) \
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 ) \
840 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
841 MALLOC_TRACE("memalign(al %llu, size %llu)", \
842 (ULong)alignment, (ULong)n ); \
844 /* Round up to minimum alignment if necessary. */ \
845 if (alignment < VG_MIN_MALLOC_SZB) \
846 alignment = VG_MIN_MALLOC_SZB; \
848 /* Round up to nearest power-of-two if necessary (like glibc). */ \
849 while (0 != (alignment & (alignment - 1))) alignment++; \
851 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
852 MALLOC_TRACE(" = %p\n", v ); \
856 #if defined(VGO_linux)
857 MEMALIGN(VG_Z_LIBC_SONAME
, memalign
);
858 MEMALIGN(SO_SYN_MALLOC
, memalign
);
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
);
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
);
874 /*---------------------- valloc ----------------------*/
876 #define VALLOC(soname, fnname) \
878 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
879 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
881 static int pszB = 0; \
883 pszB = my_getpagesize(); \
884 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
885 ((SizeT)pszB, size); \
888 #define ZONEVALLOC(soname, fnname) \
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 ) \
895 static int 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); \
903 #if defined(VGO_linux)
904 VALLOC(VG_Z_LIBC_SONAME
, valloc
);
905 VALLOC(SO_SYN_MALLOC
, valloc
);
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
);
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
);
921 /*---------------------- mallopt ----------------------*/
923 /* Various compatibility wrapper functions, for glibc and libstdc++. */
925 #define MALLOPT(soname, fnname) \
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 ) \
930 /* In glibc-2.2.4, 1 denotes a successful return value for \
932 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
933 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
937 #if defined(VGO_linux)
938 MALLOPT(VG_Z_LIBC_SONAME
, mallopt
);
939 MALLOPT(SO_SYN_MALLOC
, mallopt
);
941 #elif defined(VGO_darwin)
942 //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
947 /*---------------------- malloc_trim ----------------------*/
948 // Documentation says:
949 // malloc_trim(size_t pad);
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.
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.
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.
969 // For simplicity, we always return 0.
970 #define MALLOC_TRIM(soname, fnname) \
972 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
973 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
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); \
981 #if defined(VGO_linux)
982 MALLOC_TRIM(VG_Z_LIBC_SONAME
, malloc_trim
);
983 MALLOC_TRIM(SO_SYN_MALLOC
, malloc_trim
);
985 #elif defined(VGO_darwin)
986 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
991 /*---------------------- posix_memalign ----------------------*/
993 #define POSIX_MEMALIGN(soname, fnname) \
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 ) \
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; \
1008 mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
1009 (alignment, size); \
1011 if (mem != NULL) { \
1016 return VKI_ENOMEM; \
1019 #if defined(VGO_linux)
1020 POSIX_MEMALIGN(VG_Z_LIBC_SONAME
, posix_memalign
);
1021 POSIX_MEMALIGN(SO_SYN_MALLOC
, posix_memalign
);
1023 #elif defined(VGO_darwin)
1024 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1026 #elif defined(VGO_solaris)
1027 POSIX_MEMALIGN(VG_Z_LIBC_SONAME
, posix_memalign
);
1028 POSIX_MEMALIGN(SO_SYN_MALLOC
, posix_memalign
);
1033 /*---------------------- malloc_usable_size ----------------------*/
1035 #define MALLOC_USABLE_SIZE(soname, fnname) \
1037 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
1038 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
1043 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
1047 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
1048 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
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
);
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
);
1072 /*---------------------- (unimplemented) ----------------------*/
1074 /* Bomb out if we get any of these. */
1076 static void panic(const char *str
) __attribute__((unused
));
1077 static void panic(const char *str
)
1079 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str
);
1083 #define PANIC(soname, fnname) \
1085 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
1086 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
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
);
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
);
1104 #define MALLOC_STATS(soname, fnname) \
1106 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
1107 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
1109 /* Valgrind's malloc_stats implementation does nothing. */ \
1112 #if defined(VGO_linux)
1113 MALLOC_STATS(VG_Z_LIBC_SONAME
, malloc_stats
);
1114 MALLOC_STATS(SO_SYN_MALLOC
, malloc_stats
);
1116 #elif defined(VGO_darwin)
1117 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1122 /*---------------------- mallinfo ----------------------*/
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) \
1129 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1130 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
1132 static struct vg_mallinfo mi; \
1134 MALLOC_TRACE("mallinfo()\n"); \
1135 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1139 #if defined(VGO_linux)
1140 MALLINFO(VG_Z_LIBC_SONAME
, mallinfo
);
1141 MALLINFO(SO_SYN_MALLOC
, mallinfo
);
1143 #elif defined(VGO_darwin)
1144 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1149 /*------------------ Darwin zone stuff ------------------*/
1151 #if defined(VGO_darwin)
1153 static size_t my_malloc_size ( void* zone
, void* ptr
)
1155 /* Implement "malloc_size" by handing the request through to the
1156 tool's .tl_usable_size method. */
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
);
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. */
1168 static vki_malloc_zone_t vg_default_zone
= {
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
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 */
1189 #define DEFAULT_ZONE(soname, fnname) \
1191 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1192 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
1194 return &vg_default_zone; \
1197 DEFAULT_ZONE(VG_Z_LIBC_SONAME
, malloc_default_zone
);
1198 DEFAULT_ZONE(SO_SYN_MALLOC
, malloc_default_zone
);
1199 DEFAULT_ZONE(VG_Z_LIBC_SONAME
, malloc_default_purgeable_zone
);
1200 DEFAULT_ZONE(SO_SYN_MALLOC
, malloc_default_purgeable_zone
);
1203 #define CREATE_ZONE(soname, fnname) \
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) \
1208 return &vg_default_zone; \
1210 CREATE_ZONE(VG_Z_LIBC_SONAME
, malloc_create_zone
);
1213 #define ZONE_FROM_PTR(soname, fnname) \
1215 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
1216 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ) \
1218 return &vg_default_zone; \
1221 ZONE_FROM_PTR(VG_Z_LIBC_SONAME
, malloc_zone_from_ptr
);
1222 ZONE_FROM_PTR(SO_SYN_MALLOC
, malloc_zone_from_ptr
);
1225 // GrP fixme bypass libc's use of zone->introspect->check
1226 #define ZONE_CHECK(soname, fnname) \
1228 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
1229 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone) \
1231 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1236 ZONE_CHECK(VG_Z_LIBC_SONAME
, malloc_zone_check
);
1237 ZONE_CHECK(SO_SYN_MALLOC
, malloc_zone_check
);
1240 #define ZONE_REGISTER(soname, fnname) \
1242 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
1243 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone) \
1245 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1248 ZONE_REGISTER(VG_Z_LIBC_SONAME
, malloc_zone_register
);
1249 ZONE_REGISTER(SO_SYN_MALLOC
, malloc_zone_register
);
1252 #define ZONE_UNREGISTER(soname, fnname) \
1254 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
1255 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone) \
1257 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1260 ZONE_UNREGISTER(VG_Z_LIBC_SONAME
, malloc_zone_unregister
);
1261 ZONE_UNREGISTER(SO_SYN_MALLOC
, malloc_zone_unregister
);
1264 #define ZONE_SET_NAME(soname, fnname) \
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) \
1269 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1272 ZONE_SET_NAME(VG_Z_LIBC_SONAME
, malloc_set_zone_name
);
1273 ZONE_SET_NAME(SO_SYN_MALLOC
, malloc_set_zone_name
);
1276 #define ZONE_GET_NAME(soname, fnname) \
1278 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
1279 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone) \
1281 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1282 return vg_default_zone.zone_name; \
1285 ZONE_GET_NAME(VG_Z_LIBC_SONAME
, malloc_get_zone_name
);
1286 ZONE_GET_NAME(SO_SYN_MALLOC
, malloc_get_zone_name
);
1288 #endif /* defined(VGO_darwin) */
1291 /*------------------ (startup related) ------------------*/
1293 /* All the code in here is unused until this function is called */
1295 __attribute__((constructor
))
1296 static void init(void)
1298 // This doesn't look thread-safe, but it should be ok... Bart says:
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.
1305 // If the assignment to the variable init_done would be triggering a race
1306 // condition, both DRD and Helgrind would report this race.
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.
1319 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS
, &info
,
1323 /*--------------------------------------------------------------------*/
1325 /*--------------------------------------------------------------------*/