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