1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Replacements for malloc() et al, which run on the simulated  ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- CPU.                                     vg_replace_malloc.c ---*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2000-2012 Julian Seward
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      jseward@acm.org
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   These functions are drop-in replacements for malloc() and friends.
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   They have global scope, but are not intended to be called directly.
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   See pub_core_redir.h for the gory details.
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file can be linked into the vg_preload_<tool>.so file for any tool
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that wishes to know about calls to malloc().  The tool must define all
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the functions that will be called via 'info'.
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   It is called vg_replace_malloc.c because this filename appears in stack
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   traces, so we want the name to be (hopefully!) meaningful to users.
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IMPORTANT: this file must not contain any floating point code, nor
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any integer division.  This is because on ARM these can cause calls
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   to helper functions, which will be unresolved within this .so.
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Although it is usually the case that the client's ld.so instance
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   can bind them at runtime to the relevant functions in the client
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   executable, there is no guarantee of this; and so the client may
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   die via a runtime link failure.  Hence the only safe approach is to
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   avoid such function calls in the first place.  See "#define CALLOC"
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   below for a specific example.
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   A useful command is
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for f in `find . -name "*preload*.so*"` ; \
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          do nm -A $f | grep " U " ; \
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      done
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   to see all the undefined symbols in all the preload shared objects.
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h"           // VKI_EINVAL, VKI_ENOMEM
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_clreq.h"         // for VALGRIND_INTERNAL_PRINTF,
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    //   VALGRIND_NON_SIMD_CALL[12]
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuginfo.h"     // needed for pub_core_redir.h :(
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_mallocfree.h"    // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_redir.h"         // for VG_REPLACE_FUNCTION_*
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_replacemalloc.h"
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Assignment of behavioural equivalence class tags: 1NNNP is intended
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to be reserved for the Valgrind core.  Current usage:
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10010 ALLOC_or_NULL
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10020 ZONEALLOC_or_NULL
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10030 ALLOC_or_BOMB
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10040 ZONEFREE
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10050 FREE
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10060 ZONECALLOC
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10070 CALLOC
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10080 ZONEREALLOC
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10090 REALLOC
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10100 ZONEMEMALIGN
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10110 MEMALIGN
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10120 VALLOC
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10130 ZONEVALLOC
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10140 MALLOPT
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10150 MALLOC_TRIM
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10160 POSIX_MEMALIGN
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10170 MALLOC_USABLE_SIZE
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10180 PANIC
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10190 MALLOC_STATS
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10200 MALLINFO
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10210 DEFAULT_ZONE
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   10220 ZONE_CHECK
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangling, could be supported properly by the redirects in this
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   module.  Except we can't because it doesn't put its allocation
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   functions in libpgc.so but instead hardwires them into the
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   compilation unit holding main(), which makes them impossible to
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   intercept directly.  Fortunately those fns seem to route everything
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   through to malloc/free.
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mid-06: could be improved, since we can now intercept in the main
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   executable too.
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Call here to exit if we can't continue.  On Android we can't call
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _exit for some reason, so we have to blunt-instrument it. */
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((__noreturn__))
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline void my_exit ( int x )
1188f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov{
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  if defined(VGPV_arm_linux_android)
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   __asm__ __volatile__(".word 0xFFFFFFFF");
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (1) {}
122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  elif defined(VGPV_x86_linux_android)
123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__ __volatile__("ud2");
124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   while (1) {}
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  else
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   extern __attribute__ ((__noreturn__)) void _exit(int status);
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _exit(x);
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  endif
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Same problem with getpagesize. */
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline int my_getpagesize ( void )
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 4096; /* kludge - link failure on Android, for some reason */
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  else
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   extern int getpagesize (void);
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return getpagesize();
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  endif
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Compute the high word of the double-length unsigned product of U
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and V.  This is for calloc argument overflow checking; see comments
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   below.  Algorithm as described in Hacker's Delight, chapter 8. */
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord umulHW ( UWord u, UWord v )
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord u0, v0, w0, rHi;
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord u1, v1, w1,w2,t;
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord halfMask  = sizeof(UWord)==4 ? (UWord)0xFFFF
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                      : (UWord)0xFFFFFFFFULL;
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   u0  = u & halfMask;
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   u1  = u >> halfShift;
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   v0  = v & halfMask;
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   v1  = v >> halfShift;
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w0  = u0 * v0;
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t   = u1 * v0 + (w0 >> halfShift);
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w1  = t & halfMask;
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w2  = t >> halfShift;
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w1  = u0 * v1 + w1;
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rHi = u1 * v1 + w2 + (w1 >> halfShift);
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return rHi;
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Replacing malloc() et al                             ---*/
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This struct is initially empty.  Before the first use of any of
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   these functions, we make a client request which fills in the
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fields.
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct vg_mallocfunc_info info;
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int init_done;
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Startup hook - called as init section */
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((constructor))
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void init(void);
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLOC_TRACE(format, args...)  \
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (info.clo_trace_malloc) {        \
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VALGRIND_INTERNAL_PRINTF(format, ## args ); }
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Below are new versions of malloc, __builtin_new, free,
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __builtin_delete, calloc, realloc, memalign, and friends.
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   None of these functions are called directly - they are not meant to
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be found by the dynamic linker.  But ALL client calls to malloc()
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and friends wind up here eventually.  They get called because
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_replace_malloc installs a bunch of code redirects which causes
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Valgrind to use these functions rather than the ones they're
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   replacing.
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- malloc ----------------------*/
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate a replacement for 'fnname' in object 'soname', which calls
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'vg_replacement' to allocate memory.  If that fails, return NULL.
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n)  \
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n)  \
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate a replacement for 'fnname' in object 'soname', which calls
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'vg_replacement' to allocate memory.  If that fails, it bombs the
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   system.
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ALLOC_or_BOMB(soname, fnname, vg_replacement)  \
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n)  \
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(#fnname "(%llu)", (ULong)n );        \
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (NULL == v) { \
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_PRINTF( \
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "new/new[] failed and should throw an exception, but Valgrind\n"); \
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_PRINTF_BACKTRACE( \
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            my_exit(1); \
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } \
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Each of these lines generates a replacement function:
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//     (from_so, from_fn,  v's replacement)
262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// For some lines, we will also define a replacement function
263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// whose only purpose is to be a soname synonym place holder
264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// that can be replaced using --soname-synonyms.
265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SO_SYN_MALLOC VG_SO_SYN(somalloc)
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// malloc
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME,  malloc_zone_malloc, malloc);
277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEALLOC_or_NULL(SO_SYN_MALLOC,     malloc_zone_malloc, malloc);
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- new ----------------------*/
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned int), not mangled (for gcc 2.96)
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned int), GNU mangling
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned long), GNU mangling
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 8
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
3029bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned int), GNU mangling
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned long), GNU mangling
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if 1 // FIXME: is this right?
311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- new nothrow ----------------------*/
319f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned, std::nothrow_t const&), GNU mangling
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned long, std::nothrow_t const&), GNU mangling
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 8
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned, std::nothrow_t const&), GNU mangling
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new(unsigned long, std::nothrow_t const&), GNU mangling
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if 1 // FIXME: is this right?
342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- new [] ----------------------*/
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned int), not mangled (for gcc 2.96)
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned int), GNU mangling
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned long), GNU mangling
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 8
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned int), GNU mangling
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned long), GNU mangling
375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if 1 // FIXME: is this right?
376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
3799bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- new [] nothrow ----------------------*/
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned, std::nothrow_t const&), GNU mangling
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 8
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned, std::nothrow_t const&), GNU mangling
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if VG_WORDSIZE == 4
402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #if 1 // FIXME: is this right?
407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #endif
4109bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- free ----------------------*/
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate a replacement for 'fnname' in object 'soname', which calls
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'vg_replacement' to free previously allocated memory.
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONEFREE(soname, fnname, vg_replacement) \
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p)  \
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p == NULL)  \
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return; \
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define FREE(soname, fnname, vg_replacement) \
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p)  \
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      MALLOC_TRACE(#fnname "(%p)\n", p ); \
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p == NULL)  \
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return; \
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       free,                 free );
447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          free,                 free );
448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       free,                 free );
451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          free,                 free );
452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEFREE(SO_SYN_MALLOC,      malloc_zone_free,     free );
454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- cfree ----------------------*/
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// cfree
461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       cfree,                free );
464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          cfree,                free );
465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //FREE(VG_Z_LIBC_SONAME,       cfree,                free );
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- delete ----------------------*/
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete(void*), not mangled (for gcc 2.96)
477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete(void*), GNU mangling
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete(void*), GNU mangling
486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- delete nothrow ----------------------*/
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete(void*, std::nothrow_t const&), GNU mangling
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete(void*, std::nothrow_t const&), GNU mangling
502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- delete [] ----------------------*/
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*), not mangled (for gcc 2.96)
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*), GNU mangling
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*), not mangled (for gcc 2.96)
521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*), GNU mangling
524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- delete [] nothrow ----------------------*/
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*, std::nothrow_t const&), GNU mangling
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operator delete[](void*, std::nothrow_t const&), GNU mangling
540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- calloc ----------------------*/
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONECALLOC(soname, fnname) \
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT nmemb, SizeT size ); \
552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT nmemb, SizeT size )  \
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALLOC(soname, fnname) \
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( SizeT nmemb, SizeT size ); \
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( SizeT nmemb, SizeT size )  \
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Protect against overflow.  See bug 24078. (that bug number is
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         invalid.  Which one really?) */ \
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* But don't use division, since that produces an external symbol
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         reference on ARM, in the form of a call to __aeabi_uidiv.  It's
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         normally OK, because ld.so manages to resolve it to something in the
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         executable, or one of its shared objects.  But that isn't guaranteed
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to be the case, and it has been observed to fail in rare cases, eg:
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         So instead compute the high word of the product and check it is zero. */ \
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (umulHW(size, nmemb) != 0) return NULL; \
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov CALLOC(VG_Z_LIBC_SONAME, calloc);
594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CALLOC(SO_SYN_MALLOC,    calloc);
595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov CALLOC(VG_Z_LIBC_SONAME, calloc);
598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CALLOC(SO_SYN_MALLOC,    calloc);
599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONECALLOC(SO_SYN_MALLOC,    malloc_zone_calloc);
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- realloc ----------------------*/
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONEREALLOC(soname, fnname) \
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, void* ptrV, SizeT new_size ); \
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, void* ptrV, SizeT new_size ) \
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ptrV == NULL) \
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* We need to call a malloc-like function; so let's use \
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            one which we know exists. GrP fixme use zonemalloc instead? */ \
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   (new_size); \
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (new_size <= 0) { \
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         MALLOC_TRACE(" = 0\n"); \
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL; \
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } \
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define REALLOC(soname, fnname) \
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void* ptrV, SizeT new_size );\
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void* ptrV, SizeT new_size ) \
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ptrV == NULL) \
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* We need to call a malloc-like function; so let's use \
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            one which we know exists. */ \
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   (new_size); \
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (new_size <= 0) { \
652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         MALLOC_TRACE(" = 0\n"); \
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return NULL; \
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } \
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov REALLOC(VG_Z_LIBC_SONAME, realloc);
663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng REALLOC(SO_SYN_MALLOC,    realloc);
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov REALLOC(VG_Z_LIBC_SONAME, realloc);
667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng REALLOC(SO_SYN_MALLOC,    realloc);
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEREALLOC(SO_SYN_MALLOC,    malloc_zone_realloc);
670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- memalign ----------------------*/
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONEMEMALIGN(soname, fnname) \
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT alignment, SizeT n ); \
680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT alignment, SizeT n ) \
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   zone, (ULong)alignment, (ULong)n );  \
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Round up to minimum alignment if necessary. */ \
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (alignment < VG_MIN_MALLOC_SZB) \
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         alignment = VG_MIN_MALLOC_SZB; \
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Round up to nearest power-of-two if necessary (like glibc). */ \
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (0 != (alignment & (alignment - 1))) alignment++; \
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MEMALIGN(soname, fnname) \
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( SizeT alignment, SizeT n ); \
705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( SizeT alignment, SizeT n )  \
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void* v; \
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE("memalign(al %llu, size %llu)", \
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (ULong)alignment, (ULong)n ); \
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Round up to minimum alignment if necessary. */ \
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (alignment < VG_MIN_MALLOC_SZB) \
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         alignment = VG_MIN_MALLOC_SZB; \
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Round up to nearest power-of-two if necessary (like glibc). */ \
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (0 != (alignment & (alignment - 1))) alignment++; \
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %p\n", v ); \
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return v; \
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMALIGN(VG_Z_LIBC_SONAME, memalign);
728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMALIGN(SO_SYN_MALLOC,    memalign);
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMALIGN(VG_Z_LIBC_SONAME, memalign);
732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMALIGN(SO_SYN_MALLOC,    memalign);
733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEMEMALIGN(SO_SYN_MALLOC,    malloc_zone_memalign);
735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- valloc ----------------------*/
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALLOC(soname, fnname) \
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      static int pszB = 0; \
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (pszB == 0) \
748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         pszB = my_getpagesize(); \
749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ((SizeT)pszB, size); \
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONEVALLOC(soname, fnname) \
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT size ); \
757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ( void *zone, SizeT size )  \
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      static int pszB = 0; \
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (pszB == 0) \
762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         pszB = my_getpagesize(); \
763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ((SizeT)pszB, size); \
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALLOC(VG_Z_LIBC_SONAME, valloc);
769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALLOC(SO_SYN_MALLOC, valloc);
770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALLOC(VG_Z_LIBC_SONAME, valloc);
773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VALLOC(SO_SYN_MALLOC, valloc);
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZONEVALLOC(SO_SYN_MALLOC,    malloc_zone_valloc);
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- mallopt ----------------------*/
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Various compatibility wrapper functions, for glibc and libstdc++. */
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLOPT(soname, fnname) \
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* In glibc-2.2.4, 1 denotes a successful return value for \
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mallopt */ \
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 1; \
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOPT(VG_Z_LIBC_SONAME, mallopt);
796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOPT(SO_SYN_MALLOC,    mallopt);
797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- malloc_trim ----------------------*/
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Documentation says:
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   malloc_trim(size_t pad);
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   If possible, gives memory back to the system (via negative arguments to
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   sbrk) if there is unused memory at the `high' end of the malloc pool.
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   You can call this after freeing large blocks of memory to potentially
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   reduce the system-level memory requirements of a program. However, it
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   cannot guarantee to reduce memory.  Under some allocation patterns,
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   some large free blocks of memory will be locked between two used
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   chunks, so they cannot be given back to the system.
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   The `pad' argument to malloc_trim represents the amount of free
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   trailing space to leave untrimmed. If this argument is zero, only the
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   minimum amount of memory to maintain internal data structures will be
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   left (one page or less). Non-zero arguments can be supplied to maintain
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   enough trailing space to service future expected allocations without
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   having to re-obtain memory from the system.
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   Malloc_trim returns 1 if it actually released any memory, else 0. On
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   systems that do not support "negative sbrks", it will always return 0.
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// For simplicity, we always return 0.
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLOC_TRIM(soname, fnname) \
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* 0 denotes that malloc_trim() either wasn't able \
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to do anything, or was not implemented */ \
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0; \
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOC_TRIM(SO_SYN_MALLOC,    malloc_trim);
840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- posix_memalign ----------------------*/
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POSIX_MEMALIGN(soname, fnname) \
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          ( void **memptr, SizeT alignment, SizeT size ); \
853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          ( void **memptr, SizeT alignment, SizeT size ) \
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void *mem; \
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Test whether the alignment argument is valid.  It must be \
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         a power of two multiple of sizeof (void *).  */ \
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (alignment % sizeof (void *) != 0 \
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          || (alignment & (alignment - 1)) != 0) \
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return VKI_EINVAL; \
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               (alignment, size); \
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (mem != NULL) { \
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        *memptr = mem; \
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return 0; \
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } \
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return VKI_ENOMEM; \
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- malloc_usable_size ----------------------*/
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLOC_USABLE_SIZE(soname, fnname) \
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {  \
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SizeT pszB; \
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE("malloc_usable_size(%p)", p ); \
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (NULL == p) \
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return 0; \
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      \
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return pszB; \
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
905b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
908b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# endif
914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- (unimplemented) ----------------------*/
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Bomb out if we get any of these. */
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void panic(const char *str)
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   my_exit(99);
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *(volatile int *)0 = 'x';
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PANIC(soname, fnname) \
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void )  \
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      panic(#fnname); \
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, pvalloc);
944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, pvalloc);
949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
951b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
952b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
953b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLOC_STATS(soname, fnname) \
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void )  \
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Valgrind's malloc_stats implementation does nothing. */ \
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
964b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLOC_STATS(SO_SYN_MALLOC,    malloc_stats);
966b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
967b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
968b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
969b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------- mallinfo ----------------------*/
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// mi must be static;  if it is auto then Memcheck thinks it is
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// uninitialised when used by the caller of this function, because Memcheck
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// doesn't know that the call to mallinfo fills in mi.
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MALLINFO(soname, fnname) \
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
980b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
981b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      static struct vg_mallinfo mi; \
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!init_done) init(); \
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MALLOC_TRACE("mallinfo()\n"); \
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return mi; \
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MALLINFO(SO_SYN_MALLOC,    mallinfo);
993b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
994b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
995b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
996b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
997b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
998b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
999b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1000b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------ Darwin zone stuff ------------------*/
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_darwin)
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic size_t my_malloc_size ( void* zone, void* ptr )
1005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Implement "malloc_size" by handing the request through to the
1007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      tool's .tl_usable_size method. */
1008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (!init_done) init();
1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                           info.tl_malloc_usable_size, ptr);
1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return res;
1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Note that the (void*) casts below are a kludge which stops
1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   compilers complaining about the fact that the the replacement
1016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   functions aren't really of the right type. */
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic vki_malloc_zone_t vg_default_zone = {
1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, // reserved1
1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, // reserved2
1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    (void*)my_malloc_size, // JRS fixme: is this right?
1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1023b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
1026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, // GrP fixme: destroy
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    "ValgrindMallocZone",
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NULL, // batch_malloc
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NULL, // batch_free
1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, // GrP fixme: introspect
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    2,  // version (GrP fixme 3?)
1032b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, /* memalign */   // DDD: this field exists in Mac OS 10.6, but not 10.5.
1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, /* free_definite_size */
1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    NULL, /* pressure_relief */
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFAULT_ZONE(soname, fnname) \
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   \
1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void )  \
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return &vg_default_zone; \
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownDEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengDEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_zone);
1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1049b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1050b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ZONE_FROM_PTR(soname, fnname) \
1051b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   \
1052b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \
1053b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr )  \
1054b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { \
1055b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return &vg_default_zone; \
1056b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
1059663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengZONE_FROM_PTR(SO_SYN_MALLOC,    malloc_zone_from_ptr);
1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// GrP fixme bypass libc's use of zone->introspect->check
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ZONE_CHECK(soname, fnname) \
1064b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   \
1065b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \
1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone)  \
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { \
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 1; \
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1071b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1073b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* defined(VGO_darwin) */
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1075f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov
1076b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------ (startup related) ------------------*/
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* All the code in here is unused until this function is called */
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((constructor))
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void init(void)
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This doesn't look thread-safe, but it should be ok... Bart says:
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   Every program I know of calls malloc() at least once before calling
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   pthread_create().  So init_done gets initialized before any thread is
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   created, and is only read when multiple threads are active
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   simultaneously.  Such an access pattern is safe.
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   If the assignment to the variable init_done would be triggering a race
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   condition, both DRD and Helgrind would report this race.
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   By the way, although the init() function in
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   __attribute__((constructor)), it is not safe to remove the variable
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   init_done. This is because it is possible that malloc() and hence
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   init() gets called before shared library initialization finished.
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (init_done)
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_done = 1;
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                   0, 0, 0, 0);
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
1111