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