• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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