• 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-2013 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) || defined(VGPV_mips32_linux_android)
120    __asm__ __volatile__(".word 0xFFFFFFFF");
121    while (1) {}
122 #  elif defined(VGPV_x86_linux_android)
123    __asm__ __volatile__("ud2");
124    while (1) {}
125 #  else
126    extern __attribute__ ((__noreturn__)) void _exit(int status);
127    _exit(x);
128 #  endif
129 }
130 
131 /* Same problem with getpagesize. */
my_getpagesize(void)132 static inline int my_getpagesize ( void )
133 {
134 #  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
135       || defined(VGPV_mips32_linux_android)
136    return 4096; /* kludge - link failure on Android, for some reason */
137 #  else
138    extern int getpagesize (void);
139    return getpagesize();
140 #  endif
141 }
142 
143 
144 /* Compute the high word of the double-length unsigned product of U
145    and V.  This is for calloc argument overflow checking; see comments
146    below.  Algorithm as described in Hacker's Delight, chapter 8. */
umulHW(UWord u,UWord v)147 static UWord umulHW ( UWord u, UWord v )
148 {
149    UWord u0, v0, w0, rHi;
150    UWord u1, v1, w1,w2,t;
151    UWord halfMask  = sizeof(UWord)==4 ? (UWord)0xFFFF
152                                       : (UWord)0xFFFFFFFFULL;
153    UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
154    u0  = u & halfMask;
155    u1  = u >> halfShift;
156    v0  = v & halfMask;
157    v1  = v >> halfShift;
158    w0  = u0 * v0;
159    t   = u1 * v0 + (w0 >> halfShift);
160    w1  = t & halfMask;
161    w2  = t >> halfShift;
162    w1  = u0 * v1 + w1;
163    rHi = u1 * v1 + w2 + (w1 >> halfShift);
164    return rHi;
165 }
166 
167 
168 /*------------------------------------------------------------*/
169 /*--- Replacing malloc() et al                             ---*/
170 /*------------------------------------------------------------*/
171 
172 /* This struct is initially empty.  Before the first use of any of
173    these functions, we make a client request which fills in the
174    fields.
175 */
176 static struct vg_mallocfunc_info info;
177 static int init_done;
178 #define DO_INIT if (UNLIKELY(!init_done)) init()
179 
180 /* Startup hook - called as init section */
181 __attribute__((constructor))
182 static void init(void);
183 
184 #define MALLOC_TRACE(format, args...)  \
185    if (info.clo_trace_malloc) {        \
186       VALGRIND_INTERNAL_PRINTF(format, ## args ); }
187 
188 /* Below are new versions of malloc, __builtin_new, free,
189    __builtin_delete, calloc, realloc, memalign, and friends.
190 
191    None of these functions are called directly - they are not meant to
192    be found by the dynamic linker.  But ALL client calls to malloc()
193    and friends wind up here eventually.  They get called because
194    vg_replace_malloc installs a bunch of code redirects which causes
195    Valgrind to use these functions rather than the ones they're
196    replacing.
197 */
198 
199 /* The replacement functions are running on the simulated CPU.
200    The code on the simulated CPU does not necessarily use
201    all arguments. E.g. args can be ignored and/or only given
202    to a NON SIMD call.
203    The definedness of such 'unused' arguments will not be verified
204    by memcheck.
205    A call to 'trigger_memcheck_error_if_undefined' allows
206    memcheck to detect such errors for the otherwise unused args.
207    Apart of allowing memcheck to detect an error, the function
208    trigger_memcheck_error_if_undefined has no effect and
209    has a minimal cost for other tools replacing malloc functions.
210 */
trigger_memcheck_error_if_undefined(ULong x)211 static inline void trigger_memcheck_error_if_undefined ( ULong x )
212 {
213    if (x == 0) __asm__ __volatile__( "" ::: "memory" );
214 }
215 
216 /*---------------------- malloc ----------------------*/
217 
218 /* Generate a replacement for 'fnname' in object 'soname', which calls
219    'vg_replacement' to allocate memory.  If that fails, return NULL.
220 */
221 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
222    \
223    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
224    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n)  \
225    { \
226       void* v; \
227       \
228       DO_INIT; \
229       trigger_memcheck_error_if_undefined((ULong)n ); \
230       MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
231       \
232       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
233       MALLOC_TRACE(" = %p\n", v ); \
234       return v; \
235    }
236 
237 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
238    \
239    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
240    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n)  \
241    { \
242       void* v; \
243       \
244       DO_INIT; \
245       trigger_memcheck_error_if_undefined((ULong)(UWord) zone);	\
246       trigger_memcheck_error_if_undefined((ULong) n); \
247       MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
248       \
249       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
250       MALLOC_TRACE(" = %p\n", v ); \
251       return v; \
252    }
253 
254 
255 /* Generate a replacement for 'fnname' in object 'soname', which calls
256    'vg_replacement' to allocate memory.  If that fails, it bombs the
257    system.
258 */
259 #define ALLOC_or_BOMB(soname, fnname, vg_replacement)  \
260    \
261    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
262    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n)  \
263    { \
264       void* v; \
265       \
266       DO_INIT; \
267       trigger_memcheck_error_if_undefined((ULong) n); \
268       MALLOC_TRACE(#fnname "(%llu)", (ULong)n );        \
269       \
270       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
271       MALLOC_TRACE(" = %p\n", v ); \
272       if (NULL == v) { \
273          VALGRIND_PRINTF( \
274             "new/new[] failed and should throw an exception, but Valgrind\n"); \
275          VALGRIND_PRINTF_BACKTRACE( \
276             "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
277             my_exit(1); \
278       } \
279       return v; \
280    }
281 
282 // Each of these lines generates a replacement function:
283 //     (from_so, from_fn,  v's replacement)
284 // For some lines, we will also define a replacement function
285 // whose only purpose is to be a soname synonym place holder
286 // that can be replaced using --soname-synonyms.
287 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
288 
289 // malloc
290 #if defined(VGO_linux)
291  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
292  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
293  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
294 
295 #elif defined(VGO_darwin)
296  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
297  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
298  ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME,  malloc_zone_malloc, malloc);
299  ZONEALLOC_or_NULL(SO_SYN_MALLOC,     malloc_zone_malloc, malloc);
300 
301 #endif
302 
303 
304 /*---------------------- new ----------------------*/
305 
306 #if defined(VGO_linux)
307  // operator new(unsigned int), not mangled (for gcc 2.96)
308  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
309  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
310  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
311  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
312  // operator new(unsigned int), GNU mangling
313  #if VG_WORDSIZE == 4
314   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
315   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
316   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
317  #endif
318  // operator new(unsigned long), GNU mangling
319  #if VG_WORDSIZE == 8
320   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
321   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
322   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
323  #endif
324 
325 #elif defined(VGO_darwin)
326  // operator new(unsigned int), GNU mangling
327  #if VG_WORDSIZE == 4
328   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
329   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
330  #endif
331  // operator new(unsigned long), GNU mangling
332  #if 1 // FIXME: is this right?
333   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
334   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
335  #endif
336 
337 #endif
338 
339 
340 /*---------------------- new nothrow ----------------------*/
341 
342 #if defined(VGO_linux)
343  // operator new(unsigned, std::nothrow_t const&), GNU mangling
344  #if VG_WORDSIZE == 4
345   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
346   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
347   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
348  #endif
349  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
350  #if VG_WORDSIZE == 8
351   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
352   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
353   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
354  #endif
355 
356 #elif defined(VGO_darwin)
357  // operator new(unsigned, std::nothrow_t const&), GNU mangling
358  #if VG_WORDSIZE == 4
359   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
360   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
361  #endif
362  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
363  #if 1 // FIXME: is this right?
364   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
365   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
366  #endif
367 
368 #endif
369 
370 
371 /*---------------------- new [] ----------------------*/
372 
373 #if defined(VGO_linux)
374  // operator new[](unsigned int), not mangled (for gcc 2.96)
375  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
376  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
377  // operator new[](unsigned int), GNU mangling
378  #if VG_WORDSIZE == 4
379   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
380   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
381   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
382  #endif
383  // operator new[](unsigned long), GNU mangling
384  #if VG_WORDSIZE == 8
385   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
386   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
387   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
388  #endif
389 
390 #elif defined(VGO_darwin)
391  // operator new[](unsigned int), GNU mangling
392  #if VG_WORDSIZE == 4
393   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
394   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
395  #endif
396  // operator new[](unsigned long), GNU mangling
397  #if 1 // FIXME: is this right?
398   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
399   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
400  #endif
401 
402 #endif
403 
404 
405 /*---------------------- new [] nothrow ----------------------*/
406 
407 #if defined(VGO_linux)
408  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
409  #if VG_WORDSIZE == 4
410   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
411   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
412   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
413  #endif
414  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
415  #if VG_WORDSIZE == 8
416   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
417   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
418   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
419  #endif
420 
421 #elif defined(VGO_darwin)
422  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
423  #if VG_WORDSIZE == 4
424   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
425   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
426  #endif
427  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
428  #if 1 // FIXME: is this right?
429   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
430   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
431  #endif
432 
433 #endif
434 
435 
436 /*---------------------- free ----------------------*/
437 
438 /* Generate a replacement for 'fnname' in object 'soname', which calls
439    'vg_replacement' to free previously allocated memory.
440 */
441 #define ZONEFREE(soname, fnname, vg_replacement) \
442    \
443    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
444    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p)  \
445    { \
446       DO_INIT; \
447       trigger_memcheck_error_if_undefined((ULong)(UWord) zone);	\
448       MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
449       if (p == NULL)  \
450          return; \
451       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
452    }
453 
454 #define FREE(soname, fnname, vg_replacement) \
455    \
456    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
457    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p)  \
458    { \
459       DO_INIT; \
460       MALLOC_TRACE(#fnname "(%p)\n", p ); \
461       if (p == NULL)  \
462          return; \
463       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
464    }
465 
466 
467 #if defined(VGO_linux)
468  FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
469  FREE(VG_Z_LIBC_SONAME,       free,                 free );
470  FREE(SO_SYN_MALLOC,          free,                 free );
471 
472 #elif defined(VGO_darwin)
473  FREE(VG_Z_LIBC_SONAME,       free,                 free );
474  FREE(SO_SYN_MALLOC,          free,                 free );
475  ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
476  ZONEFREE(SO_SYN_MALLOC,      malloc_zone_free,     free );
477 
478 #endif
479 
480 
481 /*---------------------- cfree ----------------------*/
482 
483 // cfree
484 #if defined(VGO_linux)
485  FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
486  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
487  FREE(SO_SYN_MALLOC,          cfree,                free );
488 
489 #elif defined(VGO_darwin)
490  //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
491  //FREE(VG_Z_LIBC_SONAME,       cfree,                free );
492 
493 #endif
494 
495 
496 /*---------------------- delete ----------------------*/
497 
498 #if defined(VGO_linux)
499  // operator delete(void*), not mangled (for gcc 2.96)
500  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
501  FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
502  // operator delete(void*), GNU mangling
503  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
504  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
505  FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
506 
507 #elif defined(VGO_darwin)
508  // operator delete(void*), GNU mangling
509  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
510  //FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
511 
512 #endif
513 
514 
515 /*---------------------- delete nothrow ----------------------*/
516 
517 #if defined(VGO_linux)
518  // operator delete(void*, std::nothrow_t const&), GNU mangling
519  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
520  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
521  FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
522 
523 #elif defined(VGO_darwin)
524  // operator delete(void*, std::nothrow_t const&), GNU mangling
525  //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
526  //FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
527 
528 #endif
529 
530 
531 /*---------------------- delete [] ----------------------*/
532 
533 #if defined(VGO_linux)
534  // operator delete[](void*), not mangled (for gcc 2.96)
535  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
536  FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
537  // operator delete[](void*), GNU mangling
538  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
539  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
540  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
541 
542 #elif defined(VGO_darwin)
543  // operator delete[](void*), not mangled (for gcc 2.96)
544  //FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
545  //FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
546  // operator delete[](void*), GNU mangling
547  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
548  //FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
549 
550 #endif
551 
552 
553 /*---------------------- delete [] nothrow ----------------------*/
554 
555 #if defined(VGO_linux)
556  // operator delete[](void*, std::nothrow_t const&), GNU mangling
557  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
558  FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
559  FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
560 
561 #elif defined(VGO_darwin)
562  // operator delete[](void*, std::nothrow_t const&), GNU mangling
563  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
564  //FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
565 
566 #endif
567 
568 
569 /*---------------------- calloc ----------------------*/
570 
571 #define ZONECALLOC(soname, fnname) \
572    \
573    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
574             ( void *zone, SizeT nmemb, SizeT size ); \
575    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
576             ( void *zone, SizeT nmemb, SizeT size )  \
577    { \
578       void* v; \
579       \
580       DO_INIT; \
581       trigger_memcheck_error_if_undefined((ULong)(UWord) zone); \
582       trigger_memcheck_error_if_undefined((ULong) nmemb); \
583       trigger_memcheck_error_if_undefined((ULong) size); \
584       MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
585       \
586       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
587       MALLOC_TRACE(" = %p\n", v ); \
588       return v; \
589    }
590 
591 #define CALLOC(soname, fnname) \
592    \
593    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
594             ( SizeT nmemb, SizeT size ); \
595    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
596             ( SizeT nmemb, SizeT size )  \
597    { \
598       void* v; \
599       \
600       DO_INIT; \
601       MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
602       \
603       /* Protect against overflow.  See bug 24078. (that bug number is
604          invalid.  Which one really?) */ \
605       /* But don't use division, since that produces an external symbol
606          reference on ARM, in the form of a call to __aeabi_uidiv.  It's
607          normally OK, because ld.so manages to resolve it to something in the
608          executable, or one of its shared objects.  But that isn't guaranteed
609          to be the case, and it has been observed to fail in rare cases, eg:
610             echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
611          So instead compute the high word of the product and check it is zero. */ \
612       if (umulHW(size, nmemb) != 0) return NULL; \
613       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
614       MALLOC_TRACE(" = %p\n", v ); \
615       return v; \
616    }
617 
618 #if defined(VGO_linux)
619  CALLOC(VG_Z_LIBC_SONAME, calloc);
620  CALLOC(SO_SYN_MALLOC,    calloc);
621 
622 #elif defined(VGO_darwin)
623  CALLOC(VG_Z_LIBC_SONAME, calloc);
624  CALLOC(SO_SYN_MALLOC,    calloc);
625  ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
626  ZONECALLOC(SO_SYN_MALLOC,    malloc_zone_calloc);
627 
628 #endif
629 
630 
631 /*---------------------- realloc ----------------------*/
632 
633 #define ZONEREALLOC(soname, fnname) \
634    \
635    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
636             ( void *zone, void* ptrV, SizeT new_size ); \
637    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
638             ( void *zone, void* ptrV, SizeT new_size ) \
639    { \
640       void* v; \
641       \
642       DO_INIT; \
643       MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
644       \
645       if (ptrV == NULL) \
646          /* We need to call a malloc-like function; so let's use \
647             one which we know exists. GrP fixme use zonemalloc instead? */ \
648          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
649                    (new_size); \
650       if (new_size <= 0) { \
651          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
652          MALLOC_TRACE(" = 0\n"); \
653          return NULL; \
654       } \
655       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
656       MALLOC_TRACE(" = %p\n", v ); \
657       return v; \
658    }
659 
660 #define REALLOC(soname, fnname) \
661    \
662    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
663             ( void* ptrV, SizeT new_size );\
664    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
665             ( void* ptrV, SizeT new_size ) \
666    { \
667       void* v; \
668       \
669       DO_INIT; \
670       MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
671       \
672       if (ptrV == NULL) \
673          /* We need to call a malloc-like function; so let's use \
674             one which we know exists. */ \
675          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
676                    (new_size); \
677       if (new_size <= 0) { \
678          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
679          MALLOC_TRACE(" = 0\n"); \
680          return NULL; \
681       } \
682       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
683       MALLOC_TRACE(" = %p\n", v ); \
684       return v; \
685    }
686 
687 #if defined(VGO_linux)
688  REALLOC(VG_Z_LIBC_SONAME, realloc);
689  REALLOC(SO_SYN_MALLOC,    realloc);
690 
691 #elif defined(VGO_darwin)
692  REALLOC(VG_Z_LIBC_SONAME, realloc);
693  REALLOC(SO_SYN_MALLOC,    realloc);
694  ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
695  ZONEREALLOC(SO_SYN_MALLOC,    malloc_zone_realloc);
696 
697 #endif
698 
699 
700 /*---------------------- memalign ----------------------*/
701 
702 #define ZONEMEMALIGN(soname, fnname) \
703    \
704    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
705             ( void *zone, SizeT alignment, SizeT n ); \
706    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
707             ( void *zone, SizeT alignment, SizeT n ) \
708    { \
709       void* v; \
710       \
711       DO_INIT; \
712       trigger_memcheck_error_if_undefined((ULong)(UWord) zone);	\
713       trigger_memcheck_error_if_undefined((ULong) n); \
714       MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
715                    zone, (ULong)alignment, (ULong)n );  \
716       \
717       /* Round up to minimum alignment if necessary. */ \
718       if (alignment < VG_MIN_MALLOC_SZB) \
719          alignment = VG_MIN_MALLOC_SZB; \
720       \
721       /* Round up to nearest power-of-two if necessary (like glibc). */ \
722       while (0 != (alignment & (alignment - 1))) alignment++; \
723       \
724       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
725       MALLOC_TRACE(" = %p\n", v ); \
726       return v; \
727    }
728 
729 #define MEMALIGN(soname, fnname) \
730    \
731    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
732             ( SizeT alignment, SizeT n ); \
733    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
734             ( SizeT alignment, SizeT n )  \
735    { \
736       void* v; \
737       \
738       DO_INIT; \
739       trigger_memcheck_error_if_undefined((ULong) n); \
740       MALLOC_TRACE("memalign(al %llu, size %llu)", \
741                    (ULong)alignment, (ULong)n ); \
742       \
743       /* Round up to minimum alignment if necessary. */ \
744       if (alignment < VG_MIN_MALLOC_SZB) \
745          alignment = VG_MIN_MALLOC_SZB; \
746       \
747       /* Round up to nearest power-of-two if necessary (like glibc). */ \
748       while (0 != (alignment & (alignment - 1))) alignment++; \
749       \
750       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
751       MALLOC_TRACE(" = %p\n", v ); \
752       return v; \
753    }
754 
755 #if defined(VGO_linux)
756  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
757  MEMALIGN(SO_SYN_MALLOC,    memalign);
758 
759 #elif defined(VGO_darwin)
760  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
761  MEMALIGN(SO_SYN_MALLOC,    memalign);
762  ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
763  ZONEMEMALIGN(SO_SYN_MALLOC,    malloc_zone_memalign);
764 
765 #endif
766 
767 
768 /*---------------------- valloc ----------------------*/
769 
770 #define VALLOC(soname, fnname) \
771    \
772    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
773    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
774    { \
775       static int pszB = 0; \
776       if (pszB == 0) \
777          pszB = my_getpagesize(); \
778       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
779                 ((SizeT)pszB, size); \
780    }
781 
782 #define ZONEVALLOC(soname, fnname) \
783    \
784    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
785             ( void *zone, SizeT size ); \
786    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
787             ( void *zone, SizeT size )  \
788    { \
789       static int pszB = 0; \
790       if (pszB == 0) \
791          pszB = my_getpagesize(); \
792       trigger_memcheck_error_if_undefined((ULong)(UWord) zone);	      \
793       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
794                 ((SizeT)pszB, size); \
795    }
796 
797 #if defined(VGO_linux)
798  VALLOC(VG_Z_LIBC_SONAME, valloc);
799  VALLOC(SO_SYN_MALLOC, valloc);
800 
801 #elif defined(VGO_darwin)
802  VALLOC(VG_Z_LIBC_SONAME, valloc);
803  VALLOC(SO_SYN_MALLOC, valloc);
804  ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
805  ZONEVALLOC(SO_SYN_MALLOC,    malloc_zone_valloc);
806 
807 #endif
808 
809 
810 /*---------------------- mallopt ----------------------*/
811 
812 /* Various compatibility wrapper functions, for glibc and libstdc++. */
813 
814 #define MALLOPT(soname, fnname) \
815    \
816    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
817    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
818    { \
819       /* In glibc-2.2.4, 1 denotes a successful return value for \
820          mallopt */ \
821       trigger_memcheck_error_if_undefined((ULong) cmd); \
822       trigger_memcheck_error_if_undefined((ULong) value); \
823       return 1; \
824    }
825 
826 #if defined(VGO_linux)
827  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
828  MALLOPT(SO_SYN_MALLOC,    mallopt);
829 
830 #elif defined(VGO_darwin)
831  //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
832 
833 #endif
834 
835 
836 /*---------------------- malloc_trim ----------------------*/
837 // Documentation says:
838 //   malloc_trim(size_t pad);
839 //
840 //   If possible, gives memory back to the system (via negative arguments to
841 //   sbrk) if there is unused memory at the `high' end of the malloc pool.
842 //   You can call this after freeing large blocks of memory to potentially
843 //   reduce the system-level memory requirements of a program. However, it
844 //   cannot guarantee to reduce memory.  Under some allocation patterns,
845 //   some large free blocks of memory will be locked between two used
846 //   chunks, so they cannot be given back to the system.
847 //
848 //   The `pad' argument to malloc_trim represents the amount of free
849 //   trailing space to leave untrimmed. If this argument is zero, only the
850 //   minimum amount of memory to maintain internal data structures will be
851 //   left (one page or less). Non-zero arguments can be supplied to maintain
852 //   enough trailing space to service future expected allocations without
853 //   having to re-obtain memory from the system.
854 //
855 //   Malloc_trim returns 1 if it actually released any memory, else 0. On
856 //   systems that do not support "negative sbrks", it will always return 0.
857 //
858 // For simplicity, we always return 0.
859 #define MALLOC_TRIM(soname, fnname) \
860    \
861    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
862    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
863    { \
864       /* 0 denotes that malloc_trim() either wasn't able \
865          to do anything, or was not implemented */ \
866       trigger_memcheck_error_if_undefined((ULong) pad); \
867       return 0; \
868    }
869 
870 #if defined(VGO_linux)
871  MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
872  MALLOC_TRIM(SO_SYN_MALLOC,    malloc_trim);
873 
874 #elif defined(VGO_darwin)
875  //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
876 
877 #endif
878 
879 
880 /*---------------------- posix_memalign ----------------------*/
881 
882 #define POSIX_MEMALIGN(soname, fnname) \
883    \
884    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
885           ( void **memptr, SizeT alignment, SizeT size ); \
886    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
887           ( void **memptr, SizeT alignment, SizeT size ) \
888    { \
889       void *mem; \
890       \
891       /* Test whether the alignment argument is valid.  It must be \
892          a power of two multiple of sizeof (void *).  */ \
893       if (alignment % sizeof (void *) != 0 \
894           || (alignment & (alignment - 1)) != 0) \
895          return VKI_EINVAL; \
896       \
897       mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
898                (alignment, size); \
899       \
900       if (mem != NULL) { \
901         *memptr = mem; \
902         return 0; \
903       } \
904       \
905       return VKI_ENOMEM; \
906    }
907 
908 #if defined(VGO_linux)
909  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
910  POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
911 
912 #elif defined(VGO_darwin)
913  //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
914 
915 #endif
916 
917 
918 /*---------------------- malloc_usable_size ----------------------*/
919 
920 #define MALLOC_USABLE_SIZE(soname, fnname) \
921    \
922    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
923    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
924    {  \
925       SizeT pszB; \
926       \
927       DO_INIT; \
928       MALLOC_TRACE("malloc_usable_size(%p)", p ); \
929       if (NULL == p) \
930          return 0; \
931       \
932       pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
933       MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
934       \
935       return pszB; \
936    }
937 
938 #if defined(VGO_linux)
939  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
940  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
941  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
942  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
943 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
944      || defined(VGPV_mips32_linux_android)
945   MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
946   MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
947 # endif
948 
949 #elif defined(VGO_darwin)
950  //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
951  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
952  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
953 
954 #endif
955 
956 
957 /*---------------------- (unimplemented) ----------------------*/
958 
959 /* Bomb out if we get any of these. */
960 
panic(const char * str)961 static void panic(const char *str)
962 {
963    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
964    my_exit(99);
965    *(volatile int *)0 = 'x';
966 }
967 
968 #define PANIC(soname, fnname) \
969    \
970    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
971    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void )  \
972    { \
973       panic(#fnname); \
974    }
975 
976 #if defined(VGO_linux)
977  PANIC(VG_Z_LIBC_SONAME, pvalloc);
978  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
979  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
980 
981 #elif defined(VGO_darwin)
982  PANIC(VG_Z_LIBC_SONAME, pvalloc);
983  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
984  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
985 
986 #endif
987 
988 
989 #define MALLOC_STATS(soname, fnname) \
990    \
991    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
992    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void )  \
993    { \
994       /* Valgrind's malloc_stats implementation does nothing. */ \
995    }
996 
997 #if defined(VGO_linux)
998  MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
999  MALLOC_STATS(SO_SYN_MALLOC,    malloc_stats);
1000 
1001 #elif defined(VGO_darwin)
1002  //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1003 
1004 #endif
1005 
1006 
1007 /*---------------------- mallinfo ----------------------*/
1008 
1009 // mi must be static;  if it is auto then Memcheck thinks it is
1010 // uninitialised when used by the caller of this function, because Memcheck
1011 // doesn't know that the call to mallinfo fills in mi.
1012 #define MALLINFO(soname, fnname) \
1013    \
1014    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1015    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
1016    { \
1017       static struct vg_mallinfo mi; \
1018       DO_INIT; \
1019       MALLOC_TRACE("mallinfo()\n"); \
1020       (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1021       return mi; \
1022    }
1023 
1024 #if defined(VGO_linux)
1025  MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1026  MALLINFO(SO_SYN_MALLOC,    mallinfo);
1027 
1028 #elif defined(VGO_darwin)
1029  //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1030 
1031 #endif
1032 
1033 
1034 /*------------------ Darwin zone stuff ------------------*/
1035 
1036 #if defined(VGO_darwin)
1037 
my_malloc_size(void * zone,void * ptr)1038 static size_t my_malloc_size ( void* zone, void* ptr )
1039 {
1040    /* Implement "malloc_size" by handing the request through to the
1041       tool's .tl_usable_size method. */
1042    DO_INIT;
1043    trigger_memcheck_error_if_undefined((ULong)(UWord) zone);
1044    trigger_memcheck_error_if_undefined((ULong)(UWord) ptr);
1045    size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1046                            info.tl_malloc_usable_size, ptr);
1047    return res;
1048 }
1049 
1050 /* Note that the (void*) casts below are a kludge which stops
1051    compilers complaining about the fact that the the replacement
1052    functions aren't really of the right type. */
1053 static vki_malloc_zone_t vg_default_zone = {
1054     NULL, // reserved1
1055     NULL, // reserved2
1056     (void*)my_malloc_size, // JRS fixme: is this right?
1057     (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1058     (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1059     (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1060     (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1061     (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
1062     NULL, // GrP fixme: destroy
1063     "ValgrindMallocZone",
1064     NULL, // batch_malloc
1065     NULL, // batch_free
1066     NULL, // GrP fixme: introspect
1067     2,  // version (GrP fixme 3?)
1068     NULL, /* memalign */   // DDD: this field exists in Mac OS 10.6, but not 10.5.
1069     NULL, /* free_definite_size */
1070     NULL, /* pressure_relief */
1071 };
1072 
1073 
1074 #define DEFAULT_ZONE(soname, fnname) \
1075    \
1076    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1077    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void )  \
1078    { \
1079       return &vg_default_zone; \
1080    }
1081 
1082 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
1083 DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_zone);
1084 
1085 
1086 #define ZONE_FROM_PTR(soname, fnname) \
1087    \
1088    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \
1089    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr )  \
1090    { \
1091       return &vg_default_zone; \
1092    }
1093 
1094 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
1095 ZONE_FROM_PTR(SO_SYN_MALLOC,    malloc_zone_from_ptr);
1096 
1097 
1098 // GrP fixme bypass libc's use of zone->introspect->check
1099 #define ZONE_CHECK(soname, fnname) \
1100    \
1101    int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \
1102    int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone)  \
1103    { \
1104       trigger_memcheck_error_if_undefined((ULong) zone); \
1105       return 1; \
1106    }
1107 
1108 //ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1109 
1110 #endif /* defined(VGO_darwin) */
1111 
1112 
1113 /*------------------ (startup related) ------------------*/
1114 
1115 /* All the code in here is unused until this function is called */
1116 
1117 __attribute__((constructor))
init(void)1118 static void init(void)
1119 {
1120    // This doesn't look thread-safe, but it should be ok... Bart says:
1121    //
1122    //   Every program I know of calls malloc() at least once before calling
1123    //   pthread_create().  So init_done gets initialized before any thread is
1124    //   created, and is only read when multiple threads are active
1125    //   simultaneously.  Such an access pattern is safe.
1126    //
1127    //   If the assignment to the variable init_done would be triggering a race
1128    //   condition, both DRD and Helgrind would report this race.
1129    //
1130    //   By the way, although the init() function in
1131    //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1132    //   __attribute__((constructor)), it is not safe to remove the variable
1133    //   init_done. This is because it is possible that malloc() and hence
1134    //   init() gets called before shared library initialization finished.
1135    //
1136    if (init_done)
1137       return;
1138 
1139    init_done = 1;
1140 
1141    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1142                                    0, 0, 0, 0);
1143 }
1144 
1145 /*--------------------------------------------------------------------*/
1146 /*--- end                                                          ---*/
1147 /*--------------------------------------------------------------------*/
1148