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