1
2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for malloc() et al, which run on the simulated ---*/
4 /*--- CPU. vg_replace_malloc.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2011 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30 */
31
32 /* ---------------------------------------------------------------------
33 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
34
35 These functions are drop-in replacements for malloc() and friends.
36 They have global scope, but are not intended to be called directly.
37 See pub_core_redir.h for the gory details.
38
39 This file can be linked into the vg_preload_<tool>.so file for any tool
40 that wishes to know about calls to malloc(). The tool must define all
41 the functions that will be called via 'info'.
42
43 It is called vg_replace_malloc.c because this filename appears in stack
44 traces, so we want the name to be (hopefully!) meaningful to users.
45
46 IMPORTANT: this file must not contain any floating point code, nor
47 any integer division. This is because on ARM these can cause calls
48 to helper functions, which will be unresolved within this .so.
49 Although it is usually the case that the client's ld.so instance
50 can bind them at runtime to the relevant functions in the client
51 executable, there is no guarantee of this; and so the client may
52 die via a runtime link failure. Hence the only safe approach is to
53 avoid such function calls in the first place. See "#define CALLOC"
54 below for a specific example.
55
56 A useful command is
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
59 done
60
61 to see all the undefined symbols in all the preload shared objects.
62 ------------------------------------------------------------------ */
63
64 #include "pub_core_basics.h"
65 #include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM
66 #include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF,
67 // VALGRIND_NON_SIMD_CALL[12]
68 #include "pub_core_debuginfo.h" // needed for pub_core_redir.h :(
69 #include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
70 #include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_*
71 #include "pub_core_replacemalloc.h"
72
73 /* Assignment of behavioural equivalence class tags: 1NNNP is intended
74 to be reserved for the Valgrind core. Current usage:
75
76 10010 ALLOC_or_NULL
77 10020 ZONEALLOC_or_NULL
78 10030 ALLOC_or_BOMB
79 10040 ZONEFREE
80 10050 FREE
81 10060 ZONECALLOC
82 10070 CALLOC
83 10080 ZONEREALLOC
84 10090 REALLOC
85 10100 ZONEMEMALIGN
86 10110 MEMALIGN
87 10120 VALLOC
88 10130 ZONEVALLOC
89 10140 MALLOPT
90 10150 MALLOC_TRIM
91 10160 POSIX_MEMALIGN
92 10170 MALLOC_USABLE_SIZE
93 10180 PANIC
94 10190 MALLOC_STATS
95 10200 MALLINFO
96 10210 DEFAULT_ZONE
97 10220 ZONE_CHECK
98 */
99
100 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
101 mangling, could be supported properly by the redirects in this
102 module. Except we can't because it doesn't put its allocation
103 functions in libpgc.so but instead hardwires them into the
104 compilation unit holding main(), which makes them impossible to
105 intercept directly. Fortunately those fns seem to route everything
106 through to malloc/free.
107
108 mid-06: could be improved, since we can now intercept in the main
109 executable too.
110 */
111
112
113
114 /* Call here to exit if we can't continue. On Android we can't call
115 _exit for some reason, so we have to blunt-instrument it. */
116 __attribute__ ((__noreturn__))
my_exit(int x)117 static inline void my_exit ( int x )
118 {
119 # if defined(VGPV_arm_linux_android)
120 __asm__ __volatile__(".word 0xFFFFFFFF");
121 while (1) {}
122 # else
123 extern __attribute__ ((__noreturn__)) void _exit(int status);
124 _exit(x);
125 # endif
126 }
127
128 /* Same problem with getpagesize. */
my_getpagesize(void)129 static inline int my_getpagesize ( void )
130 {
131 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
132 return 4096; /* kludge - link failure on Android, for some reason */
133 # else
134 extern int getpagesize (void);
135 return getpagesize();
136 # endif
137 }
138
139
140 /* Compute the high word of the double-length unsigned product of U
141 and V. This is for calloc argument overflow checking; see comments
142 below. Algorithm as described in Hacker's Delight, chapter 8. */
umulHW(UWord u,UWord v)143 static UWord umulHW ( UWord u, UWord v )
144 {
145 UWord u0, v0, w0, rHi;
146 UWord u1, v1, w1,w2,t;
147 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF
148 : (UWord)0xFFFFFFFFULL;
149 UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
150 u0 = u & halfMask;
151 u1 = u >> halfShift;
152 v0 = v & halfMask;
153 v1 = v >> halfShift;
154 w0 = u0 * v0;
155 t = u1 * v0 + (w0 >> halfShift);
156 w1 = t & halfMask;
157 w2 = t >> halfShift;
158 w1 = u0 * v1 + w1;
159 rHi = u1 * v1 + w2 + (w1 >> halfShift);
160 return rHi;
161 }
162
163
164 /*------------------------------------------------------------*/
165 /*--- Replacing malloc() et al ---*/
166 /*------------------------------------------------------------*/
167
168 /* This struct is initially empty. Before the first use of any of
169 these functions, we make a client request which fills in the
170 fields.
171 */
172 static struct vg_mallocfunc_info info;
173 static int init_done;
174
175 /* Startup hook - called as init section */
176 __attribute__((constructor))
177 static void init(void);
178
179 #define MALLOC_TRACE(format, args...) \
180 if (info.clo_trace_malloc) { \
181 VALGRIND_INTERNAL_PRINTF(format, ## args ); }
182
183 /* Below are new versions of malloc, __builtin_new, free,
184 __builtin_delete, calloc, realloc, memalign, and friends.
185
186 None of these functions are called directly - they are not meant to
187 be found by the dynamic linker. But ALL client calls to malloc()
188 and friends wind up here eventually. They get called because
189 vg_replace_malloc installs a bunch of code redirects which causes
190 Valgrind to use these functions rather than the ones they're
191 replacing.
192 */
193
194
195 /*---------------------- malloc ----------------------*/
196
197 /* Generate a replacement for 'fnname' in object 'soname', which calls
198 'vg_replacement' to allocate memory. If that fails, return NULL.
199 */
200 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
201 \
202 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
203 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \
204 { \
205 void* v; \
206 \
207 if (!init_done) init(); \
208 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
209 \
210 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
211 MALLOC_TRACE(" = %p\n", v ); \
212 return v; \
213 }
214
215 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
216 \
217 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
218 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \
219 { \
220 void* v; \
221 \
222 if (!init_done) init(); \
223 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
224 \
225 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
226 MALLOC_TRACE(" = %p\n", v ); \
227 return v; \
228 }
229
230
231 /* Generate a replacement for 'fnname' in object 'soname', which calls
232 'vg_replacement' to allocate memory. If that fails, it bombs the
233 system.
234 */
235 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
236 \
237 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
238 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \
239 { \
240 void* v; \
241 \
242 if (!init_done) init(); \
243 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
244 \
245 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
246 MALLOC_TRACE(" = %p\n", v ); \
247 if (NULL == v) { \
248 VALGRIND_PRINTF( \
249 "new/new[] failed and should throw an exception, but Valgrind\n"); \
250 VALGRIND_PRINTF_BACKTRACE( \
251 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \
252 my_exit(1); \
253 } \
254 return v; \
255 }
256
257 // Each of these lines generates a replacement function:
258 // (from_so, from_fn, v's replacement)
259
260 // malloc
261 #if defined(VGO_linux)
262 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
263 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
264
265 #elif defined(VGO_darwin)
266 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
267 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
268
269 #endif
270
271
272 /*---------------------- new ----------------------*/
273
274 #if defined(VGO_linux)
275 // operator new(unsigned int), not mangled (for gcc 2.96)
276 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
277 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
278 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
279 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
280 // operator new(unsigned int), GNU mangling
281 #if VG_WORDSIZE == 4
282 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
283 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
284 #endif
285 // operator new(unsigned long), GNU mangling
286 #if VG_WORDSIZE == 8
287 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
288 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
289 #endif
290
291 #elif defined(VGO_darwin)
292 // glider: hereafter we uncomment the interceptors for operator new
293 // and operator delete, see https://bugs.kde.org/show_bug.cgi?id=286849
294 // operator new(unsigned int), GNU mangling
295 #if VG_WORDSIZE == 4
296 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
297 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
298 #endif
299 // operator new(unsigned long), GNU mangling
300 #if 1 // FIXME: is this right?
301 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
302 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
303 #endif
304
305 #endif
306
307 /*---------------------- new nothrow ----------------------*/
308 // operator new(unsigned, std::nothrow_t const&), GNU mangling
309
310 #if defined(VGO_linux)
311 // operator new(unsigned, std::nothrow_t const&), GNU mangling
312 #if VG_WORDSIZE == 4
313 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
314 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
315 #endif
316 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
317 #if VG_WORDSIZE == 8
318 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
319 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
320 #endif
321 #elif defined(VGO_darwin)
322 // operator new(unsigned, std::nothrow_t const&), GNU mangling
323 #if VG_WORDSIZE == 4
324 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
325 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
326 #endif
327 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
328 #if 1 // FIXME: is this right?
329 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
330 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
331 #endif
332 #endif
333
334
335 /*---------------------- new [] ----------------------*/
336
337 #if defined(VGO_linux)
338 // operator new[](unsigned int), not mangled (for gcc 2.96)
339 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
340 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
341 // operator new[](unsigned int), GNU mangling
342 #if VG_WORDSIZE == 4
343 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
344 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
345 #endif
346 // operator new[](unsigned long), GNU mangling
347 #if VG_WORDSIZE == 8
348 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
349 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
350 #endif
351
352 #elif defined(VGO_darwin)
353 // operator new[](unsigned int), GNU mangling
354 #if VG_WORDSIZE == 4
355 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
356 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
357 #endif
358 // operator new[](unsigned long), GNU mangling
359 #if 1 // FIXME: is this right?
360 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
361 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
362 #endif
363
364 #endif
365
366
367 /*---------------------- new [] nothrow ----------------------*/
368
369 #if defined(VGO_linux)
370 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
371 #if VG_WORDSIZE == 4
372 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
373 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
374 #endif
375 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
376 #if VG_WORDSIZE == 8
377 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
378 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
379 #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, _ZnajRKSt9nothrow_t, __builtin_vec_new );
384 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_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, _ZnamRKSt9nothrow_t, __builtin_vec_new );
389 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
390 #endif
391
392 #endif
393
394
395 /*---------------------- free ----------------------*/
396
397 /* Generate a replacement for 'fnname' in object 'soname', which calls
398 'vg_replacement' to free previously allocated memory.
399 */
400 #define ZONEFREE(soname, fnname, vg_replacement) \
401 \
402 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
403 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
404 { \
405 if (!init_done) init(); \
406 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
407 if (p == NULL) \
408 return; \
409 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
410 }
411
412 #define FREE(soname, fnname, vg_replacement) \
413 \
414 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
415 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
416 { \
417 if (!init_done) init(); \
418 MALLOC_TRACE(#fnname "(%p)\n", p ); \
419 if (p == NULL) \
420 return; \
421 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
422 }
423
424 #if defined(VGO_linux)
425 FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
426 FREE(VG_Z_LIBC_SONAME, free, free );
427
428 #elif defined(VGO_darwin)
429 FREE(VG_Z_LIBC_SONAME, free, free );
430 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
431
432 #endif
433
434
435 /*---------------------- cfree ----------------------*/
436
437 // cfree
438 #if defined(VGO_linux)
439 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
440 FREE(VG_Z_LIBC_SONAME, cfree, free );
441
442 #elif defined(VGO_darwin)
443 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
444 //FREE(VG_Z_LIBC_SONAME, cfree, free );
445
446 #endif
447
448
449 /*---------------------- delete ----------------------*/
450
451 #if defined(VGO_linux)
452 // operator delete(void*), not mangled (for gcc 2.96)
453 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
454 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
455 // operator delete(void*), GNU mangling
456 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
457 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
458
459 #elif defined(VGO_darwin)
460 // operator delete(void*), GNU mangling
461 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
462 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
463
464 #endif
465
466
467 /*---------------------- delete nothrow ----------------------*/
468
469 #if defined(VGO_linux)
470 // operator delete(void*, std::nothrow_t const&), GNU mangling
471 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
472 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
473
474 #elif defined(VGO_darwin)
475 // operator delete(void*, std::nothrow_t const&), GNU mangling
476 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
477 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
478
479 #endif
480
481
482 /*---------------------- delete [] ----------------------*/
483
484 #if defined(VGO_linux)
485 // operator delete[](void*), not mangled (for gcc 2.96)
486 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
487 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
488 // operator delete[](void*), GNU mangling
489 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
490 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
491
492 #elif defined(VGO_darwin)
493 // operator delete[](void*), not mangled (for gcc 2.96)
494 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
495 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
496 // operator delete[](void*), GNU mangling
497 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
498 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
499
500 #endif
501
502
503 /*---------------------- delete [] nothrow ----------------------*/
504
505 #if defined(VGO_linux)
506 // operator delete[](void*, std::nothrow_t const&), GNU mangling
507 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
508 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
509
510 #elif defined(VGO_darwin)
511 // operator delete[](void*, std::nothrow_t const&), GNU mangling
512 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
513 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
514
515 #endif
516
517
518 /*---------------------- calloc ----------------------*/
519
520 #define ZONECALLOC(soname, fnname) \
521 \
522 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
523 ( void *zone, SizeT nmemb, SizeT size ); \
524 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
525 ( void *zone, SizeT nmemb, SizeT size ) \
526 { \
527 void* v; \
528 \
529 if (!init_done) init(); \
530 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
531 \
532 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
533 MALLOC_TRACE(" = %p\n", v ); \
534 return v; \
535 }
536
537 #define CALLOC(soname, fnname) \
538 \
539 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
540 ( SizeT nmemb, SizeT size ); \
541 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
542 ( SizeT nmemb, SizeT size ) \
543 { \
544 void* v; \
545 \
546 if (!init_done) init(); \
547 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
548 \
549 /* Protect against overflow. See bug 24078. (that bug number is
550 invalid. Which one really?) */ \
551 /* But don't use division, since that produces an external symbol
552 reference on ARM, in the form of a call to __aeabi_uidiv. It's
553 normally OK, because ld.so manages to resolve it to something in the
554 executable, or one of its shared objects. But that isn't guaranteed
555 to be the case, and it has been observed to fail in rare cases, eg:
556 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
557 So instead compute the high word of the product and check it is zero. */ \
558 if (umulHW(size, nmemb) != 0) return NULL; \
559 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
560 MALLOC_TRACE(" = %p\n", v ); \
561 return v; \
562 }
563
564 #if defined(VGO_linux)
565 CALLOC(VG_Z_LIBC_SONAME, calloc);
566
567 #elif defined(VGO_darwin)
568 CALLOC(VG_Z_LIBC_SONAME, calloc);
569 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
570
571 #endif
572
573
574 /*---------------------- realloc ----------------------*/
575
576 #define ZONEREALLOC(soname, fnname) \
577 \
578 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
579 ( void *zone, void* ptrV, SizeT new_size ); \
580 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
581 ( void *zone, void* ptrV, SizeT new_size ) \
582 { \
583 void* v; \
584 \
585 if (!init_done) init(); \
586 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
587 \
588 if (ptrV == NULL) \
589 /* We need to call a malloc-like function; so let's use \
590 one which we know exists. GrP fixme use zonemalloc instead? */ \
591 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
592 (new_size); \
593 if (new_size <= 0) { \
594 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
595 MALLOC_TRACE(" = 0\n"); \
596 return NULL; \
597 } \
598 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
599 MALLOC_TRACE(" = %p\n", v ); \
600 return v; \
601 }
602
603 #define REALLOC(soname, fnname) \
604 \
605 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
606 ( void* ptrV, SizeT new_size );\
607 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
608 ( void* ptrV, SizeT new_size ) \
609 { \
610 void* v; \
611 \
612 if (!init_done) init(); \
613 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
614 \
615 if (ptrV == NULL) \
616 /* We need to call a malloc-like function; so let's use \
617 one which we know exists. */ \
618 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
619 (new_size); \
620 if (new_size <= 0) { \
621 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
622 MALLOC_TRACE(" = 0\n"); \
623 return NULL; \
624 } \
625 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
626 MALLOC_TRACE(" = %p\n", v ); \
627 return v; \
628 }
629
630 #if defined(VGO_linux)
631 REALLOC(VG_Z_LIBC_SONAME, realloc);
632
633 #elif defined(VGO_darwin)
634 REALLOC(VG_Z_LIBC_SONAME, realloc);
635 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
636
637 #endif
638
639
640 /*---------------------- memalign ----------------------*/
641
642 #define ZONEMEMALIGN(soname, fnname) \
643 \
644 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
645 ( void *zone, SizeT alignment, SizeT n ); \
646 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
647 ( void *zone, SizeT alignment, SizeT n ) \
648 { \
649 void* v; \
650 \
651 if (!init_done) init(); \
652 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
653 zone, (ULong)alignment, (ULong)n ); \
654 \
655 /* Round up to minimum alignment if necessary. */ \
656 if (alignment < VG_MIN_MALLOC_SZB) \
657 alignment = VG_MIN_MALLOC_SZB; \
658 \
659 /* Round up to nearest power-of-two if necessary (like glibc). */ \
660 while (0 != (alignment & (alignment - 1))) alignment++; \
661 \
662 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
663 MALLOC_TRACE(" = %p\n", v ); \
664 return v; \
665 }
666
667 #define MEMALIGN(soname, fnname) \
668 \
669 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
670 ( SizeT alignment, SizeT n ); \
671 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
672 ( SizeT alignment, SizeT n ) \
673 { \
674 void* v; \
675 \
676 if (!init_done) init(); \
677 MALLOC_TRACE("memalign(al %llu, size %llu)", \
678 (ULong)alignment, (ULong)n ); \
679 \
680 /* Round up to minimum alignment if necessary. */ \
681 if (alignment < VG_MIN_MALLOC_SZB) \
682 alignment = VG_MIN_MALLOC_SZB; \
683 \
684 /* Round up to nearest power-of-two if necessary (like glibc). */ \
685 while (0 != (alignment & (alignment - 1))) alignment++; \
686 \
687 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
688 MALLOC_TRACE(" = %p\n", v ); \
689 return v; \
690 }
691
692 #if defined(VGO_linux)
693 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
694
695 #elif defined(VGO_darwin)
696 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
697 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
698
699 #endif
700
701
702 /*---------------------- valloc ----------------------*/
703
704 #define VALLOC(soname, fnname) \
705 \
706 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
707 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
708 { \
709 static int pszB = 0; \
710 if (pszB == 0) \
711 pszB = my_getpagesize(); \
712 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
713 ((SizeT)pszB, size); \
714 }
715
716 #define ZONEVALLOC(soname, fnname) \
717 \
718 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
719 ( void *zone, SizeT size ); \
720 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
721 ( void *zone, SizeT size ) \
722 { \
723 static int pszB = 0; \
724 if (pszB == 0) \
725 pszB = my_getpagesize(); \
726 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
727 ((SizeT)pszB, size); \
728 }
729
730 #if defined(VGO_linux)
731 VALLOC(VG_Z_LIBC_SONAME, valloc);
732
733 #elif defined(VGO_darwin)
734 VALLOC(VG_Z_LIBC_SONAME, valloc);
735 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
736
737 #endif
738
739
740 /*---------------------- mallopt ----------------------*/
741
742 /* Various compatibility wrapper functions, for glibc and libstdc++. */
743
744 #define MALLOPT(soname, fnname) \
745 \
746 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
747 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
748 { \
749 /* In glibc-2.2.4, 1 denotes a successful return value for \
750 mallopt */ \
751 return 1; \
752 }
753
754 #if defined(VGO_linux)
755 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
756
757 #elif defined(VGO_darwin)
758 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
759
760 #endif
761
762
763 /*---------------------- malloc_trim ----------------------*/
764 // Documentation says:
765 // malloc_trim(size_t pad);
766 //
767 // If possible, gives memory back to the system (via negative arguments to
768 // sbrk) if there is unused memory at the `high' end of the malloc pool.
769 // You can call this after freeing large blocks of memory to potentially
770 // reduce the system-level memory requirements of a program. However, it
771 // cannot guarantee to reduce memory. Under some allocation patterns,
772 // some large free blocks of memory will be locked between two used
773 // chunks, so they cannot be given back to the system.
774 //
775 // The `pad' argument to malloc_trim represents the amount of free
776 // trailing space to leave untrimmed. If this argument is zero, only the
777 // minimum amount of memory to maintain internal data structures will be
778 // left (one page or less). Non-zero arguments can be supplied to maintain
779 // enough trailing space to service future expected allocations without
780 // having to re-obtain memory from the system.
781 //
782 // Malloc_trim returns 1 if it actually released any memory, else 0. On
783 // systems that do not support "negative sbrks", it will always return 0.
784 //
785 // For simplicity, we always return 0.
786 #define MALLOC_TRIM(soname, fnname) \
787 \
788 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
789 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
790 { \
791 /* 0 denotes that malloc_trim() either wasn't able \
792 to do anything, or was not implemented */ \
793 return 0; \
794 }
795
796 #if defined(VGO_linux)
797 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
798
799 #elif defined(VGO_darwin)
800 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
801
802 #endif
803
804
805 /*---------------------- posix_memalign ----------------------*/
806
807 #define POSIX_MEMALIGN(soname, fnname) \
808 \
809 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
810 ( void **memptr, SizeT alignment, SizeT size ); \
811 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
812 ( void **memptr, SizeT alignment, SizeT size ) \
813 { \
814 void *mem; \
815 \
816 /* Test whether the alignment argument is valid. It must be \
817 a power of two multiple of sizeof (void *). */ \
818 if (alignment % sizeof (void *) != 0 \
819 || (alignment & (alignment - 1)) != 0) \
820 return VKI_EINVAL; \
821 \
822 /* Round up to minimum alignment if necessary. */ \
823 if (alignment < VG_MIN_MALLOC_SZB) \
824 alignment = VG_MIN_MALLOC_SZB; \
825 \
826 mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size); \
827 \
828 if (mem != NULL) { \
829 *memptr = mem; \
830 return 0; \
831 } \
832 \
833 return VKI_ENOMEM; \
834 }
835
836 #if defined(VGO_linux)
837 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
838
839 #elif defined(VGO_darwin)
840 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
841
842 #endif
843
844
845 /*---------------------- malloc_usable_size ----------------------*/
846
847 #define MALLOC_USABLE_SIZE(soname, fnname) \
848 \
849 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
850 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
851 { \
852 SizeT pszB; \
853 \
854 if (!init_done) init(); \
855 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
856 if (NULL == p) \
857 return 0; \
858 \
859 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
860 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
861 \
862 return pszB; \
863 }
864
865 #if defined(VGO_linux)
866 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
867 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
868
869 #elif defined(VGO_darwin)
870 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
871 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
872
873 #endif
874
875
876 /*---------------------- (unimplemented) ----------------------*/
877
878 /* Bomb out if we get any of these. */
879
panic(const char * str)880 static void panic(const char *str)
881 {
882 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
883 my_exit(99);
884 *(volatile int *)0 = 'x';
885 }
886
887 #define PANIC(soname, fnname) \
888 \
889 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
890 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
891 { \
892 panic(#fnname); \
893 }
894
895 #if defined(VGO_linux)
896 PANIC(VG_Z_LIBC_SONAME, pvalloc);
897 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
898 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
899
900 #elif defined(VGO_darwin)
901 PANIC(VG_Z_LIBC_SONAME, pvalloc);
902 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
903 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
904
905 #endif
906
907
908 #define MALLOC_STATS(soname, fnname) \
909 \
910 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
911 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
912 { \
913 /* Valgrind's malloc_stats implementation does nothing. */ \
914 }
915
916 #if defined(VGO_linux)
917 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
918
919 #elif defined(VGO_darwin)
920 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
921
922 #endif
923
924
925 /*---------------------- mallinfo ----------------------*/
926
927 // mi must be static; if it is auto then Memcheck thinks it is
928 // uninitialised when used by the caller of this function, because Memcheck
929 // doesn't know that the call to mallinfo fills in mi.
930 #define MALLINFO(soname, fnname) \
931 \
932 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
933 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
934 { \
935 static struct vg_mallinfo mi; \
936 if (!init_done) init(); \
937 MALLOC_TRACE("mallinfo()\n"); \
938 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
939 return mi; \
940 }
941
942 #if defined(VGO_linux)
943 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
944
945 #elif defined(VGO_darwin)
946 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
947
948 #endif
949
950
951 /*------------------ Darwin zone stuff ------------------*/
952
953
954 #if defined(VGO_darwin)
955
956 static vki_malloc_zone_t vg_default_zone = {
957 NULL, // reserved1
958 NULL, // reserved2
959 NULL, // GrP fixme: malloc_size
960 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
961 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
962 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
963 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
964 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
965 NULL, // GrP fixme: destroy
966 "ValgrindMallocZone",
967 NULL, // batch_malloc
968 NULL, // batch_free
969 NULL, // GrP fixme: introspect
970 2, // version (GrP fixme 3?)
971 NULL, /* memalign */ // DDD: this field exists in Mac OS 10.6, but not 10.5.
972 NULL, /* free_definite_size */
973 NULL, /* pressure_relief */
974 };
975
976 #define DEFAULT_ZONE(soname, fnname) \
977 \
978 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
979 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
980 { \
981 return &vg_default_zone; \
982 }
983
984 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
985
986 #define ZONE_FROM_PTR(soname, fnname) \
987 \
988 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \
989 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ) \
990 { \
991 return &vg_default_zone; \
992 }
993
994 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
995
996
997 // GrP fixme bypass libc's use of zone->introspect->check
998 #define ZONE_CHECK(soname, fnname) \
999 \
1000 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \
1001 int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone) \
1002 { \
1003 return 1; \
1004 }
1005
1006 //ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1007
1008 #endif /* defined(VGO_darwin) */
1009
1010 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start);
I_WRAP_SONAME_FNNAME_ZZ(NONE,NaClSandboxMemoryStartForValgrind)1011 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start) {
1012 OrigFn fn;
1013 VALGRIND_GET_ORIG_FN(fn);
1014 CALL_FN_v_W(fn, mem_start);
1015 int res;
1016 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MEM_START, mem_start, 0, 0, 0, 0);
1017 }
1018
1019 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file);
I_WRAP_SONAME_FNNAME_ZZ(NONE,NaClFileNameForValgrind)1020 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file) {
1021 OrigFn fn;
1022 int ret;
1023 VALGRIND_GET_ORIG_FN(fn);
1024 CALL_FN_W_W(ret, fn, file);
1025 int res;
1026 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_FILE, file, 0, 0, 0, 0);
1027 return ret;
1028 }
1029
1030 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset);
I_WRAP_SONAME_FNNAME_ZZ(NONE,NaClFileMappingForValgrind)1031 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset) {
1032 OrigFn fn;
1033 VALGRIND_GET_ORIG_FN(fn);
1034 CALL_FN_v_WWW(fn, vma, size, file_offset);
1035 int res;
1036 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MMAP, vma, size, file_offset, 0, 0);
1037 }
1038
1039 /* Handle tcmalloc (http://code.google.com/p/google-perftools/) */
1040
1041 /* tc_ functions (used when tcmalloc is running in release mode) */
1042 ALLOC_or_NULL(NONE,tc_malloc,malloc);
1043 ALLOC_or_BOMB(NONE,tc_new,__builtin_new);
1044 ALLOC_or_NULL(NONE,tc_new_nothrow,__builtin_new);
1045 ALLOC_or_BOMB(NONE,tc_newarray,__builtin_vec_new);
1046 ALLOC_or_NULL(NONE,tc_newarray_nothrow,__builtin_vec_new);
1047 FREE(NONE,tc_free,free);
1048 FREE(NONE,tc_cfree,free);
1049 FREE(NONE,tc_delete,__builtin_delete);
1050 FREE(NONE,tc_delete_nothrow,__builtin_delete);
1051 FREE(NONE,tc_deletearray,__builtin_vec_delete);
1052 FREE(NONE,tc_deletearray_nothrow,__builtin_vec_delete);
1053 CALLOC(NONE,tc_calloc);
1054 REALLOC(NONE,tc_realloc);
1055 VALLOC(NONE,tc_valloc);
1056 MEMALIGN(NONE,tc_memalign);
1057 MALLOPT(NONE,tc_mallopt);
1058 POSIX_MEMALIGN(NONE,tc_posix_memalign);
1059 MALLOC_USABLE_SIZE(NONE,tc_malloc_size);
1060 MALLINFO(NONE,tc_mallinfo);
1061
1062 /* Python */
1063 ALLOC_or_NULL(NONE, PyObject_Malloc, malloc);
1064 FREE(NONE, PyObject_Free, free);
1065 REALLOC(NONE, PyObject_Realloc);
1066
1067 /* Interceptors for custom malloc functions in user code
1068 (NONE, malloc). We need these to intercept tcmalloc in debug builds.
1069 TODO(kcc): get rid of these once we have tc_malloc/tc_new/etc
1070 in tcmalloc's debugallocation.cc
1071 */
1072 ALLOC_or_NULL(NONE, malloc, malloc);
1073 ALLOC_or_BOMB(NONE, _Znwj, __builtin_new);
1074 ALLOC_or_BOMB(NONE, _Znwm, __builtin_new);
1075 ALLOC_or_NULL(NONE, _ZnwjRKSt9nothrow_t, __builtin_new);
1076 ALLOC_or_NULL(NONE, _ZnwmRKSt9nothrow_t, __builtin_new);
1077 ALLOC_or_BOMB(NONE, _Znaj, __builtin_vec_new);
1078 ALLOC_or_BOMB(NONE, _Znam, __builtin_vec_new);
1079 ALLOC_or_NULL(NONE, _ZnajRKSt9nothrow_t, __builtin_vec_new);
1080 ALLOC_or_NULL(NONE, _ZnamRKSt9nothrow_t, __builtin_vec_new);
1081 FREE(NONE, free, free );
1082 FREE(NONE, cfree, free );
1083 FREE(NONE, _ZdlPv, __builtin_delete );
1084 FREE(NONE, _ZdlPvRKSt9nothrow_t, __builtin_delete );
1085 FREE(NONE, _ZdaPv, __builtin_vec_delete );
1086 FREE(NONE, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
1087 CALLOC(NONE, calloc);
1088 REALLOC(NONE, realloc);
1089 MEMALIGN(NONE, memalign);
1090 VALLOC(NONE, valloc);
1091 MALLOPT(NONE, mallopt);
1092 MALLOC_TRIM(NONE, malloc_trim);
1093 POSIX_MEMALIGN(NONE, posix_memalign);
1094 MALLOC_USABLE_SIZE(NONE, malloc_usable_size);
1095 MALLINFO(NONE, mallinfo);
1096
1097 // TODO(kcc): these are interceptors for bash's malloc.
1098 // The bash interpretor has functions malloc() and sh_malloc()
1099 // as well as free() and sh_free(). And sometimes they are called
1100 // inconsistently (malloc, then sh_free).
1101 // So, if we intercept malloc/free, we also need to intercept
1102 // sh_malloc/sh_free.
1103 //
1104 // Standard valgrind does not intercept user's malloc, so it does not have this
1105 // problem.
1106 //
1107 // Get rid of these once we are able to intercept tcmalloc
1108 // w/o intercepting (NONE,malloc)
1109 ALLOC_or_NULL(NONE, sh_malloc, malloc);
1110 FREE(NONE, sh_free, free );
1111 FREE(NONE, sh_cfree, free );
1112 CALLOC(NONE, sh_calloc);
1113 REALLOC(NONE, sh_realloc);
1114 MEMALIGN(NONE, sh_memalign);
1115 VALLOC(NONE, sh_valloc);
1116
1117 /*------- alternative to RUNNING_ON_VALGRIND client request -----*/
1118
1119 #define ANN_FUNC0(ret_ty, f) \
1120 ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void); \
1121 ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void)
1122
ANN_FUNC0(int,RunningOnValgrind)1123 ANN_FUNC0(int, RunningOnValgrind) { return 1; }
1124
1125 /*------------------ (startup related) ------------------*/
1126
1127 /* All the code in here is unused until this function is called */
1128
1129 __attribute__((constructor))
init(void)1130 static void init(void)
1131 {
1132
1133 // This doesn't look thread-safe, but it should be ok... Bart says:
1134 //
1135 // Every program I know of calls malloc() at least once before calling
1136 // pthread_create(). So init_done gets initialized before any thread is
1137 // created, and is only read when multiple threads are active
1138 // simultaneously. Such an access pattern is safe.
1139 //
1140 // If the assignment to the variable init_done would be triggering a race
1141 // condition, both DRD and Helgrind would report this race.
1142 //
1143 // By the way, although the init() function in
1144 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1145 // __attribute__((constructor)), it is not safe to remove the variable
1146 // init_done. This is because it is possible that malloc() and hence
1147 // init() gets called before shared library initialization finished.
1148 //
1149 if (init_done)
1150 return;
1151
1152 init_done = 1;
1153
1154 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1155 0, 0, 0, 0);
1156 }
1157
1158 /*--------------------------------------------------------------------*/
1159 /*--- end ---*/
1160 /*--------------------------------------------------------------------*/
1161