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