blob: 9fb0069b171a2e315ba76617de92b00cc4893078 [file] [log] [blame]
sewardj9ee81f52005-04-02 17:38:59 +00001
2/*--------------------------------------------------------------------*/
3/*--- Replacements for malloc() et al, which run on the simulated ---*/
4/*--- CPU. vg_replace_malloc.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright (C) 2000-2017 Julian Seward
sewardj9ee81f52005-04-02 17:38:59 +000012 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32/* ---------------------------------------------------------------------
njn16eeb4e2005-06-16 03:56:58 +000033 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
34
35 These functions are drop-in replacements for malloc() and friends.
36 They have global scope, but are not intended to be called directly.
37 See pub_core_redir.h for the gory details.
sewardj9ee81f52005-04-02 17:38:59 +000038
njn16eeb4e2005-06-16 03:56:58 +000039 This file can be linked into the vg_preload_<tool>.so file for any tool
40 that wishes to know about calls to malloc(). The tool must define all
njn51d827b2005-05-09 01:02:08 +000041 the functions that will be called via 'info'.
njn717cde52005-05-10 02:47:21 +000042
njn16eeb4e2005-06-16 03:56:58 +000043 It is called vg_replace_malloc.c because this filename appears in stack
44 traces, so we want the name to be (hopefully!) meaningful to users.
sewardj59570ff2010-01-01 11:59:33 +000045
46 IMPORTANT: this file must not contain any floating point code, nor
47 any integer division. This is because on ARM these can cause calls
48 to helper functions, which will be unresolved within this .so.
49 Although it is usually the case that the client's ld.so instance
50 can bind them at runtime to the relevant functions in the client
51 executable, there is no guarantee of this; and so the client may
52 die via a runtime link failure. Hence the only safe approach is to
53 avoid such function calls in the first place. See "#define CALLOC"
54 below for a specific example.
55
56 A useful command is
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
59 done
60
61 to see all the undefined symbols in all the preload shared objects.
sewardj9ee81f52005-04-02 17:38:59 +000062 ------------------------------------------------------------------ */
63
njnc7561b92005-06-19 01:24:32 +000064#include "pub_core_basics.h"
sewardje66f2e02006-12-30 17:45:08 +000065#include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM
njn93fe3b22005-12-21 20:22:52 +000066#include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF,
67 // VALGRIND_NON_SIMD_CALL[12]
njn16eeb4e2005-06-16 03:56:58 +000068#include "pub_core_debuginfo.h" // needed for pub_core_redir.h :(
njnaf1d7df2005-06-11 01:31:52 +000069#include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
sewardjec92a072006-10-17 01:50:31 +000070#include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_*
njnda325d92005-05-11 18:51:53 +000071#include "pub_core_replacemalloc.h"
sewardj9ee81f52005-04-02 17:38:59 +000072
sewardj3c944452011-09-05 20:39:57 +000073/* Assignment of behavioural equivalence class tags: 1NNNP is intended
sewardjbd2cff22011-08-16 21:45:28 +000074 to be reserved for the Valgrind core. Current usage:
75
sewardj96044842011-08-18 13:09:55 +000076 10010 ALLOC_or_NULL
77 10020 ZONEALLOC_or_NULL
78 10030 ALLOC_or_BOMB
79 10040 ZONEFREE
80 10050 FREE
81 10060 ZONECALLOC
82 10070 CALLOC
83 10080 ZONEREALLOC
84 10090 REALLOC
85 10100 ZONEMEMALIGN
86 10110 MEMALIGN
87 10120 VALLOC
88 10130 ZONEVALLOC
89 10140 MALLOPT
90 10150 MALLOC_TRIM
91 10160 POSIX_MEMALIGN
92 10170 MALLOC_USABLE_SIZE
93 10180 PANIC
94 10190 MALLOC_STATS
95 10200 MALLINFO
96 10210 DEFAULT_ZONE
sewardj7817ee42014-06-25 11:24:16 +000097 10220 CREATE_ZONE
98 10230 ZONE_FROM_PTR
99 10240 ZONE_CHECK
100 10250 ZONE_REGISTER
101 10260 ZONE_UNREGISTER
102 10270 ZONE_SET_NAME
103 10280 ZONE_GET_NAME
sewardjbd2cff22011-08-16 21:45:28 +0000104*/
sewardj9ee81f52005-04-02 17:38:59 +0000105
106/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
107 mangling, could be supported properly by the redirects in this
108 module. Except we can't because it doesn't put its allocation
109 functions in libpgc.so but instead hardwires them into the
110 compilation unit holding main(), which makes them impossible to
111 intercept directly. Fortunately those fns seem to route everything
112 through to malloc/free.
sewardjec92a072006-10-17 01:50:31 +0000113
114 mid-06: could be improved, since we can now intercept in the main
115 executable too.
sewardj9ee81f52005-04-02 17:38:59 +0000116*/
117
sewardj126e82d2011-07-12 13:33:00 +0000118
119
120/* Call here to exit if we can't continue. On Android we can't call
121 _exit for some reason, so we have to blunt-instrument it. */
njn4c245e52009-03-15 23:25:38 +0000122__attribute__ ((__noreturn__))
sewardj126e82d2011-07-12 13:33:00 +0000123static inline void my_exit ( int x )
124{
sewardj26ed4192014-11-04 17:44:21 +0000125# if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
126 || defined(VGPV_arm64_linux_android)
sewardj126e82d2011-07-12 13:33:00 +0000127 __asm__ __volatile__(".word 0xFFFFFFFF");
128 while (1) {}
philippe5d5dd8e2012-08-05 00:08:25 +0000129# elif defined(VGPV_x86_linux_android)
130 __asm__ __volatile__("ud2");
131 while (1) {}
sewardj126e82d2011-07-12 13:33:00 +0000132# else
florian052f5912011-10-05 14:51:55 +0000133 extern __attribute__ ((__noreturn__)) void _exit(int status);
sewardj49665422011-07-12 13:50:59 +0000134 _exit(x);
sewardj126e82d2011-07-12 13:33:00 +0000135# endif
136}
137
138/* Same problem with getpagesize. */
sewardj3c944452011-09-05 20:39:57 +0000139static inline int my_getpagesize ( void )
140{
sewardj26ed4192014-11-04 17:44:21 +0000141# if defined(VGPV_arm_linux_android) \
142 || defined(VGPV_x86_linux_android) \
143 || defined(VGPV_mips32_linux_android) \
144 || defined(VGPV_arm64_linux_android)
sewardj126e82d2011-07-12 13:33:00 +0000145 return 4096; /* kludge - link failure on Android, for some reason */
146# else
147 extern int getpagesize (void);
148 return getpagesize();
149# endif
150}
sewardj9ee81f52005-04-02 17:38:59 +0000151
sewardjec92a072006-10-17 01:50:31 +0000152
sewardj59570ff2010-01-01 11:59:33 +0000153/* Compute the high word of the double-length unsigned product of U
154 and V. This is for calloc argument overflow checking; see comments
155 below. Algorithm as described in Hacker's Delight, chapter 8. */
156static UWord umulHW ( UWord u, UWord v )
157{
158 UWord u0, v0, w0, rHi;
159 UWord u1, v1, w1,w2,t;
160 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF
161 : (UWord)0xFFFFFFFFULL;
162 UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
163 u0 = u & halfMask;
164 u1 = u >> halfShift;
165 v0 = v & halfMask;
166 v1 = v >> halfShift;
167 w0 = u0 * v0;
168 t = u1 * v0 + (w0 >> halfShift);
169 w1 = t & halfMask;
170 w2 = t >> halfShift;
171 w1 = u0 * v1 + w1;
172 rHi = u1 * v1 + w2 + (w1 >> halfShift);
173 return rHi;
174}
175
176
sewardj9ee81f52005-04-02 17:38:59 +0000177/*------------------------------------------------------------*/
178/*--- Replacing malloc() et al ---*/
179/*------------------------------------------------------------*/
180
181/* This struct is initially empty. Before the first use of any of
182 these functions, we make a client request which fills in the
183 fields.
184*/
185static struct vg_mallocfunc_info info;
186static int init_done;
philippecf9e1972013-04-04 21:10:22 +0000187#define DO_INIT if (UNLIKELY(!init_done)) init()
sewardj9ee81f52005-04-02 17:38:59 +0000188
189/* Startup hook - called as init section */
njn2c4e5352009-06-29 05:19:15 +0000190__attribute__((constructor))
191static void init(void);
sewardj9ee81f52005-04-02 17:38:59 +0000192
sewardj9ee81f52005-04-02 17:38:59 +0000193#define MALLOC_TRACE(format, args...) \
njnd2597c22009-05-19 07:56:55 +0000194 if (info.clo_trace_malloc) { \
195 VALGRIND_INTERNAL_PRINTF(format, ## args ); }
sewardj9ee81f52005-04-02 17:38:59 +0000196
sewardj9ee81f52005-04-02 17:38:59 +0000197/* Below are new versions of malloc, __builtin_new, free,
198 __builtin_delete, calloc, realloc, memalign, and friends.
199
200 None of these functions are called directly - they are not meant to
sewardj0ec07f32006-01-12 12:32:32 +0000201 be found by the dynamic linker. But ALL client calls to malloc()
202 and friends wind up here eventually. They get called because
203 vg_replace_malloc installs a bunch of code redirects which causes
204 Valgrind to use these functions rather than the ones they're
205 replacing.
sewardj9ee81f52005-04-02 17:38:59 +0000206*/
207
philippecf9e1972013-04-04 21:10:22 +0000208/* The replacement functions are running on the simulated CPU.
209 The code on the simulated CPU does not necessarily use
210 all arguments. E.g. args can be ignored and/or only given
211 to a NON SIMD call.
212 The definedness of such 'unused' arguments will not be verified
213 by memcheck.
philippe347a4812014-09-01 21:46:52 +0000214 The macro 'TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED' allows
philippecf9e1972013-04-04 21:10:22 +0000215 memcheck to detect such errors for the otherwise unused args.
philippe347a4812014-09-01 21:46:52 +0000216 Apart of allowing memcheck to detect an error, the macro
217 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED has no effect and
philippecf9e1972013-04-04 21:10:22 +0000218 has a minimal cost for other tools replacing malloc functions.
219*/
philippe347a4812014-09-01 21:46:52 +0000220#define TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(x) \
221 if ((ULong)x == 0) __asm__ __volatile__( "" ::: "memory" )
sewardjec92a072006-10-17 01:50:31 +0000222
223/*---------------------- malloc ----------------------*/
224
sewardj9ee81f52005-04-02 17:38:59 +0000225/* Generate a replacement for 'fnname' in object 'soname', which calls
226 'vg_replacement' to allocate memory. If that fails, return NULL.
227*/
228#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
229 \
sewardj96044842011-08-18 13:09:55 +0000230 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
231 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \
sewardj9ee81f52005-04-02 17:38:59 +0000232 { \
233 void* v; \
234 \
philippecf9e1972013-04-04 21:10:22 +0000235 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000236 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
sewardjcf64bd22006-01-19 03:35:37 +0000237 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
sewardj9ee81f52005-04-02 17:38:59 +0000238 \
239 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
njnd55f0d92009-08-03 01:38:56 +0000240 MALLOC_TRACE(" = %p\n", v ); \
sewardj9ee81f52005-04-02 17:38:59 +0000241 return v; \
242 }
243
njnf76d27a2009-05-28 01:53:07 +0000244#define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
245 \
sewardj96044842011-08-18 13:09:55 +0000246 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
247 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \
njnf76d27a2009-05-28 01:53:07 +0000248 { \
249 void* v; \
250 \
philippecf9e1972013-04-04 21:10:22 +0000251 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000252 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
253 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
njnf76d27a2009-05-28 01:53:07 +0000254 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
255 \
256 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
njnd55f0d92009-08-03 01:38:56 +0000257 MALLOC_TRACE(" = %p\n", v ); \
njnf76d27a2009-05-28 01:53:07 +0000258 return v; \
259 }
260
sewardj9ee81f52005-04-02 17:38:59 +0000261
262/* Generate a replacement for 'fnname' in object 'soname', which calls
263 'vg_replacement' to allocate memory. If that fails, it bombs the
264 system.
265*/
266#define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
267 \
sewardj96044842011-08-18 13:09:55 +0000268 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
269 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \
sewardj9ee81f52005-04-02 17:38:59 +0000270 { \
271 void* v; \
272 \
philippecf9e1972013-04-04 21:10:22 +0000273 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000274 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
sewardjcf64bd22006-01-19 03:35:37 +0000275 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
sewardj9ee81f52005-04-02 17:38:59 +0000276 \
277 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
njnd55f0d92009-08-03 01:38:56 +0000278 MALLOC_TRACE(" = %p\n", v ); \
sewardj9ee81f52005-04-02 17:38:59 +0000279 if (NULL == v) { \
tom9cdf9622010-07-30 13:14:11 +0000280 VALGRIND_PRINTF( \
njnd55f0d92009-08-03 01:38:56 +0000281 "new/new[] failed and should throw an exception, but Valgrind\n"); \
282 VALGRIND_PRINTF_BACKTRACE( \
283 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \
sewardj126e82d2011-07-12 13:33:00 +0000284 my_exit(1); \
sewardj9ee81f52005-04-02 17:38:59 +0000285 } \
286 return v; \
287 }
288
289// Each of these lines generates a replacement function:
290// (from_so, from_fn, v's replacement)
philippe1e470b52012-05-11 19:33:46 +0000291// For some lines, we will also define a replacement function
292// whose only purpose is to be a soname synonym place holder
293// that can be replaced using --soname-synonyms.
sewardj9ee81f52005-04-02 17:38:59 +0000294
295// malloc
sewardj3c944452011-09-05 20:39:57 +0000296#if defined(VGO_linux)
297 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
298 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
philippe1e470b52012-05-11 19:33:46 +0000299 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
sewardj3c944452011-09-05 20:39:57 +0000300
301#elif defined(VGO_darwin)
sewardj3c944452011-09-05 20:39:57 +0000302 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
philippe1e470b52012-05-11 19:33:46 +0000303 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
304 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
305 ZONEALLOC_or_NULL(SO_SYN_MALLOC, malloc_zone_malloc, malloc);
sewardj3c944452011-09-05 20:39:57 +0000306
sewardj8eb8bab2015-07-21 14:44:28 +0000307#elif defined(VGO_solaris)
308 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
309 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
310 ALLOC_or_NULL(VG_Z_LIBUMEM_SO_1, malloc, malloc);
311 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
312
sewardjddc00dd2007-11-27 11:42:47 +0000313#endif
sewardj9ee81f52005-04-02 17:38:59 +0000314
sewardja0e16562005-05-05 01:16:24 +0000315
sewardjec92a072006-10-17 01:50:31 +0000316/*---------------------- new ----------------------*/
317
sewardj3c944452011-09-05 20:39:57 +0000318#if defined(VGO_linux)
319 // operator new(unsigned int), not mangled (for gcc 2.96)
320 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
321 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
322 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
323 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
324 // operator new(unsigned int), GNU mangling
325 #if VG_WORDSIZE == 4
326 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
327 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
philippe1e470b52012-05-11 19:33:46 +0000328 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000329 #endif
330 // operator new(unsigned long), GNU mangling
331 #if VG_WORDSIZE == 8
332 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
333 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
philippe1e470b52012-05-11 19:33:46 +0000334 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000335 #endif
sewardj7c1fa872006-05-21 01:52:09 +0000336
sewardj3c944452011-09-05 20:39:57 +0000337#elif defined(VGO_darwin)
338 // operator new(unsigned int), GNU mangling
339 #if VG_WORDSIZE == 4
sewardj731f9cf2011-09-21 08:43:08 +0000340 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
341 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000342 #endif
343 // operator new(unsigned long), GNU mangling
344 #if 1 // FIXME: is this right?
sewardj731f9cf2011-09-21 08:43:08 +0000345 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
346 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000347 #endif
sewardj7c1fa872006-05-21 01:52:09 +0000348
sewardj8eb8bab2015-07-21 14:44:28 +0000349#elif defined(VGO_solaris)
350 // operator new(unsigned int), GNU mangling
351 #if VG_WORDSIZE == 4
352 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
353 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new);
354 #endif
355 // operator new(unsigned long), GNU mangling
356 #if VG_WORDSIZE == 8
357 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
358 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new);
359 #endif
360
sewardjec92a072006-10-17 01:50:31 +0000361#endif
362
sewardj9b3328d2005-04-24 00:04:42 +0000363
sewardjec92a072006-10-17 01:50:31 +0000364/*---------------------- new nothrow ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +0000365
sewardj3c944452011-09-05 20:39:57 +0000366#if defined(VGO_linux)
367 // operator new(unsigned, std::nothrow_t const&), GNU mangling
368 #if VG_WORDSIZE == 4
369 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
370 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
philippe1e470b52012-05-11 19:33:46 +0000371 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000372 #endif
373 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
374 #if VG_WORDSIZE == 8
375 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
376 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
philippe1e470b52012-05-11 19:33:46 +0000377 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000378 #endif
tomf91889f2005-05-04 18:01:26 +0000379
sewardj3c944452011-09-05 20:39:57 +0000380#elif defined(VGO_darwin)
381 // operator new(unsigned, std::nothrow_t const&), GNU mangling
382 #if VG_WORDSIZE == 4
sewardj731f9cf2011-09-21 08:43:08 +0000383 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
384 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000385 #endif
386 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
387 #if 1 // FIXME: is this right?
sewardj731f9cf2011-09-21 08:43:08 +0000388 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
389 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
sewardj3c944452011-09-05 20:39:57 +0000390 #endif
391
sewardj8eb8bab2015-07-21 14:44:28 +0000392#elif defined(VGO_solaris)
393 // operator new(unsigned, std::nothrow_t const&), GNU mangling
394 #if VG_WORDSIZE == 4
395 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
396 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new);
397 #endif
398 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
399 #if VG_WORDSIZE == 8
400 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
401 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new);
402 #endif
403
sewardjec92a072006-10-17 01:50:31 +0000404#endif
405
sewardjec92a072006-10-17 01:50:31 +0000406
407/*---------------------- new [] ----------------------*/
sewardja0e16562005-05-05 01:16:24 +0000408
sewardj3c944452011-09-05 20:39:57 +0000409#if defined(VGO_linux)
410 // operator new[](unsigned int), not mangled (for gcc 2.96)
411 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
412 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
413 // operator new[](unsigned int), GNU mangling
414 #if VG_WORDSIZE == 4
415 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
416 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
philippe1e470b52012-05-11 19:33:46 +0000417 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000418 #endif
419 // operator new[](unsigned long), GNU mangling
420 #if VG_WORDSIZE == 8
421 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
422 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
philippe1e470b52012-05-11 19:33:46 +0000423 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000424 #endif
sewardj7c1fa872006-05-21 01:52:09 +0000425
sewardj3c944452011-09-05 20:39:57 +0000426#elif defined(VGO_darwin)
427 // operator new[](unsigned int), GNU mangling
428 #if VG_WORDSIZE == 4
sewardj731f9cf2011-09-21 08:43:08 +0000429 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
430 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000431 #endif
432 // operator new[](unsigned long), GNU mangling
433 #if 1 // FIXME: is this right?
sewardj731f9cf2011-09-21 08:43:08 +0000434 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
435 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000436 #endif
sewardjec92a072006-10-17 01:50:31 +0000437
sewardj8eb8bab2015-07-21 14:44:28 +0000438#elif defined(VGO_solaris)
439 // operator new[](unsigned int), GNU mangling
440 #if VG_WORDSIZE == 4
441 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
442 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new );
443 #endif
444 // operator new[](unsigned long), GNU mangling
445 #if VG_WORDSIZE == 8
446 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
447 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new );
448 #endif
449
sewardjec92a072006-10-17 01:50:31 +0000450#endif
451
sewardj9ee81f52005-04-02 17:38:59 +0000452
sewardjec92a072006-10-17 01:50:31 +0000453/*---------------------- new [] nothrow ----------------------*/
454
sewardj3c944452011-09-05 20:39:57 +0000455#if defined(VGO_linux)
456 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
457 #if VG_WORDSIZE == 4
458 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
459 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
philippe1e470b52012-05-11 19:33:46 +0000460 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000461 #endif
462 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
463 #if VG_WORDSIZE == 8
464 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
465 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
philippe1e470b52012-05-11 19:33:46 +0000466 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000467 #endif
tomf91889f2005-05-04 18:01:26 +0000468
sewardj3c944452011-09-05 20:39:57 +0000469#elif defined(VGO_darwin)
470 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
471 #if VG_WORDSIZE == 4
sewardj731f9cf2011-09-21 08:43:08 +0000472 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
473 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000474 #endif
475 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
476 #if 1 // FIXME: is this right?
sewardj731f9cf2011-09-21 08:43:08 +0000477 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
478 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
sewardj3c944452011-09-05 20:39:57 +0000479 #endif
480
sewardj8eb8bab2015-07-21 14:44:28 +0000481#elif defined(VGO_solaris)
482 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
483 #if VG_WORDSIZE == 4
484 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
485 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new );
486 #endif
487 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
488 #if VG_WORDSIZE == 8
489 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
490 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new );
491 #endif
492
sewardjec92a072006-10-17 01:50:31 +0000493#endif
494
sewardjec92a072006-10-17 01:50:31 +0000495
496/*---------------------- free ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +0000497
498/* Generate a replacement for 'fnname' in object 'soname', which calls
499 'vg_replacement' to free previously allocated memory.
500*/
njnf76d27a2009-05-28 01:53:07 +0000501#define ZONEFREE(soname, fnname, vg_replacement) \
502 \
sewardj96044842011-08-18 13:09:55 +0000503 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
504 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
njnf76d27a2009-05-28 01:53:07 +0000505 { \
philippecf9e1972013-04-04 21:10:22 +0000506 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000507 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
sewardj731f9cf2011-09-21 08:43:08 +0000508 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
njnf76d27a2009-05-28 01:53:07 +0000509 if (p == NULL) \
510 return; \
511 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
512 }
513
sewardj9ee81f52005-04-02 17:38:59 +0000514#define FREE(soname, fnname, vg_replacement) \
515 \
sewardj96044842011-08-18 13:09:55 +0000516 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
517 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
sewardj9ee81f52005-04-02 17:38:59 +0000518 { \
philippecf9e1972013-04-04 21:10:22 +0000519 DO_INIT; \
sewardj731f9cf2011-09-21 08:43:08 +0000520 MALLOC_TRACE(#fnname "(%p)\n", p ); \
sewardj9ee81f52005-04-02 17:38:59 +0000521 if (p == NULL) \
522 return; \
sewardj9ee81f52005-04-02 17:38:59 +0000523 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
524 }
525
philippe1e470b52012-05-11 19:33:46 +0000526
sewardj3c944452011-09-05 20:39:57 +0000527#if defined(VGO_linux)
528 FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
529 FREE(VG_Z_LIBC_SONAME, free, free );
philippe1e470b52012-05-11 19:33:46 +0000530 FREE(SO_SYN_MALLOC, free, free );
sewardj3c944452011-09-05 20:39:57 +0000531
532#elif defined(VGO_darwin)
sewardj3c944452011-09-05 20:39:57 +0000533 FREE(VG_Z_LIBC_SONAME, free, free );
philippe1e470b52012-05-11 19:33:46 +0000534 FREE(SO_SYN_MALLOC, free, free );
sewardj3c944452011-09-05 20:39:57 +0000535 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
philippe1e470b52012-05-11 19:33:46 +0000536 ZONEFREE(SO_SYN_MALLOC, malloc_zone_free, free );
sewardj3c944452011-09-05 20:39:57 +0000537
sewardj8eb8bab2015-07-21 14:44:28 +0000538#elif defined(VGO_solaris)
539 FREE(VG_Z_LIBC_SONAME, free, free );
540 FREE(VG_Z_LIBUMEM_SO_1, free, free );
541 FREE(SO_SYN_MALLOC, free, free );
542
sewardjddc00dd2007-11-27 11:42:47 +0000543#endif
sewardjec92a072006-10-17 01:50:31 +0000544
545
546/*---------------------- cfree ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +0000547
548// cfree
sewardj3c944452011-09-05 20:39:57 +0000549#if defined(VGO_linux)
550 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
551 FREE(VG_Z_LIBC_SONAME, cfree, free );
philippe1e470b52012-05-11 19:33:46 +0000552 FREE(SO_SYN_MALLOC, cfree, free );
sewardj3c944452011-09-05 20:39:57 +0000553
554#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +0000555 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
556 //FREE(VG_Z_LIBC_SONAME, cfree, free );
sewardj3c944452011-09-05 20:39:57 +0000557
sewardj8eb8bab2015-07-21 14:44:28 +0000558#elif defined(VGO_solaris)
559 FREE(VG_Z_LIBC_SONAME, cfree, free );
560 /* libumem does not implement cfree(). */
561 //FREE(VG_Z_LIBUMEM_SO_1, cfree, free );
562 FREE(SO_SYN_MALLOC, cfree, free );
563
sewardj3c944452011-09-05 20:39:57 +0000564#endif
sewardj9ee81f52005-04-02 17:38:59 +0000565
sewardjec92a072006-10-17 01:50:31 +0000566
567/*---------------------- delete ----------------------*/
sewardj7c1fa872006-05-21 01:52:09 +0000568
sewardj3c944452011-09-05 20:39:57 +0000569#if defined(VGO_linux)
570 // operator delete(void*), not mangled (for gcc 2.96)
571 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
572 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
573 // operator delete(void*), GNU mangling
574 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
575 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
philippe1e470b52012-05-11 19:33:46 +0000576 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete );
sewardj3c944452011-09-05 20:39:57 +0000577
578#elif defined(VGO_darwin)
579 // operator delete(void*), GNU mangling
sewardj731f9cf2011-09-21 08:43:08 +0000580 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
581 //FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
sewardj3c944452011-09-05 20:39:57 +0000582
sewardj8eb8bab2015-07-21 14:44:28 +0000583#elif defined(VGO_solaris)
584 // operator delete(void*), GNU mangling
585 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
586 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete );
587
sewardj3c944452011-09-05 20:39:57 +0000588#endif
sewardjec92a072006-10-17 01:50:31 +0000589
sewardjec92a072006-10-17 01:50:31 +0000590
591/*---------------------- delete nothrow ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +0000592
sewardj3c944452011-09-05 20:39:57 +0000593#if defined(VGO_linux)
594 // operator delete(void*, std::nothrow_t const&), GNU mangling
595 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
596 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
philippe1e470b52012-05-11 19:33:46 +0000597 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete );
sewardj3c944452011-09-05 20:39:57 +0000598
599#elif defined(VGO_darwin)
600 // operator delete(void*, std::nothrow_t const&), GNU mangling
sewardj731f9cf2011-09-21 08:43:08 +0000601 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
602 //FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
sewardj3c944452011-09-05 20:39:57 +0000603
sewardj8eb8bab2015-07-21 14:44:28 +0000604#elif defined(VGO_solaris)
605 // operator delete(void*, std::nothrow_t const&), GNU mangling
606 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
607 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete );
608
sewardj3c944452011-09-05 20:39:57 +0000609#endif
sewardj9ee81f52005-04-02 17:38:59 +0000610
sewardjec92a072006-10-17 01:50:31 +0000611
612/*---------------------- delete [] ----------------------*/
sewardj7c1fa872006-05-21 01:52:09 +0000613
sewardj3c944452011-09-05 20:39:57 +0000614#if defined(VGO_linux)
615 // operator delete[](void*), not mangled (for gcc 2.96)
616 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
617 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
618 // operator delete[](void*), GNU mangling
619 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
620 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
philippe1e470b52012-05-11 19:33:46 +0000621 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete );
sewardj3c944452011-09-05 20:39:57 +0000622
623#elif defined(VGO_darwin)
624 // operator delete[](void*), not mangled (for gcc 2.96)
sewardj731f9cf2011-09-21 08:43:08 +0000625 //FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
626 //FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
sewardj3c944452011-09-05 20:39:57 +0000627 // operator delete[](void*), GNU mangling
sewardj731f9cf2011-09-21 08:43:08 +0000628 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
629 //FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
sewardj3c944452011-09-05 20:39:57 +0000630
sewardj8eb8bab2015-07-21 14:44:28 +0000631#elif defined(VGO_solaris)
632 // operator delete[](void*), GNU mangling
633 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
634 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete );
635
sewardj3c944452011-09-05 20:39:57 +0000636#endif
sewardjec92a072006-10-17 01:50:31 +0000637
sewardjec92a072006-10-17 01:50:31 +0000638
639/*---------------------- delete [] nothrow ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +0000640
sewardj3c944452011-09-05 20:39:57 +0000641#if defined(VGO_linux)
642 // operator delete[](void*, std::nothrow_t const&), GNU mangling
643 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
644 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
philippe1e470b52012-05-11 19:33:46 +0000645 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
sewardj3c944452011-09-05 20:39:57 +0000646
647#elif defined(VGO_darwin)
648 // operator delete[](void*, std::nothrow_t const&), GNU mangling
sewardj731f9cf2011-09-21 08:43:08 +0000649 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
650 //FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
sewardj3c944452011-09-05 20:39:57 +0000651
sewardj8eb8bab2015-07-21 14:44:28 +0000652#elif defined(VGO_solaris)
653 // operator delete[](void*, std::nothrow_t const&), GNU mangling
654 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
655 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
656
sewardj3c944452011-09-05 20:39:57 +0000657#endif
sewardj9ee81f52005-04-02 17:38:59 +0000658
659
sewardjec92a072006-10-17 01:50:31 +0000660/*---------------------- calloc ----------------------*/
661
njnf76d27a2009-05-28 01:53:07 +0000662#define ZONECALLOC(soname, fnname) \
663 \
sewardj96044842011-08-18 13:09:55 +0000664 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000665 ( void *zone, SizeT nmemb, SizeT size ); \
sewardj96044842011-08-18 13:09:55 +0000666 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000667 ( void *zone, SizeT nmemb, SizeT size ) \
njnf76d27a2009-05-28 01:53:07 +0000668 { \
669 void* v; \
670 \
philippecf9e1972013-04-04 21:10:22 +0000671 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000672 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
673 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \
674 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
sewardj731f9cf2011-09-21 08:43:08 +0000675 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
njnf76d27a2009-05-28 01:53:07 +0000676 \
677 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
njnd55f0d92009-08-03 01:38:56 +0000678 MALLOC_TRACE(" = %p\n", v ); \
njnf76d27a2009-05-28 01:53:07 +0000679 return v; \
680 }
681
sewardj9ee81f52005-04-02 17:38:59 +0000682#define CALLOC(soname, fnname) \
683 \
sewardj96044842011-08-18 13:09:55 +0000684 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000685 ( SizeT nmemb, SizeT size ); \
sewardj96044842011-08-18 13:09:55 +0000686 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000687 ( SizeT nmemb, SizeT size ) \
sewardj9ee81f52005-04-02 17:38:59 +0000688 { \
689 void* v; \
690 \
philippecf9e1972013-04-04 21:10:22 +0000691 DO_INIT; \
sewardj9ee81f52005-04-02 17:38:59 +0000692 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
sewardj9ee81f52005-04-02 17:38:59 +0000693 \
sewardj59570ff2010-01-01 11:59:33 +0000694 /* Protect against overflow. See bug 24078. (that bug number is
695 invalid. Which one really?) */ \
696 /* But don't use division, since that produces an external symbol
697 reference on ARM, in the form of a call to __aeabi_uidiv. It's
698 normally OK, because ld.so manages to resolve it to something in the
699 executable, or one of its shared objects. But that isn't guaranteed
700 to be the case, and it has been observed to fail in rare cases, eg:
701 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
702 So instead compute the high word of the product and check it is zero. */ \
703 if (umulHW(size, nmemb) != 0) return NULL; \
sewardj9ee81f52005-04-02 17:38:59 +0000704 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
njnd55f0d92009-08-03 01:38:56 +0000705 MALLOC_TRACE(" = %p\n", v ); \
sewardj9ee81f52005-04-02 17:38:59 +0000706 return v; \
707 }
708
sewardj3c944452011-09-05 20:39:57 +0000709#if defined(VGO_linux)
710 CALLOC(VG_Z_LIBC_SONAME, calloc);
philippe1e470b52012-05-11 19:33:46 +0000711 CALLOC(SO_SYN_MALLOC, calloc);
sewardj3c944452011-09-05 20:39:57 +0000712
713#elif defined(VGO_darwin)
714 CALLOC(VG_Z_LIBC_SONAME, calloc);
philippe1e470b52012-05-11 19:33:46 +0000715 CALLOC(SO_SYN_MALLOC, calloc);
sewardj3c944452011-09-05 20:39:57 +0000716 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
philippe1e470b52012-05-11 19:33:46 +0000717 ZONECALLOC(SO_SYN_MALLOC, malloc_zone_calloc);
sewardj3c944452011-09-05 20:39:57 +0000718
sewardj8eb8bab2015-07-21 14:44:28 +0000719#elif defined(VGO_solaris)
720 CALLOC(VG_Z_LIBC_SONAME, calloc);
721 CALLOC(VG_Z_LIBUMEM_SO_1, calloc);
722 CALLOC(SO_SYN_MALLOC, calloc);
723
sewardjddc00dd2007-11-27 11:42:47 +0000724#endif
sewardj9ee81f52005-04-02 17:38:59 +0000725
726
sewardjec92a072006-10-17 01:50:31 +0000727/*---------------------- realloc ----------------------*/
728
njnf76d27a2009-05-28 01:53:07 +0000729#define ZONEREALLOC(soname, fnname) \
730 \
sewardj96044842011-08-18 13:09:55 +0000731 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000732 ( void *zone, void* ptrV, SizeT new_size ); \
sewardj96044842011-08-18 13:09:55 +0000733 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000734 ( void *zone, void* ptrV, SizeT new_size ) \
njnf76d27a2009-05-28 01:53:07 +0000735 { \
736 void* v; \
737 \
philippecf9e1972013-04-04 21:10:22 +0000738 DO_INIT; \
sewardj731f9cf2011-09-21 08:43:08 +0000739 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
njnf76d27a2009-05-28 01:53:07 +0000740 \
741 if (ptrV == NULL) \
742 /* We need to call a malloc-like function; so let's use \
743 one which we know exists. GrP fixme use zonemalloc instead? */ \
sewardj96044842011-08-18 13:09:55 +0000744 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
sewardj76967262011-08-16 22:31:45 +0000745 (new_size); \
njnf76d27a2009-05-28 01:53:07 +0000746 if (new_size <= 0) { \
sewardj96044842011-08-18 13:09:55 +0000747 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
njnd55f0d92009-08-03 01:38:56 +0000748 MALLOC_TRACE(" = 0\n"); \
njnf76d27a2009-05-28 01:53:07 +0000749 return NULL; \
750 } \
751 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
njnd55f0d92009-08-03 01:38:56 +0000752 MALLOC_TRACE(" = %p\n", v ); \
njnf76d27a2009-05-28 01:53:07 +0000753 return v; \
754 }
755
sewardj9ee81f52005-04-02 17:38:59 +0000756#define REALLOC(soname, fnname) \
757 \
sewardj96044842011-08-18 13:09:55 +0000758 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000759 ( void* ptrV, SizeT new_size );\
sewardj96044842011-08-18 13:09:55 +0000760 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000761 ( void* ptrV, SizeT new_size ) \
sewardj9ee81f52005-04-02 17:38:59 +0000762 { \
763 void* v; \
764 \
philippecf9e1972013-04-04 21:10:22 +0000765 DO_INIT; \
sewardj9ee81f52005-04-02 17:38:59 +0000766 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
sewardj9ee81f52005-04-02 17:38:59 +0000767 \
768 if (ptrV == NULL) \
769 /* We need to call a malloc-like function; so let's use \
770 one which we know exists. */ \
sewardj96044842011-08-18 13:09:55 +0000771 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
sewardjbd2cff22011-08-16 21:45:28 +0000772 (new_size); \
sewardj9ee81f52005-04-02 17:38:59 +0000773 if (new_size <= 0) { \
sewardj96044842011-08-18 13:09:55 +0000774 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
njnd55f0d92009-08-03 01:38:56 +0000775 MALLOC_TRACE(" = 0\n"); \
sewardj9ee81f52005-04-02 17:38:59 +0000776 return NULL; \
777 } \
sewardj9ee81f52005-04-02 17:38:59 +0000778 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
njnd55f0d92009-08-03 01:38:56 +0000779 MALLOC_TRACE(" = %p\n", v ); \
sewardj9ee81f52005-04-02 17:38:59 +0000780 return v; \
781 }
782
sewardj3c944452011-09-05 20:39:57 +0000783#if defined(VGO_linux)
784 REALLOC(VG_Z_LIBC_SONAME, realloc);
philippe1e470b52012-05-11 19:33:46 +0000785 REALLOC(SO_SYN_MALLOC, realloc);
sewardj3c944452011-09-05 20:39:57 +0000786
787#elif defined(VGO_darwin)
788 REALLOC(VG_Z_LIBC_SONAME, realloc);
philippe1e470b52012-05-11 19:33:46 +0000789 REALLOC(SO_SYN_MALLOC, realloc);
sewardj3c944452011-09-05 20:39:57 +0000790 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
philippe1e470b52012-05-11 19:33:46 +0000791 ZONEREALLOC(SO_SYN_MALLOC, malloc_zone_realloc);
sewardj3c944452011-09-05 20:39:57 +0000792
sewardj8eb8bab2015-07-21 14:44:28 +0000793#elif defined(VGO_solaris)
794 REALLOC(VG_Z_LIBC_SONAME, realloc);
795 REALLOC(VG_Z_LIBUMEM_SO_1, realloc);
796 REALLOC(SO_SYN_MALLOC, realloc);
797
sewardjddc00dd2007-11-27 11:42:47 +0000798#endif
sewardj9ee81f52005-04-02 17:38:59 +0000799
800
sewardjec92a072006-10-17 01:50:31 +0000801/*---------------------- memalign ----------------------*/
802
njnf76d27a2009-05-28 01:53:07 +0000803#define ZONEMEMALIGN(soname, fnname) \
804 \
sewardj96044842011-08-18 13:09:55 +0000805 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000806 ( void *zone, SizeT alignment, SizeT n ); \
sewardj96044842011-08-18 13:09:55 +0000807 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000808 ( void *zone, SizeT alignment, SizeT n ) \
njnf76d27a2009-05-28 01:53:07 +0000809 { \
810 void* v; \
811 \
philippecf9e1972013-04-04 21:10:22 +0000812 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000813 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
814 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
sewardj731f9cf2011-09-21 08:43:08 +0000815 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
njnf76d27a2009-05-28 01:53:07 +0000816 zone, (ULong)alignment, (ULong)n ); \
817 \
818 /* Round up to minimum alignment if necessary. */ \
819 if (alignment < VG_MIN_MALLOC_SZB) \
820 alignment = VG_MIN_MALLOC_SZB; \
821 \
822 /* Round up to nearest power-of-two if necessary (like glibc). */ \
823 while (0 != (alignment & (alignment - 1))) alignment++; \
824 \
825 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
njnd55f0d92009-08-03 01:38:56 +0000826 MALLOC_TRACE(" = %p\n", v ); \
njnf76d27a2009-05-28 01:53:07 +0000827 return v; \
828 }
829
sewardj9ee81f52005-04-02 17:38:59 +0000830#define MEMALIGN(soname, fnname) \
831 \
sewardj96044842011-08-18 13:09:55 +0000832 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000833 ( SizeT alignment, SizeT n ); \
sewardj96044842011-08-18 13:09:55 +0000834 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000835 ( SizeT alignment, SizeT n ) \
sewardj9ee81f52005-04-02 17:38:59 +0000836 { \
837 void* v; \
838 \
philippecf9e1972013-04-04 21:10:22 +0000839 DO_INIT; \
philippe347a4812014-09-01 21:46:52 +0000840 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
sewardj9ee81f52005-04-02 17:38:59 +0000841 MALLOC_TRACE("memalign(al %llu, size %llu)", \
842 (ULong)alignment, (ULong)n ); \
sewardj9ee81f52005-04-02 17:38:59 +0000843 \
844 /* Round up to minimum alignment if necessary. */ \
845 if (alignment < VG_MIN_MALLOC_SZB) \
846 alignment = VG_MIN_MALLOC_SZB; \
847 \
848 /* Round up to nearest power-of-two if necessary (like glibc). */ \
849 while (0 != (alignment & (alignment - 1))) alignment++; \
850 \
sewardj9ee81f52005-04-02 17:38:59 +0000851 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
njnd55f0d92009-08-03 01:38:56 +0000852 MALLOC_TRACE(" = %p\n", v ); \
sewardj9ee81f52005-04-02 17:38:59 +0000853 return v; \
854 }
855
sewardj3c944452011-09-05 20:39:57 +0000856#if defined(VGO_linux)
857 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
philippe1e470b52012-05-11 19:33:46 +0000858 MEMALIGN(SO_SYN_MALLOC, memalign);
sewardj3c944452011-09-05 20:39:57 +0000859
860#elif defined(VGO_darwin)
861 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
philippe1e470b52012-05-11 19:33:46 +0000862 MEMALIGN(SO_SYN_MALLOC, memalign);
sewardj3c944452011-09-05 20:39:57 +0000863 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
philippe1e470b52012-05-11 19:33:46 +0000864 ZONEMEMALIGN(SO_SYN_MALLOC, malloc_zone_memalign);
sewardj3c944452011-09-05 20:39:57 +0000865
sewardj8eb8bab2015-07-21 14:44:28 +0000866#elif defined(VGO_solaris)
867 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
868 MEMALIGN(VG_Z_LIBUMEM_SO_1, memalign);
869 MEMALIGN(SO_SYN_MALLOC, memalign);
870
njnf76d27a2009-05-28 01:53:07 +0000871#endif
sewardj9ee81f52005-04-02 17:38:59 +0000872
873
sewardjec92a072006-10-17 01:50:31 +0000874/*---------------------- valloc ----------------------*/
875
sewardj9ee81f52005-04-02 17:38:59 +0000876#define VALLOC(soname, fnname) \
877 \
sewardj96044842011-08-18 13:09:55 +0000878 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
879 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
sewardj9ee81f52005-04-02 17:38:59 +0000880 { \
sewardje66f2e02006-12-30 17:45:08 +0000881 static int pszB = 0; \
sewardje66f2e02006-12-30 17:45:08 +0000882 if (pszB == 0) \
sewardj126e82d2011-07-12 13:33:00 +0000883 pszB = my_getpagesize(); \
sewardj96044842011-08-18 13:09:55 +0000884 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
sewardje66f2e02006-12-30 17:45:08 +0000885 ((SizeT)pszB, size); \
sewardj9ee81f52005-04-02 17:38:59 +0000886 }
887
njnf76d27a2009-05-28 01:53:07 +0000888#define ZONEVALLOC(soname, fnname) \
889 \
sewardj96044842011-08-18 13:09:55 +0000890 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000891 ( void *zone, SizeT size ); \
sewardj96044842011-08-18 13:09:55 +0000892 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000893 ( void *zone, SizeT size ) \
njnf76d27a2009-05-28 01:53:07 +0000894 { \
895 static int pszB = 0; \
njnf76d27a2009-05-28 01:53:07 +0000896 if (pszB == 0) \
sewardj126e82d2011-07-12 13:33:00 +0000897 pszB = my_getpagesize(); \
sewardjef934632014-09-01 22:37:57 +0000898 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
sewardj96044842011-08-18 13:09:55 +0000899 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
njnf76d27a2009-05-28 01:53:07 +0000900 ((SizeT)pszB, size); \
901 }
902
sewardj3c944452011-09-05 20:39:57 +0000903#if defined(VGO_linux)
904 VALLOC(VG_Z_LIBC_SONAME, valloc);
philippe1e470b52012-05-11 19:33:46 +0000905 VALLOC(SO_SYN_MALLOC, valloc);
sewardj3c944452011-09-05 20:39:57 +0000906
907#elif defined(VGO_darwin)
908 VALLOC(VG_Z_LIBC_SONAME, valloc);
philippe1e470b52012-05-11 19:33:46 +0000909 VALLOC(SO_SYN_MALLOC, valloc);
sewardj3c944452011-09-05 20:39:57 +0000910 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
philippe1e470b52012-05-11 19:33:46 +0000911 ZONEVALLOC(SO_SYN_MALLOC, malloc_zone_valloc);
sewardj3c944452011-09-05 20:39:57 +0000912
sewardj8eb8bab2015-07-21 14:44:28 +0000913#elif defined(VGO_solaris)
914 VALLOC(VG_Z_LIBC_SONAME, valloc);
915 VALLOC(VG_Z_LIBUMEM_SO_1, valloc);
916 VALLOC(SO_SYN_MALLOC, valloc);
917
njnf76d27a2009-05-28 01:53:07 +0000918#endif
sewardj9ee81f52005-04-02 17:38:59 +0000919
920
sewardjec92a072006-10-17 01:50:31 +0000921/*---------------------- mallopt ----------------------*/
922
sewardj9ee81f52005-04-02 17:38:59 +0000923/* Various compatibility wrapper functions, for glibc and libstdc++. */
924
925#define MALLOPT(soname, fnname) \
926 \
sewardj96044842011-08-18 13:09:55 +0000927 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
928 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
sewardj9ee81f52005-04-02 17:38:59 +0000929 { \
930 /* In glibc-2.2.4, 1 denotes a successful return value for \
931 mallopt */ \
philippe347a4812014-09-01 21:46:52 +0000932 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
933 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
sewardj9ee81f52005-04-02 17:38:59 +0000934 return 1; \
935 }
936
sewardj3c944452011-09-05 20:39:57 +0000937#if defined(VGO_linux)
938 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
philippe1e470b52012-05-11 19:33:46 +0000939 MALLOPT(SO_SYN_MALLOC, mallopt);
sewardj3c944452011-09-05 20:39:57 +0000940
941#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +0000942 //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
sewardj3c944452011-09-05 20:39:57 +0000943
944#endif
sewardj9ee81f52005-04-02 17:38:59 +0000945
946
sewardjec92a072006-10-17 01:50:31 +0000947/*---------------------- malloc_trim ----------------------*/
njnceb02662006-07-08 08:29:20 +0000948// Documentation says:
949// malloc_trim(size_t pad);
950//
951// If possible, gives memory back to the system (via negative arguments to
952// sbrk) if there is unused memory at the `high' end of the malloc pool.
953// You can call this after freeing large blocks of memory to potentially
954// reduce the system-level memory requirements of a program. However, it
955// cannot guarantee to reduce memory. Under some allocation patterns,
956// some large free blocks of memory will be locked between two used
957// chunks, so they cannot be given back to the system.
958//
959// The `pad' argument to malloc_trim represents the amount of free
960// trailing space to leave untrimmed. If this argument is zero, only the
961// minimum amount of memory to maintain internal data structures will be
962// left (one page or less). Non-zero arguments can be supplied to maintain
963// enough trailing space to service future expected allocations without
964// having to re-obtain memory from the system.
965//
966// Malloc_trim returns 1 if it actually released any memory, else 0. On
967// systems that do not support "negative sbrks", it will always return 0.
968//
969// For simplicity, we always return 0.
970#define MALLOC_TRIM(soname, fnname) \
971 \
sewardj96044842011-08-18 13:09:55 +0000972 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
973 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
njnceb02662006-07-08 08:29:20 +0000974 { \
975 /* 0 denotes that malloc_trim() either wasn't able \
976 to do anything, or was not implemented */ \
philippe347a4812014-09-01 21:46:52 +0000977 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(pad); \
njnceb02662006-07-08 08:29:20 +0000978 return 0; \
979 }
980
sewardj3c944452011-09-05 20:39:57 +0000981#if defined(VGO_linux)
982 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
philippe1e470b52012-05-11 19:33:46 +0000983 MALLOC_TRIM(SO_SYN_MALLOC, malloc_trim);
sewardj3c944452011-09-05 20:39:57 +0000984
985#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +0000986 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
sewardj3c944452011-09-05 20:39:57 +0000987
988#endif
njnceb02662006-07-08 08:29:20 +0000989
990
sewardjec92a072006-10-17 01:50:31 +0000991/*---------------------- posix_memalign ----------------------*/
992
sewardj9ee81f52005-04-02 17:38:59 +0000993#define POSIX_MEMALIGN(soname, fnname) \
994 \
sewardj96044842011-08-18 13:09:55 +0000995 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000996 ( void **memptr, SizeT alignment, SizeT size ); \
sewardj96044842011-08-18 13:09:55 +0000997 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
sewardjbd2cff22011-08-16 21:45:28 +0000998 ( void **memptr, SizeT alignment, SizeT size ) \
sewardj9ee81f52005-04-02 17:38:59 +0000999 { \
1000 void *mem; \
1001 \
1002 /* Test whether the alignment argument is valid. It must be \
1003 a power of two multiple of sizeof (void *). */ \
1004 if (alignment % sizeof (void *) != 0 \
1005 || (alignment & (alignment - 1)) != 0) \
1006 return VKI_EINVAL; \
1007 \
sewardj96044842011-08-18 13:09:55 +00001008 mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
sewardjbd2cff22011-08-16 21:45:28 +00001009 (alignment, size); \
sewardj9ee81f52005-04-02 17:38:59 +00001010 \
1011 if (mem != NULL) { \
1012 *memptr = mem; \
1013 return 0; \
1014 } \
1015 \
1016 return VKI_ENOMEM; \
1017 }
1018
sewardj3c944452011-09-05 20:39:57 +00001019#if defined(VGO_linux)
1020 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
philippe1e470b52012-05-11 19:33:46 +00001021 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign);
sewardj3c944452011-09-05 20:39:57 +00001022
1023#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +00001024 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
sewardj3c944452011-09-05 20:39:57 +00001025
sewardj8eb8bab2015-07-21 14:44:28 +00001026#elif defined(VGO_solaris)
1027 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1028 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign);
1029
sewardj3c944452011-09-05 20:39:57 +00001030#endif
sewardj9ee81f52005-04-02 17:38:59 +00001031
1032
sewardjec92a072006-10-17 01:50:31 +00001033/*---------------------- malloc_usable_size ----------------------*/
1034
sewardj9ee81f52005-04-02 17:38:59 +00001035#define MALLOC_USABLE_SIZE(soname, fnname) \
1036 \
sewardj96044842011-08-18 13:09:55 +00001037 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
1038 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
sewardj9ee81f52005-04-02 17:38:59 +00001039 { \
1040 SizeT pszB; \
1041 \
philippecf9e1972013-04-04 21:10:22 +00001042 DO_INIT; \
sewardj9ee81f52005-04-02 17:38:59 +00001043 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
1044 if (NULL == p) \
1045 return 0; \
1046 \
njn8b140de2009-02-17 04:31:18 +00001047 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
njnd55f0d92009-08-03 01:38:56 +00001048 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
sewardj9ee81f52005-04-02 17:38:59 +00001049 \
1050 return pszB; \
1051 }
1052
sewardj3c944452011-09-05 20:39:57 +00001053#if defined(VGO_linux)
1054 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
philippe1e470b52012-05-11 19:33:46 +00001055 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_usable_size);
sewardj3c944452011-09-05 20:39:57 +00001056 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
philippe1e470b52012-05-11 19:33:46 +00001057 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
dejanj9c6b05d2013-12-27 09:06:55 +00001058# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
1059 || defined(VGPV_mips32_linux_android)
sewardjcce48f82012-04-11 08:46:53 +00001060 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
philippe1e470b52012-05-11 19:33:46 +00001061 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, dlmalloc_usable_size);
sewardjcce48f82012-04-11 08:46:53 +00001062# endif
sewardj3c944452011-09-05 20:39:57 +00001063
1064#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +00001065 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
sewardj3c944452011-09-05 20:39:57 +00001066 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
philippe1e470b52012-05-11 19:33:46 +00001067 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
sewardj3c944452011-09-05 20:39:57 +00001068
1069#endif
sewardj9ee81f52005-04-02 17:38:59 +00001070
1071
sewardjec92a072006-10-17 01:50:31 +00001072/*---------------------- (unimplemented) ----------------------*/
1073
sewardj9ee81f52005-04-02 17:38:59 +00001074/* Bomb out if we get any of these. */
1075
sewardj8eb8bab2015-07-21 14:44:28 +00001076static void panic(const char *str) __attribute__((unused));
sewardj9ee81f52005-04-02 17:38:59 +00001077static void panic(const char *str)
1078{
njnd55f0d92009-08-03 01:38:56 +00001079 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
florian77ae9992015-08-09 20:29:18 +00001080 my_exit(1);
sewardj9ee81f52005-04-02 17:38:59 +00001081}
1082
1083#define PANIC(soname, fnname) \
1084 \
sewardj96044842011-08-18 13:09:55 +00001085 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
1086 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
sewardj9ee81f52005-04-02 17:38:59 +00001087 { \
1088 panic(#fnname); \
1089 }
1090
sewardj3c944452011-09-05 20:39:57 +00001091#if defined(VGO_linux)
1092 PANIC(VG_Z_LIBC_SONAME, pvalloc);
1093 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1094 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1095
1096#elif defined(VGO_darwin)
1097 PANIC(VG_Z_LIBC_SONAME, pvalloc);
1098 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1099 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1100
1101#endif
1102
sewardjec92a072006-10-17 01:50:31 +00001103
sewardja610f532007-11-16 22:29:27 +00001104#define MALLOC_STATS(soname, fnname) \
1105 \
sewardj96044842011-08-18 13:09:55 +00001106 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
1107 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
sewardja610f532007-11-16 22:29:27 +00001108 { \
1109 /* Valgrind's malloc_stats implementation does nothing. */ \
1110 }
1111
sewardj3c944452011-09-05 20:39:57 +00001112#if defined(VGO_linux)
1113 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
philippe1e470b52012-05-11 19:33:46 +00001114 MALLOC_STATS(SO_SYN_MALLOC, malloc_stats);
sewardj3c944452011-09-05 20:39:57 +00001115
1116#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +00001117 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
sewardj3c944452011-09-05 20:39:57 +00001118
1119#endif
sewardja610f532007-11-16 22:29:27 +00001120
sewardjec92a072006-10-17 01:50:31 +00001121
1122/*---------------------- mallinfo ----------------------*/
sewardj9ee81f52005-04-02 17:38:59 +00001123
njn088bfb42005-08-17 05:01:37 +00001124// mi must be static; if it is auto then Memcheck thinks it is
1125// uninitialised when used by the caller of this function, because Memcheck
1126// doesn't know that the call to mallinfo fills in mi.
sewardj9ee81f52005-04-02 17:38:59 +00001127#define MALLINFO(soname, fnname) \
1128 \
sewardj96044842011-08-18 13:09:55 +00001129 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1130 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
sewardj9ee81f52005-04-02 17:38:59 +00001131 { \
njn088bfb42005-08-17 05:01:37 +00001132 static struct vg_mallinfo mi; \
philippecf9e1972013-04-04 21:10:22 +00001133 DO_INIT; \
njnd55f0d92009-08-03 01:38:56 +00001134 MALLOC_TRACE("mallinfo()\n"); \
njn088bfb42005-08-17 05:01:37 +00001135 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
sewardj9ee81f52005-04-02 17:38:59 +00001136 return mi; \
1137 }
1138
sewardj3c944452011-09-05 20:39:57 +00001139#if defined(VGO_linux)
1140 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
philippe1e470b52012-05-11 19:33:46 +00001141 MALLINFO(SO_SYN_MALLOC, mallinfo);
sewardj3c944452011-09-05 20:39:57 +00001142
1143#elif defined(VGO_darwin)
sewardj731f9cf2011-09-21 08:43:08 +00001144 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
sewardj3c944452011-09-05 20:39:57 +00001145
1146#endif
sewardj9ee81f52005-04-02 17:38:59 +00001147
1148
sewardj731f9cf2011-09-21 08:43:08 +00001149/*------------------ Darwin zone stuff ------------------*/
1150
njnf76d27a2009-05-28 01:53:07 +00001151#if defined(VGO_darwin)
1152
sewardjeb83f6c2012-02-23 07:36:03 +00001153static size_t my_malloc_size ( void* zone, void* ptr )
1154{
1155 /* Implement "malloc_size" by handing the request through to the
1156 tool's .tl_usable_size method. */
philippecf9e1972013-04-04 21:10:22 +00001157 DO_INIT;
philippe347a4812014-09-01 21:46:52 +00001158 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);
1159 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) ptr);
sewardjeb83f6c2012-02-23 07:36:03 +00001160 size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1161 info.tl_malloc_usable_size, ptr);
1162 return res;
1163}
1164
sewardj21b7ab22012-04-21 22:33:44 +00001165/* Note that the (void*) casts below are a kludge which stops
florianad4e9792015-07-05 21:53:33 +00001166 compilers complaining about the fact that the replacement
sewardj21b7ab22012-04-21 22:33:44 +00001167 functions aren't really of the right type. */
njnf76d27a2009-05-28 01:53:07 +00001168static vki_malloc_zone_t vg_default_zone = {
sewardj731f9cf2011-09-21 08:43:08 +00001169 NULL, // reserved1
1170 NULL, // reserved2
sewardj21b7ab22012-04-21 22:33:44 +00001171 (void*)my_malloc_size, // JRS fixme: is this right?
sewardj96044842011-08-18 13:09:55 +00001172 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1173 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1174 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1175 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1176 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
sewardj731f9cf2011-09-21 08:43:08 +00001177 NULL, // GrP fixme: destroy
njnf76d27a2009-05-28 01:53:07 +00001178 "ValgrindMallocZone",
1179 NULL, // batch_malloc
1180 NULL, // batch_free
sewardj731f9cf2011-09-21 08:43:08 +00001181 NULL, // GrP fixme: introspect
njnf76d27a2009-05-28 01:53:07 +00001182 2, // version (GrP fixme 3?)
rhyskiddfa37d5b2015-10-04 09:23:07 +00001183 (void*)VG_REPLACE_FUNCTION_EZU(10100,VG_Z_LIBC_SONAME,malloc_zone_memalign), // DDD: this field exists in Mac OS 10.6+
sewardj731f9cf2011-09-21 08:43:08 +00001184 NULL, /* free_definite_size */
1185 NULL, /* pressure_relief */
njnf76d27a2009-05-28 01:53:07 +00001186};
1187
sewardj731f9cf2011-09-21 08:43:08 +00001188
njnf76d27a2009-05-28 01:53:07 +00001189#define DEFAULT_ZONE(soname, fnname) \
1190 \
sewardj96044842011-08-18 13:09:55 +00001191 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1192 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
njnf76d27a2009-05-28 01:53:07 +00001193 { \
1194 return &vg_default_zone; \
1195 }
1196
njnf76d27a2009-05-28 01:53:07 +00001197DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
philippe1e470b52012-05-11 19:33:46 +00001198DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_zone);
sewardj7817ee42014-06-25 11:24:16 +00001199DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_purgeable_zone);
1200DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_purgeable_zone);
1201
1202
1203#define CREATE_ZONE(soname, fnname) \
1204 \
1205 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl); \
1206 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl) \
1207 { \
1208 return &vg_default_zone; \
1209 }
1210CREATE_ZONE(VG_Z_LIBC_SONAME, malloc_create_zone);
njnf76d27a2009-05-28 01:53:07 +00001211
sewardj731f9cf2011-09-21 08:43:08 +00001212
1213#define ZONE_FROM_PTR(soname, fnname) \
1214 \
sewardj7817ee42014-06-25 11:24:16 +00001215 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
1216 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ) \
sewardj731f9cf2011-09-21 08:43:08 +00001217 { \
1218 return &vg_default_zone; \
1219 }
1220
1221ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
philippe1e470b52012-05-11 19:33:46 +00001222ZONE_FROM_PTR(SO_SYN_MALLOC, malloc_zone_from_ptr);
sewardj731f9cf2011-09-21 08:43:08 +00001223
1224
njnf76d27a2009-05-28 01:53:07 +00001225// GrP fixme bypass libc's use of zone->introspect->check
1226#define ZONE_CHECK(soname, fnname) \
sewardjbd2cff22011-08-16 21:45:28 +00001227 \
sewardj7817ee42014-06-25 11:24:16 +00001228 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
1229 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone) \
njnf76d27a2009-05-28 01:53:07 +00001230 { \
philippe347a4812014-09-01 21:46:52 +00001231 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
sewardj7817ee42014-06-25 11:24:16 +00001232 panic(#fnname); \
njnf76d27a2009-05-28 01:53:07 +00001233 return 1; \
1234 }
1235
sewardj7817ee42014-06-25 11:24:16 +00001236ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1237ZONE_CHECK(SO_SYN_MALLOC, malloc_zone_check);
1238
1239
1240#define ZONE_REGISTER(soname, fnname) \
1241 \
1242 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
1243 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone) \
1244 { \
philippe347a4812014-09-01 21:46:52 +00001245 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
sewardj7817ee42014-06-25 11:24:16 +00001246 }
1247
1248ZONE_REGISTER(VG_Z_LIBC_SONAME, malloc_zone_register);
1249ZONE_REGISTER(SO_SYN_MALLOC, malloc_zone_register);
1250
1251
1252#define ZONE_UNREGISTER(soname, fnname) \
1253 \
1254 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
1255 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone) \
1256 { \
philippe347a4812014-09-01 21:46:52 +00001257 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
sewardj7817ee42014-06-25 11:24:16 +00001258 }
1259
1260ZONE_UNREGISTER(VG_Z_LIBC_SONAME, malloc_zone_unregister);
1261ZONE_UNREGISTER(SO_SYN_MALLOC, malloc_zone_unregister);
1262
1263
1264#define ZONE_SET_NAME(soname, fnname) \
1265 \
1266 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm); \
1267 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm) \
1268 { \
philippe347a4812014-09-01 21:46:52 +00001269 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
sewardj7817ee42014-06-25 11:24:16 +00001270 }
1271
1272ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_set_zone_name);
1273ZONE_SET_NAME(SO_SYN_MALLOC, malloc_set_zone_name);
1274
1275
1276#define ZONE_GET_NAME(soname, fnname) \
1277 \
rhyskiddf7e83452015-10-19 10:20:17 +00001278 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
1279 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone) \
sewardj7817ee42014-06-25 11:24:16 +00001280 { \
philippe347a4812014-09-01 21:46:52 +00001281 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
sewardj7817ee42014-06-25 11:24:16 +00001282 return vg_default_zone.zone_name; \
1283 }
1284
rhyskidd0bbeecd2015-10-15 04:18:12 +00001285ZONE_GET_NAME(VG_Z_LIBC_SONAME, malloc_get_zone_name);
1286ZONE_GET_NAME(SO_SYN_MALLOC, malloc_get_zone_name);
njnf76d27a2009-05-28 01:53:07 +00001287
sewardj3c944452011-09-05 20:39:57 +00001288#endif /* defined(VGO_darwin) */
njnf76d27a2009-05-28 01:53:07 +00001289
1290
sewardj731f9cf2011-09-21 08:43:08 +00001291/*------------------ (startup related) ------------------*/
1292
sewardj9ee81f52005-04-02 17:38:59 +00001293/* All the code in here is unused until this function is called */
1294
njn2c4e5352009-06-29 05:19:15 +00001295__attribute__((constructor))
sewardj9ee81f52005-04-02 17:38:59 +00001296static void init(void)
1297{
njn2c4e5352009-06-29 05:19:15 +00001298 // This doesn't look thread-safe, but it should be ok... Bart says:
1299 //
1300 // Every program I know of calls malloc() at least once before calling
1301 // pthread_create(). So init_done gets initialized before any thread is
1302 // created, and is only read when multiple threads are active
1303 // simultaneously. Such an access pattern is safe.
1304 //
1305 // If the assignment to the variable init_done would be triggering a race
1306 // condition, both DRD and Helgrind would report this race.
1307 //
1308 // By the way, although the init() function in
1309 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1310 // __attribute__((constructor)), it is not safe to remove the variable
1311 // init_done. This is because it is possible that malloc() and hence
1312 // init() gets called before shared library initialization finished.
1313 //
sewardj9ee81f52005-04-02 17:38:59 +00001314 if (init_done)
1315 return;
1316
1317 init_done = 1;
1318
sewardj4b3a7422011-10-24 13:21:57 +00001319 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
bart575ce8e2011-05-15 07:04:03 +00001320 0, 0, 0, 0);
sewardj9ee81f52005-04-02 17:38:59 +00001321}
1322
1323/*--------------------------------------------------------------------*/
njn2c4e5352009-06-29 05:19:15 +00001324/*--- end ---*/
sewardj9ee81f52005-04-02 17:38:59 +00001325/*--------------------------------------------------------------------*/