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