• 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-2015 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 #elif defined(VGO_solaris)
309  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
310  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
311  ALLOC_or_NULL(VG_Z_LIBUMEM_SO_1,     malloc,      malloc);
312  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
313 
314 #endif
315 
316 
317 /*---------------------- new ----------------------*/
318 
319 #if defined(VGO_linux)
320  // operator new(unsigned int), not mangled (for gcc 2.96)
321  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
322  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
323  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
324  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
325  // operator new(unsigned int), GNU mangling
326  #if VG_WORDSIZE == 4
327   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
328   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
329   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
330  #endif
331  // operator new(unsigned long), GNU mangling
332  #if VG_WORDSIZE == 8
333   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
334   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
335   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
336  #endif
337 
338 #elif defined(VGO_darwin)
339  // operator new(unsigned int), GNU mangling
340  #if VG_WORDSIZE == 4
341   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
342   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
343  #endif
344  // operator new(unsigned long), GNU mangling
345  #if 1 // FIXME: is this right?
346   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
347   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
348  #endif
349 
350 #elif defined(VGO_solaris)
351  // operator new(unsigned int), GNU mangling
352  #if VG_WORDSIZE == 4
353   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
354   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
355  #endif
356  // operator new(unsigned long), GNU mangling
357  #if VG_WORDSIZE == 8
358   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
359   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
360  #endif
361 
362 #endif
363 
364 
365 /*---------------------- new nothrow ----------------------*/
366 
367 #if defined(VGO_linux)
368  // operator new(unsigned, std::nothrow_t const&), GNU mangling
369  #if VG_WORDSIZE == 4
370   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
371   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
372   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
373  #endif
374  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
375  #if VG_WORDSIZE == 8
376   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
377   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
378   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
379  #endif
380 
381 #elif defined(VGO_darwin)
382  // operator new(unsigned, std::nothrow_t const&), GNU mangling
383  #if VG_WORDSIZE == 4
384   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
385   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
386  #endif
387  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
388  #if 1 // FIXME: is this right?
389   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
390   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
391  #endif
392 
393 #elif defined(VGO_solaris)
394  // operator new(unsigned, std::nothrow_t const&), GNU mangling
395  #if VG_WORDSIZE == 4
396   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
397   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
398  #endif
399  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
400  #if VG_WORDSIZE == 8
401   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
402   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
403  #endif
404 
405 #endif
406 
407 
408 /*---------------------- new [] ----------------------*/
409 
410 #if defined(VGO_linux)
411  // operator new[](unsigned int), not mangled (for gcc 2.96)
412  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
413  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
414  // operator new[](unsigned int), GNU mangling
415  #if VG_WORDSIZE == 4
416   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
417   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
418   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
419  #endif
420  // operator new[](unsigned long), GNU mangling
421  #if VG_WORDSIZE == 8
422   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
423   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
424   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
425  #endif
426 
427 #elif defined(VGO_darwin)
428  // operator new[](unsigned int), GNU mangling
429  #if VG_WORDSIZE == 4
430   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
431   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
432  #endif
433  // operator new[](unsigned long), GNU mangling
434  #if 1 // FIXME: is this right?
435   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
436   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
437  #endif
438 
439 #elif defined(VGO_solaris)
440  // operator new[](unsigned int), GNU mangling
441  #if VG_WORDSIZE == 4
442   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
443   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
444  #endif
445  // operator new[](unsigned long), GNU mangling
446  #if VG_WORDSIZE == 8
447   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
448   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
449  #endif
450 
451 #endif
452 
453 
454 /*---------------------- new [] nothrow ----------------------*/
455 
456 #if defined(VGO_linux)
457  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
458  #if VG_WORDSIZE == 4
459   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
460   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
461   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
462  #endif
463  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
464  #if VG_WORDSIZE == 8
465   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
466   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
467   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
468  #endif
469 
470 #elif defined(VGO_darwin)
471  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
472  #if VG_WORDSIZE == 4
473   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
474   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
475  #endif
476  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
477  #if 1 // FIXME: is this right?
478   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
479   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
480  #endif
481 
482 #elif defined(VGO_solaris)
483  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
484  #if VG_WORDSIZE == 4
485   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
486   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
487  #endif
488  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
489  #if VG_WORDSIZE == 8
490   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
491   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
492  #endif
493 
494 #endif
495 
496 
497 /*---------------------- free ----------------------*/
498 
499 /* Generate a replacement for 'fnname' in object 'soname', which calls
500    'vg_replacement' to free previously allocated memory.
501 */
502 #define ZONEFREE(soname, fnname, vg_replacement) \
503    \
504    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
505    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p)  \
506    { \
507       DO_INIT; \
508       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	\
509       MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
510       if (p == NULL)  \
511          return; \
512       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
513    }
514 
515 #define FREE(soname, fnname, vg_replacement) \
516    \
517    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
518    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p)  \
519    { \
520       DO_INIT; \
521       MALLOC_TRACE(#fnname "(%p)\n", p ); \
522       if (p == NULL)  \
523          return; \
524       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
525    }
526 
527 
528 #if defined(VGO_linux)
529  FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
530  FREE(VG_Z_LIBC_SONAME,       free,                 free );
531  FREE(SO_SYN_MALLOC,          free,                 free );
532 
533 #elif defined(VGO_darwin)
534  FREE(VG_Z_LIBC_SONAME,       free,                 free );
535  FREE(SO_SYN_MALLOC,          free,                 free );
536  ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
537  ZONEFREE(SO_SYN_MALLOC,      malloc_zone_free,     free );
538 
539 #elif defined(VGO_solaris)
540  FREE(VG_Z_LIBC_SONAME,       free,                 free );
541  FREE(VG_Z_LIBUMEM_SO_1,      free,                 free );
542  FREE(SO_SYN_MALLOC,          free,                 free );
543 
544 #endif
545 
546 
547 /*---------------------- cfree ----------------------*/
548 
549 // cfree
550 #if defined(VGO_linux)
551  FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
552  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
553  FREE(SO_SYN_MALLOC,          cfree,                free );
554 
555 #elif defined(VGO_darwin)
556  //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
557  //FREE(VG_Z_LIBC_SONAME,       cfree,                free );
558 
559 #elif defined(VGO_solaris)
560  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
561  /* libumem does not implement cfree(). */
562  //FREE(VG_Z_LIBUMEM_SO_1,      cfree,                free );
563  FREE(SO_SYN_MALLOC,          cfree,                free );
564 
565 #endif
566 
567 
568 /*---------------------- delete ----------------------*/
569 
570 #if defined(VGO_linux)
571  // operator delete(void*), not mangled (for gcc 2.96)
572  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
573  FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
574  // operator delete(void*), GNU mangling
575  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
576  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
577  FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
578 
579 #elif defined(VGO_darwin)
580  // operator delete(void*), GNU mangling
581  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
582  //FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
583 
584 #elif defined(VGO_solaris)
585  // operator delete(void*), GNU mangling
586  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
587  FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
588 
589 #endif
590 
591 
592 /*---------------------- delete nothrow ----------------------*/
593 
594 #if defined(VGO_linux)
595  // operator delete(void*, std::nothrow_t const&), GNU mangling
596  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
597  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
598  FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
599 
600 #elif defined(VGO_darwin)
601  // operator delete(void*, std::nothrow_t const&), GNU mangling
602  //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
603  //FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
604 
605 #elif defined(VGO_solaris)
606  // operator delete(void*, std::nothrow_t const&), GNU mangling
607  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
608  FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
609 
610 #endif
611 
612 
613 /*---------------------- delete [] ----------------------*/
614 
615 #if defined(VGO_linux)
616  // operator delete[](void*), not mangled (for gcc 2.96)
617  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
618  FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
619  // operator delete[](void*), GNU mangling
620  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
621  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
622  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
623 
624 #elif defined(VGO_darwin)
625  // operator delete[](void*), not mangled (for gcc 2.96)
626  //FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
627  //FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
628  // operator delete[](void*), GNU mangling
629  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
630  //FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
631 
632 #elif defined(VGO_solaris)
633  // operator delete[](void*), GNU mangling
634  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
635  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
636 
637 #endif
638 
639 
640 /*---------------------- delete [] nothrow ----------------------*/
641 
642 #if defined(VGO_linux)
643  // operator delete[](void*, std::nothrow_t const&), GNU mangling
644  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
645  FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
646  FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
647 
648 #elif defined(VGO_darwin)
649  // operator delete[](void*, std::nothrow_t const&), GNU mangling
650  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
651  //FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
652 
653 #elif defined(VGO_solaris)
654  // operator delete[](void*, std::nothrow_t const&), GNU mangling
655  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
656  FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
657 
658 #endif
659 
660 
661 /*---------------------- calloc ----------------------*/
662 
663 #define ZONECALLOC(soname, fnname) \
664    \
665    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
666             ( void *zone, SizeT nmemb, SizeT size ); \
667    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
668             ( void *zone, SizeT nmemb, SizeT size )  \
669    { \
670       void* v; \
671       \
672       DO_INIT; \
673       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
674       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \
675       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
676       MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
677       \
678       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
679       MALLOC_TRACE(" = %p\n", v ); \
680       return v; \
681    }
682 
683 #define CALLOC(soname, fnname) \
684    \
685    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
686             ( SizeT nmemb, SizeT size ); \
687    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
688             ( SizeT nmemb, SizeT size )  \
689    { \
690       void* v; \
691       \
692       DO_INIT; \
693       MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
694       \
695       /* Protect against overflow.  See bug 24078. (that bug number is
696          invalid.  Which one really?) */ \
697       /* But don't use division, since that produces an external symbol
698          reference on ARM, in the form of a call to __aeabi_uidiv.  It's
699          normally OK, because ld.so manages to resolve it to something in the
700          executable, or one of its shared objects.  But that isn't guaranteed
701          to be the case, and it has been observed to fail in rare cases, eg:
702             echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
703          So instead compute the high word of the product and check it is zero. */ \
704       if (umulHW(size, nmemb) != 0) return NULL; \
705       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
706       MALLOC_TRACE(" = %p\n", v ); \
707       return v; \
708    }
709 
710 #if defined(VGO_linux)
711  CALLOC(VG_Z_LIBC_SONAME, calloc);
712  CALLOC(SO_SYN_MALLOC,    calloc);
713 
714 #elif defined(VGO_darwin)
715  CALLOC(VG_Z_LIBC_SONAME, calloc);
716  CALLOC(SO_SYN_MALLOC,    calloc);
717  ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
718  ZONECALLOC(SO_SYN_MALLOC,    malloc_zone_calloc);
719 
720 #elif defined(VGO_solaris)
721  CALLOC(VG_Z_LIBC_SONAME,      calloc);
722  CALLOC(VG_Z_LIBUMEM_SO_1,     calloc);
723  CALLOC(SO_SYN_MALLOC,         calloc);
724 
725 #endif
726 
727 
728 /*---------------------- realloc ----------------------*/
729 
730 #define ZONEREALLOC(soname, fnname) \
731    \
732    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
733             ( void *zone, void* ptrV, SizeT new_size ); \
734    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
735             ( void *zone, void* ptrV, SizeT new_size ) \
736    { \
737       void* v; \
738       \
739       DO_INIT; \
740       MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
741       \
742       if (ptrV == NULL) \
743          /* We need to call a malloc-like function; so let's use \
744             one which we know exists. GrP fixme use zonemalloc instead? */ \
745          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
746                    (new_size); \
747       if (new_size <= 0) { \
748          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
749          MALLOC_TRACE(" = 0\n"); \
750          return NULL; \
751       } \
752       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
753       MALLOC_TRACE(" = %p\n", v ); \
754       return v; \
755    }
756 
757 #define REALLOC(soname, fnname) \
758    \
759    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
760             ( void* ptrV, SizeT new_size );\
761    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
762             ( void* ptrV, SizeT new_size ) \
763    { \
764       void* v; \
765       \
766       DO_INIT; \
767       MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
768       \
769       if (ptrV == NULL) \
770          /* We need to call a malloc-like function; so let's use \
771             one which we know exists. */ \
772          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
773                    (new_size); \
774       if (new_size <= 0) { \
775          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
776          MALLOC_TRACE(" = 0\n"); \
777          return NULL; \
778       } \
779       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
780       MALLOC_TRACE(" = %p\n", v ); \
781       return v; \
782    }
783 
784 #if defined(VGO_linux)
785  REALLOC(VG_Z_LIBC_SONAME, realloc);
786  REALLOC(SO_SYN_MALLOC,    realloc);
787 
788 #elif defined(VGO_darwin)
789  REALLOC(VG_Z_LIBC_SONAME, realloc);
790  REALLOC(SO_SYN_MALLOC,    realloc);
791  ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
792  ZONEREALLOC(SO_SYN_MALLOC,    malloc_zone_realloc);
793 
794 #elif defined(VGO_solaris)
795  REALLOC(VG_Z_LIBC_SONAME,      realloc);
796  REALLOC(VG_Z_LIBUMEM_SO_1,     realloc);
797  REALLOC(SO_SYN_MALLOC,         realloc);
798 
799 #endif
800 
801 
802 /*---------------------- memalign ----------------------*/
803 
804 #define ZONEMEMALIGN(soname, fnname) \
805    \
806    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
807             ( void *zone, SizeT alignment, SizeT n ); \
808    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
809             ( void *zone, SizeT alignment, SizeT n ) \
810    { \
811       void* v; \
812       \
813       DO_INIT; \
814       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	\
815       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
816       MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
817                    zone, (ULong)alignment, (ULong)n );  \
818       \
819       /* Round up to minimum alignment if necessary. */ \
820       if (alignment < VG_MIN_MALLOC_SZB) \
821          alignment = VG_MIN_MALLOC_SZB; \
822       \
823       /* Round up to nearest power-of-two if necessary (like glibc). */ \
824       while (0 != (alignment & (alignment - 1))) alignment++; \
825       \
826       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
827       MALLOC_TRACE(" = %p\n", v ); \
828       return v; \
829    }
830 
831 #define MEMALIGN(soname, fnname) \
832    \
833    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
834             ( SizeT alignment, SizeT n ); \
835    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
836             ( SizeT alignment, SizeT n )  \
837    { \
838       void* v; \
839       \
840       DO_INIT; \
841       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
842       MALLOC_TRACE("memalign(al %llu, size %llu)", \
843                    (ULong)alignment, (ULong)n ); \
844       \
845       /* Round up to minimum alignment if necessary. */ \
846       if (alignment < VG_MIN_MALLOC_SZB) \
847          alignment = VG_MIN_MALLOC_SZB; \
848       \
849       /* Round up to nearest power-of-two if necessary (like glibc). */ \
850       while (0 != (alignment & (alignment - 1))) alignment++; \
851       \
852       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
853       MALLOC_TRACE(" = %p\n", v ); \
854       return v; \
855    }
856 
857 #if defined(VGO_linux)
858  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
859  MEMALIGN(SO_SYN_MALLOC,    memalign);
860 
861 #elif defined(VGO_darwin)
862  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
863  MEMALIGN(SO_SYN_MALLOC,    memalign);
864  ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
865  ZONEMEMALIGN(SO_SYN_MALLOC,    malloc_zone_memalign);
866 
867 #elif defined(VGO_solaris)
868  MEMALIGN(VG_Z_LIBC_SONAME,      memalign);
869  MEMALIGN(VG_Z_LIBUMEM_SO_1,     memalign);
870  MEMALIGN(SO_SYN_MALLOC,         memalign);
871 
872 #endif
873 
874 
875 /*---------------------- valloc ----------------------*/
876 
877 #define VALLOC(soname, fnname) \
878    \
879    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
880    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
881    { \
882       static int pszB = 0; \
883       if (pszB == 0) \
884          pszB = my_getpagesize(); \
885       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
886                 ((SizeT)pszB, size); \
887    }
888 
889 #define ZONEVALLOC(soname, fnname) \
890    \
891    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
892             ( void *zone, SizeT size ); \
893    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
894             ( void *zone, SizeT size )  \
895    { \
896       static int pszB = 0; \
897       if (pszB == 0) \
898          pszB = my_getpagesize(); \
899       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	      \
900       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
901                 ((SizeT)pszB, size); \
902    }
903 
904 #if defined(VGO_linux)
905  VALLOC(VG_Z_LIBC_SONAME, valloc);
906  VALLOC(SO_SYN_MALLOC, valloc);
907 
908 #elif defined(VGO_darwin)
909  VALLOC(VG_Z_LIBC_SONAME, valloc);
910  VALLOC(SO_SYN_MALLOC, valloc);
911  ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
912  ZONEVALLOC(SO_SYN_MALLOC,    malloc_zone_valloc);
913 
914 #elif defined(VGO_solaris)
915  VALLOC(VG_Z_LIBC_SONAME,      valloc);
916  VALLOC(VG_Z_LIBUMEM_SO_1,     valloc);
917  VALLOC(SO_SYN_MALLOC,         valloc);
918 
919 #endif
920 
921 
922 /*---------------------- mallopt ----------------------*/
923 
924 /* Various compatibility wrapper functions, for glibc and libstdc++. */
925 
926 #define MALLOPT(soname, fnname) \
927    \
928    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
929    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
930    { \
931       /* In glibc-2.2.4, 1 denotes a successful return value for \
932          mallopt */ \
933       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
934       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
935       return 1; \
936    }
937 
938 #if defined(VGO_linux)
939  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
940  MALLOPT(SO_SYN_MALLOC,    mallopt);
941 
942 #elif defined(VGO_darwin)
943  //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
944 
945 #endif
946 
947 
948 /*---------------------- malloc_trim ----------------------*/
949 // Documentation says:
950 //   malloc_trim(size_t pad);
951 //
952 //   If possible, gives memory back to the system (via negative arguments to
953 //   sbrk) if there is unused memory at the `high' end of the malloc pool.
954 //   You can call this after freeing large blocks of memory to potentially
955 //   reduce the system-level memory requirements of a program. However, it
956 //   cannot guarantee to reduce memory.  Under some allocation patterns,
957 //   some large free blocks of memory will be locked between two used
958 //   chunks, so they cannot be given back to the system.
959 //
960 //   The `pad' argument to malloc_trim represents the amount of free
961 //   trailing space to leave untrimmed. If this argument is zero, only the
962 //   minimum amount of memory to maintain internal data structures will be
963 //   left (one page or less). Non-zero arguments can be supplied to maintain
964 //   enough trailing space to service future expected allocations without
965 //   having to re-obtain memory from the system.
966 //
967 //   Malloc_trim returns 1 if it actually released any memory, else 0. On
968 //   systems that do not support "negative sbrks", it will always return 0.
969 //
970 // For simplicity, we always return 0.
971 #define MALLOC_TRIM(soname, fnname) \
972    \
973    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
974    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
975    { \
976       /* 0 denotes that malloc_trim() either wasn't able \
977          to do anything, or was not implemented */ \
978       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(pad); \
979       return 0; \
980    }
981 
982 #if defined(VGO_linux)
983  MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
984  MALLOC_TRIM(SO_SYN_MALLOC,    malloc_trim);
985 
986 #elif defined(VGO_darwin)
987  //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
988 
989 #endif
990 
991 
992 /*---------------------- posix_memalign ----------------------*/
993 
994 #define POSIX_MEMALIGN(soname, fnname) \
995    \
996    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
997           ( void **memptr, SizeT alignment, SizeT size ); \
998    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
999           ( void **memptr, SizeT alignment, SizeT size ) \
1000    { \
1001       void *mem; \
1002       \
1003       /* Test whether the alignment argument is valid.  It must be \
1004          a power of two multiple of sizeof (void *).  */ \
1005       if (alignment % sizeof (void *) != 0 \
1006           || (alignment & (alignment - 1)) != 0) \
1007          return VKI_EINVAL; \
1008       \
1009       mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
1010                (alignment, size); \
1011       \
1012       if (mem != NULL) { \
1013         *memptr = mem; \
1014         return 0; \
1015       } \
1016       \
1017       return VKI_ENOMEM; \
1018    }
1019 
1020 #if defined(VGO_linux)
1021  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1022  POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
1023 
1024 #elif defined(VGO_darwin)
1025  //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1026 
1027 #elif defined(VGO_solaris)
1028  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1029  POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
1030 
1031 #endif
1032 
1033 
1034 /*---------------------- malloc_usable_size ----------------------*/
1035 
1036 #define MALLOC_USABLE_SIZE(soname, fnname) \
1037    \
1038    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
1039    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
1040    {  \
1041       SizeT pszB; \
1042       \
1043       DO_INIT; \
1044       MALLOC_TRACE("malloc_usable_size(%p)", p ); \
1045       if (NULL == p) \
1046          return 0; \
1047       \
1048       pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
1049       MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
1050       \
1051       return pszB; \
1052    }
1053 
1054 #if defined(VGO_linux)
1055  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
1056  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
1057  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
1058  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
1059 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
1060      || defined(VGPV_mips32_linux_android)
1061   MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
1062   MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
1063 # endif
1064 
1065 #elif defined(VGO_darwin)
1066  //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
1067  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
1068  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
1069 
1070 #endif
1071 
1072 
1073 /*---------------------- (unimplemented) ----------------------*/
1074 
1075 /* Bomb out if we get any of these. */
1076 
1077 static void panic(const char *str) __attribute__((unused));
panic(const char * str)1078 static void panic(const char *str)
1079 {
1080    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
1081    my_exit(1);
1082 }
1083 
1084 #define PANIC(soname, fnname) \
1085    \
1086    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
1087    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void )  \
1088    { \
1089       panic(#fnname); \
1090    }
1091 
1092 #if defined(VGO_linux)
1093  PANIC(VG_Z_LIBC_SONAME, pvalloc);
1094  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1095  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1096 
1097 #elif defined(VGO_darwin)
1098  PANIC(VG_Z_LIBC_SONAME, pvalloc);
1099  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1100  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1101 
1102 #endif
1103 
1104 
1105 #define MALLOC_STATS(soname, fnname) \
1106    \
1107    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
1108    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void )  \
1109    { \
1110       /* Valgrind's malloc_stats implementation does nothing. */ \
1111    }
1112 
1113 #if defined(VGO_linux)
1114  MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1115  MALLOC_STATS(SO_SYN_MALLOC,    malloc_stats);
1116 
1117 #elif defined(VGO_darwin)
1118  //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1119 
1120 #endif
1121 
1122 
1123 /*---------------------- mallinfo ----------------------*/
1124 
1125 // mi must be static;  if it is auto then Memcheck thinks it is
1126 // uninitialised when used by the caller of this function, because Memcheck
1127 // doesn't know that the call to mallinfo fills in mi.
1128 #define MALLINFO(soname, fnname) \
1129    \
1130    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1131    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
1132    { \
1133       static struct vg_mallinfo mi; \
1134       DO_INIT; \
1135       MALLOC_TRACE("mallinfo()\n"); \
1136       (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1137       return mi; \
1138    }
1139 
1140 #if defined(VGO_linux)
1141  MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1142  MALLINFO(SO_SYN_MALLOC,    mallinfo);
1143 
1144 #elif defined(VGO_darwin)
1145  //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1146 
1147 #endif
1148 
1149 
1150 /*------------------ Darwin zone stuff ------------------*/
1151 
1152 #if defined(VGO_darwin)
1153 
my_malloc_size(void * zone,void * ptr)1154 static size_t my_malloc_size ( void* zone, void* ptr )
1155 {
1156    /* Implement "malloc_size" by handing the request through to the
1157       tool's .tl_usable_size method. */
1158    DO_INIT;
1159    TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);
1160    TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) ptr);
1161    size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1162                            info.tl_malloc_usable_size, ptr);
1163    return res;
1164 }
1165 
1166 /* Note that the (void*) casts below are a kludge which stops
1167    compilers complaining about the fact that the replacement
1168    functions aren't really of the right type. */
1169 static vki_malloc_zone_t vg_default_zone = {
1170     NULL, // reserved1
1171     NULL, // reserved2
1172     (void*)my_malloc_size, // JRS fixme: is this right?
1173     (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1174     (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1175     (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1176     (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1177     (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
1178     NULL, // GrP fixme: destroy
1179     "ValgrindMallocZone",
1180     NULL, // batch_malloc
1181     NULL, // batch_free
1182     NULL, // GrP fixme: introspect
1183     2,  // version (GrP fixme 3?)
1184     (void*)VG_REPLACE_FUNCTION_EZU(10100,VG_Z_LIBC_SONAME,malloc_zone_memalign), // DDD: this field exists in Mac OS 10.6+
1185     NULL, /* free_definite_size */
1186     NULL, /* pressure_relief */
1187 };
1188 
1189 
1190 #define DEFAULT_ZONE(soname, fnname) \
1191    \
1192    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1193    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void )  \
1194    { \
1195       return &vg_default_zone; \
1196    }
1197 
1198 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
1199 DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_zone);
1200 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_purgeable_zone);
1201 DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_purgeable_zone);
1202 
1203 
1204 #define CREATE_ZONE(soname, fnname) \
1205    \
1206    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl); \
1207    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl)  \
1208    { \
1209       return &vg_default_zone; \
1210    }
1211 CREATE_ZONE(VG_Z_LIBC_SONAME, malloc_create_zone);
1212 
1213 
1214 #define ZONE_FROM_PTR(soname, fnname) \
1215    \
1216    void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
1217    void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr )  \
1218    { \
1219       return &vg_default_zone; \
1220    }
1221 
1222 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
1223 ZONE_FROM_PTR(SO_SYN_MALLOC,    malloc_zone_from_ptr);
1224 
1225 
1226 // GrP fixme bypass libc's use of zone->introspect->check
1227 #define ZONE_CHECK(soname, fnname) \
1228    \
1229    int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
1230    int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone)  \
1231    { \
1232       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1233       panic(#fnname); \
1234       return 1; \
1235    }
1236 
1237 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1238 ZONE_CHECK(SO_SYN_MALLOC,    malloc_zone_check);
1239 
1240 
1241 #define ZONE_REGISTER(soname, fnname) \
1242    \
1243    void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
1244    void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone)  \
1245    { \
1246       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1247    }
1248 
1249 ZONE_REGISTER(VG_Z_LIBC_SONAME, malloc_zone_register);
1250 ZONE_REGISTER(SO_SYN_MALLOC,    malloc_zone_register);
1251 
1252 
1253 #define ZONE_UNREGISTER(soname, fnname) \
1254    \
1255    void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
1256    void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone)  \
1257    { \
1258       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1259    }
1260 
1261 ZONE_UNREGISTER(VG_Z_LIBC_SONAME, malloc_zone_unregister);
1262 ZONE_UNREGISTER(SO_SYN_MALLOC,    malloc_zone_unregister);
1263 
1264 
1265 #define ZONE_SET_NAME(soname, fnname) \
1266    \
1267    void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm); \
1268    void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm)  \
1269    { \
1270       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1271    }
1272 
1273 ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_set_zone_name);
1274 ZONE_SET_NAME(SO_SYN_MALLOC,    malloc_set_zone_name);
1275 
1276 
1277 #define ZONE_GET_NAME(soname, fnname) \
1278    \
1279    const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
1280    const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone)  \
1281    { \
1282       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1283       return vg_default_zone.zone_name; \
1284    }
1285 
1286 ZONE_GET_NAME(VG_Z_LIBC_SONAME, malloc_get_zone_name);
1287 ZONE_GET_NAME(SO_SYN_MALLOC,    malloc_get_zone_name);
1288 
1289 #endif /* defined(VGO_darwin) */
1290 
1291 
1292 /*------------------ (startup related) ------------------*/
1293 
1294 /* All the code in here is unused until this function is called */
1295 
1296 __attribute__((constructor))
init(void)1297 static void init(void)
1298 {
1299    // This doesn't look thread-safe, but it should be ok... Bart says:
1300    //
1301    //   Every program I know of calls malloc() at least once before calling
1302    //   pthread_create().  So init_done gets initialized before any thread is
1303    //   created, and is only read when multiple threads are active
1304    //   simultaneously.  Such an access pattern is safe.
1305    //
1306    //   If the assignment to the variable init_done would be triggering a race
1307    //   condition, both DRD and Helgrind would report this race.
1308    //
1309    //   By the way, although the init() function in
1310    //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1311    //   __attribute__((constructor)), it is not safe to remove the variable
1312    //   init_done. This is because it is possible that malloc() and hence
1313    //   init() gets called before shared library initialization finished.
1314    //
1315    if (init_done)
1316       return;
1317 
1318    init_done = 1;
1319 
1320    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1321                                    0, 0, 0, 0);
1322 }
1323 
1324 /*--------------------------------------------------------------------*/
1325 /*--- end                                                          ---*/
1326 /*--------------------------------------------------------------------*/
1327