Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / coregrind / m_replacemalloc / vg_replace_malloc.c
blob9fb0069b171a2e315ba76617de92b00cc4893078
2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for malloc() et al, which run on the simulated ---*/
4 /*--- CPU. vg_replace_malloc.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2017 Julian Seward
12 jseward@acm.org
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
27 02111-1307, USA.
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.
56 A useful command is
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
59 done
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:
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
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
115 executable too.
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");
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
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 */
146 # else
147 extern int getpagesize (void);
148 return getpagesize();
149 # endif
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;
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;
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
183 fields.
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
205 replacing.
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.
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) \
233 void* v; \
235 DO_INIT; \
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 ); \
241 return 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) \
249 void* v; \
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 ); \
256 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
257 MALLOC_TRACE(" = %p\n", v ); \
258 return v; \
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.
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) \
271 void* v; \
273 DO_INIT; \
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 ); \
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); \
286 return v; \
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.
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);
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);
313 #endif
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
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
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
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
361 #endif
364 /*---------------------- new nothrow ----------------------*/
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
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
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
404 #endif
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
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
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
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
450 #endif
453 /*---------------------- new [] nothrow ----------------------*/
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
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
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
493 #endif
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) \
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 ); \
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) \
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 ); \
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 );
543 #endif
546 /*---------------------- cfree ----------------------*/
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 );
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 );
564 #endif
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 );
588 #endif
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 );
609 #endif
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 );
636 #endif
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 );
657 #endif
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 ) \
669 void* v; \
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 ); \
677 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
678 MALLOC_TRACE(" = %p\n", v ); \
679 return 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 ) \
689 void* v; \
691 DO_INIT; \
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 ); \
706 return 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);
724 #endif
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 ) \
736 void* v; \
738 DO_INIT; \
739 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
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; \
751 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
752 MALLOC_TRACE(" = %p\n", v ); \
753 return 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 ) \
763 void* v; \
765 DO_INIT; \
766 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
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; \
778 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
779 MALLOC_TRACE(" = %p\n", v ); \
780 return 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);
798 #endif
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 ) \
810 void* v; \
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 ); \
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 ); \
827 return 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 ) \
837 void* v; \
839 DO_INIT; \
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 ); \
853 return 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);
871 #endif
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; \
882 if (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; \
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); \
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);
918 #endif
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 \
931 mallopt */ \
932 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
933 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
934 return 1; \
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);
944 #endif
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); \
978 return 0; \
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);
988 #endif
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 ) \
1000 void *mem; \
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) { \
1012 *memptr = mem; \
1013 return 0; \
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);
1030 #endif
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 ) \
1040 SizeT pszB; \
1042 DO_INIT; \
1043 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
1044 if (NULL == p) \
1045 return 0; \
1047 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
1048 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
1050 return 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);
1062 # endif
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);
1069 #endif
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);
1080 my_exit(1);
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 ) \
1088 panic(#fnname); \
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);
1101 #endif
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);
1119 #endif
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; \
1133 DO_INIT; \
1134 MALLOC_TRACE("mallinfo()\n"); \
1135 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1136 return 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);
1146 #endif
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. */
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;
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 = {
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 */
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); \
1232 panic(#fnname); \
1233 return 1; \
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.
1314 if (init_done)
1315 return;
1317 init_done = 1;
1319 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1320 0, 0, 0, 0);
1323 /*--------------------------------------------------------------------*/
1324 /*--- end ---*/
1325 /*--------------------------------------------------------------------*/