sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
| 3 | /*--- Replacements for malloc() et al, which run on the simulated ---*/ |
| 4 | /*--- CPU. vg_replace_malloc.c ---*/ |
| 5 | /*--------------------------------------------------------------------*/ |
| 6 | |
| 7 | /* |
| 8 | This file is part of Valgrind, a dynamic binary instrumentation |
| 9 | framework. |
| 10 | |
sewardj | 9ebd6e0 | 2007-01-08 06:01:59 +0000 | [diff] [blame] | 11 | Copyright (C) 2000-2007 Julian Seward |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 12 | jseward@acm.org |
| 13 | |
| 14 | This program is free software; you can redistribute it and/or |
| 15 | modify it under the terms of the GNU General Public License as |
| 16 | published by the Free Software Foundation; either version 2 of the |
| 17 | License, or (at your option) any later version. |
| 18 | |
| 19 | This program is distributed in the hope that it will be useful, but |
| 20 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 22 | General Public License for more details. |
| 23 | |
| 24 | You should have received a copy of the GNU General Public License |
| 25 | along with this program; if not, write to the Free Software |
| 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 27 | 02111-1307, USA. |
| 28 | |
| 29 | The GNU General Public License is contained in the file COPYING. |
| 30 | */ |
| 31 | |
| 32 | /* --------------------------------------------------------------------- |
njn | 16eeb4e | 2005-06-16 03:56:58 +0000 | [diff] [blame] | 33 | ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. |
| 34 | |
| 35 | These functions are drop-in replacements for malloc() and friends. |
| 36 | They have global scope, but are not intended to be called directly. |
| 37 | See pub_core_redir.h for the gory details. |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 38 | |
njn | 16eeb4e | 2005-06-16 03:56:58 +0000 | [diff] [blame] | 39 | This file can be linked into the vg_preload_<tool>.so file for any tool |
| 40 | that wishes to know about calls to malloc(). The tool must define all |
njn | 51d827b | 2005-05-09 01:02:08 +0000 | [diff] [blame] | 41 | the functions that will be called via 'info'. |
njn | 717cde5 | 2005-05-10 02:47:21 +0000 | [diff] [blame] | 42 | |
njn | 16eeb4e | 2005-06-16 03:56:58 +0000 | [diff] [blame] | 43 | It is called vg_replace_malloc.c because this filename appears in stack |
| 44 | traces, so we want the name to be (hopefully!) meaningful to users. |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 45 | ------------------------------------------------------------------ */ |
| 46 | |
njn | c7561b9 | 2005-06-19 01:24:32 +0000 | [diff] [blame] | 47 | #include "pub_core_basics.h" |
sewardj | e66f2e0 | 2006-12-30 17:45:08 +0000 | [diff] [blame] | 48 | #include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM |
njn | 93fe3b2 | 2005-12-21 20:22:52 +0000 | [diff] [blame] | 49 | #include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF, |
| 50 | // VALGRIND_NON_SIMD_CALL[12] |
njn | 16eeb4e | 2005-06-16 03:56:58 +0000 | [diff] [blame] | 51 | #include "pub_core_debuginfo.h" // needed for pub_core_redir.h :( |
njn | af1d7df | 2005-06-11 01:31:52 +0000 | [diff] [blame] | 52 | #include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 53 | #include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_* |
njn | da325d9 | 2005-05-11 18:51:53 +0000 | [diff] [blame] | 54 | #include "pub_core_replacemalloc.h" |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 55 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 56 | /* --------- Some handy Z-encoded names. --------- */ |
| 57 | |
| 58 | /* --- Soname of the standard C library. --- */ |
| 59 | |
| 60 | #if defined(VGO_linux) |
| 61 | # define m_libc_soname libcZdsoZa // libc.so* |
| 62 | #elif defined(VGP_ppc32_aix5) |
| 63 | /* AIX has both /usr/lib/libc.a and /usr/lib/libc_r.a. */ |
| 64 | # define m_libc_soname libcZaZdaZLshrZdoZR // libc*.a(shr.o) |
| 65 | #elif defined(VGP_ppc64_aix5) |
| 66 | # define m_libc_soname libcZaZdaZLshrZu64ZdoZR // libc*.a(shr_64.o) |
| 67 | #else |
| 68 | # error "Unknown platform" |
| 69 | #endif |
| 70 | |
| 71 | /* --- Soname of the GNU C++ library. --- */ |
| 72 | |
| 73 | #define m_libstdcxx_soname libstdcZpZpZa // libstdc++* |
| 74 | |
| 75 | /* --- Soname of XLC's C++ library. --- */ |
| 76 | |
| 77 | /* AIX: xlC's C++ runtime library is called libC.a, and the |
| 78 | interesting symbols appear to be in ansicore_32.o or ansicore_64.o |
| 79 | respectively. */ |
| 80 | #if defined(VGP_ppc32_aix5) |
| 81 | # define m_libC_dot_a libCZdaZLansicoreZu32ZdoZR // libC.a(ansicore_32.o) |
| 82 | #elif defined(VGP_ppc64_aix5) |
| 83 | # define m_libC_dot_a libCZdaZLansicoreZu64ZdoZR // libC.a(ansicore_64.o) |
| 84 | #endif |
| 85 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 86 | |
| 87 | /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style |
| 88 | mangling, could be supported properly by the redirects in this |
| 89 | module. Except we can't because it doesn't put its allocation |
| 90 | functions in libpgc.so but instead hardwires them into the |
| 91 | compilation unit holding main(), which makes them impossible to |
| 92 | intercept directly. Fortunately those fns seem to route everything |
| 93 | through to malloc/free. |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 94 | |
| 95 | mid-06: could be improved, since we can now intercept in the main |
| 96 | executable too. |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 97 | */ |
| 98 | |
| 99 | extern void _exit(int); |
| 100 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 101 | /* Apparently it is necessary to make ourselves free of any dependency |
| 102 | on memcpy() on ppc32-aix5; else programs linked with -brtl fail. |
| 103 | memcpy() is used by gcc for a struct assignment in mallinfo() |
| 104 | below. Add the following conservative implementation (memmove, |
| 105 | really). */ |
| 106 | #if defined(VGO_aix5) |
| 107 | __attribute__((weak)) |
| 108 | void *memcpy(void *destV, const void *srcV, unsigned long n) |
| 109 | { |
| 110 | unsigned char* src = (unsigned char*)srcV; |
| 111 | unsigned char* dest = (unsigned char*)destV; |
| 112 | unsigned long i; |
| 113 | if (dest < src) { |
| 114 | for (i = 0; i < n; i++) |
| 115 | dest[i] = src[i]; |
| 116 | } |
| 117 | if (dest > src) { |
| 118 | for (i = n; i > 0; i--) |
| 119 | dest[i-1] = src[i-1]; |
| 120 | } |
| 121 | return dest; |
| 122 | } |
| 123 | #endif |
| 124 | |
| 125 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 126 | /*------------------------------------------------------------*/ |
| 127 | /*--- Replacing malloc() et al ---*/ |
| 128 | /*------------------------------------------------------------*/ |
| 129 | |
| 130 | /* This struct is initially empty. Before the first use of any of |
| 131 | these functions, we make a client request which fills in the |
| 132 | fields. |
| 133 | */ |
| 134 | static struct vg_mallocfunc_info info; |
| 135 | static int init_done; |
| 136 | |
| 137 | /* Startup hook - called as init section */ |
| 138 | static void init(void) __attribute__((constructor)); |
| 139 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 140 | #define MALLOC_TRACE(format, args...) \ |
| 141 | if (info.clo_trace_malloc) \ |
njn | 1277109 | 2005-06-18 02:18:04 +0000 | [diff] [blame] | 142 | VALGRIND_INTERNAL_PRINTF(format, ## args ) |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 143 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 144 | /* Below are new versions of malloc, __builtin_new, free, |
| 145 | __builtin_delete, calloc, realloc, memalign, and friends. |
| 146 | |
| 147 | None of these functions are called directly - they are not meant to |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 148 | be found by the dynamic linker. But ALL client calls to malloc() |
| 149 | and friends wind up here eventually. They get called because |
| 150 | vg_replace_malloc installs a bunch of code redirects which causes |
| 151 | Valgrind to use these functions rather than the ones they're |
| 152 | replacing. |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 153 | */ |
| 154 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 155 | |
| 156 | /*---------------------- malloc ----------------------*/ |
| 157 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 158 | /* Generate a replacement for 'fnname' in object 'soname', which calls |
| 159 | 'vg_replacement' to allocate memory. If that fails, return NULL. |
| 160 | */ |
| 161 | #define ALLOC_or_NULL(soname, fnname, vg_replacement) \ |
| 162 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 163 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \ |
| 164 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 165 | { \ |
| 166 | void* v; \ |
| 167 | \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 168 | if (!init_done) init(); \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 169 | MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 170 | \ |
| 171 | v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ |
| 172 | MALLOC_TRACE(" = %p", v ); \ |
| 173 | return v; \ |
| 174 | } |
| 175 | |
| 176 | |
| 177 | /* Generate a replacement for 'fnname' in object 'soname', which calls |
| 178 | 'vg_replacement' to allocate memory. If that fails, it bombs the |
| 179 | system. |
| 180 | */ |
| 181 | #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \ |
| 182 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 183 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \ |
| 184 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 185 | { \ |
| 186 | void* v; \ |
| 187 | \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 188 | if (!init_done) init(); \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 189 | MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 190 | \ |
| 191 | v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \ |
| 192 | MALLOC_TRACE(" = %p", v ); \ |
| 193 | if (NULL == v) { \ |
| 194 | VALGRIND_PRINTF_BACKTRACE( \ |
| 195 | "new/new[] failed and should throw an exception, but Valgrind\n" \ |
| 196 | " cannot throw exceptions and so is aborting instead. Sorry."); \ |
| 197 | _exit(1); \ |
| 198 | } \ |
| 199 | return v; \ |
| 200 | } |
| 201 | |
| 202 | // Each of these lines generates a replacement function: |
| 203 | // (from_so, from_fn, v's replacement) |
| 204 | |
| 205 | // malloc |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 206 | ALLOC_or_NULL(m_libstdcxx_soname, malloc, malloc); |
| 207 | ALLOC_or_NULL(m_libc_soname, malloc, malloc); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 208 | |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 209 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 210 | /*---------------------- new ----------------------*/ |
| 211 | |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 212 | // operator new(unsigned int), not mangled (for gcc 2.96) |
sewardj | 2682038 | 2007-05-02 16:24:30 +0000 | [diff] [blame] | 213 | ALLOC_or_BOMB(m_libstdcxx_soname, builtin_new, __builtin_new); |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 214 | ALLOC_or_BOMB(m_libc_soname, builtin_new, __builtin_new); |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 215 | |
sewardj | 2682038 | 2007-05-02 16:24:30 +0000 | [diff] [blame] | 216 | ALLOC_or_BOMB(m_libstdcxx_soname, __builtin_new, __builtin_new); |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 217 | ALLOC_or_BOMB(m_libc_soname, __builtin_new, __builtin_new); |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 218 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 219 | // operator new(unsigned int), GNU mangling |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 220 | #if VG_WORDSIZE == 4 |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 221 | ALLOC_or_BOMB(m_libstdcxx_soname, _Znwj, __builtin_new); |
| 222 | ALLOC_or_BOMB(m_libc_soname, _Znwj, __builtin_new); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 223 | #endif |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 224 | |
| 225 | // operator new(unsigned long), GNU mangling |
| 226 | #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) |
| 227 | ALLOC_or_BOMB(m_libstdcxx_soname, _Znwm, __builtin_new); |
| 228 | ALLOC_or_BOMB(m_libc_soname, _Znwm, __builtin_new); |
| 229 | #endif |
| 230 | |
| 231 | // operator new(unsigned long), ARM/cfront mangling |
| 232 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 233 | ALLOC_or_BOMB(m_libC_dot_a, __nw__FUl, __builtin_new); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 234 | #endif |
sewardj | 9b3328d | 2005-04-24 00:04:42 +0000 | [diff] [blame] | 235 | |
| 236 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 237 | /*---------------------- new nothrow ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 238 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 239 | // operator new(unsigned, std::nothrow_t const&), GNU mangling |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 240 | #if VG_WORDSIZE == 4 |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 241 | ALLOC_or_NULL(m_libstdcxx_soname, _ZnwjRKSt9nothrow_t, __builtin_new); |
| 242 | ALLOC_or_NULL(m_libc_soname, _ZnwjRKSt9nothrow_t, __builtin_new); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 243 | #endif |
tom | f91889f | 2005-05-04 18:01:26 +0000 | [diff] [blame] | 244 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 245 | // operator new(unsigned long, std::nothrow_t const&), GNU mangling |
| 246 | #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 247 | ALLOC_or_NULL(m_libstdcxx_soname, _ZnwmRKSt9nothrow_t, __builtin_new); |
| 248 | ALLOC_or_NULL(m_libc_soname, _ZnwmRKSt9nothrow_t, __builtin_new); |
| 249 | #endif |
| 250 | |
| 251 | // operator new(unsigned long, std::nothrow_t const&), ARM/cfront mangling |
| 252 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 253 | ALLOC_or_NULL(m_libC_dot_a, __nw__FUlRCQ2_3std9nothrow_t, __builtin_new); |
| 254 | #endif |
| 255 | |
| 256 | |
| 257 | /*---------------------- new [] ----------------------*/ |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 258 | |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 259 | // operator new[](unsigned int), not mangled (for gcc 2.96) |
sewardj | 2682038 | 2007-05-02 16:24:30 +0000 | [diff] [blame] | 260 | ALLOC_or_BOMB(m_libstdcxx_soname, __builtin_vec_new, __builtin_vec_new ); |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 261 | ALLOC_or_BOMB(m_libc_soname, __builtin_vec_new, __builtin_vec_new ); |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 262 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 263 | // operator new[](unsigned int), GNU mangling |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 264 | #if VG_WORDSIZE == 4 |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 265 | ALLOC_or_BOMB(m_libstdcxx_soname, _Znaj, __builtin_vec_new ); |
| 266 | ALLOC_or_BOMB(m_libc_soname, _Znaj, __builtin_vec_new ); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 267 | #endif |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 268 | |
| 269 | // operator new[](unsigned long), GNU mangling |
| 270 | #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 271 | ALLOC_or_BOMB(m_libstdcxx_soname, _Znam, __builtin_vec_new ); |
| 272 | ALLOC_or_BOMB(m_libc_soname, _Znam, __builtin_vec_new ); |
| 273 | #endif |
| 274 | |
| 275 | // operator new[](unsigned long), ARM/cfront mangling |
| 276 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 277 | ALLOC_or_BOMB(m_libC_dot_a, __vn__FUl, __builtin_vec_new); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 278 | #endif |
sewardj | 9b3328d | 2005-04-24 00:04:42 +0000 | [diff] [blame] | 279 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 280 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 281 | /*---------------------- new [] nothrow ----------------------*/ |
| 282 | |
| 283 | // operator new[](unsigned, std::nothrow_t const&), GNU mangling |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 284 | #if VG_WORDSIZE == 4 |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 285 | ALLOC_or_NULL(m_libstdcxx_soname, _ZnajRKSt9nothrow_t, __builtin_vec_new ); |
| 286 | ALLOC_or_NULL(m_libc_soname, _ZnajRKSt9nothrow_t, __builtin_vec_new ); |
sewardj | a0e1656 | 2005-05-05 01:16:24 +0000 | [diff] [blame] | 287 | #endif |
tom | f91889f | 2005-05-04 18:01:26 +0000 | [diff] [blame] | 288 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 289 | // operator new[](unsigned long, std::nothrow_t const&), GNU mangling |
| 290 | #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 291 | ALLOC_or_NULL(m_libstdcxx_soname, _ZnamRKSt9nothrow_t, __builtin_vec_new ); |
| 292 | ALLOC_or_NULL(m_libc_soname, _ZnamRKSt9nothrow_t, __builtin_vec_new ); |
| 293 | #endif |
| 294 | |
| 295 | // operator new [](unsigned long, std::nothrow_t const&), ARM/cfront mangling |
| 296 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 297 | ALLOC_or_BOMB(m_libC_dot_a, __vn__FUlRCQ2_3std9nothrow_t, __builtin_vec_new ); |
| 298 | #endif |
| 299 | |
| 300 | |
| 301 | /*---------------------- free ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 302 | |
| 303 | /* Generate a replacement for 'fnname' in object 'soname', which calls |
| 304 | 'vg_replacement' to free previously allocated memory. |
| 305 | */ |
| 306 | #define FREE(soname, fnname, vg_replacement) \ |
| 307 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 308 | void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p); \ |
| 309 | void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 310 | { \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 311 | if (!init_done) init(); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 312 | MALLOC_TRACE(#vg_replacement "(%p)", p ); \ |
| 313 | if (p == NULL) \ |
| 314 | return; \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 315 | (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ |
| 316 | } |
| 317 | |
| 318 | // free |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 319 | FREE(m_libstdcxx_soname, free, free ); |
| 320 | FREE(m_libc_soname, free, free ); |
| 321 | |
| 322 | |
| 323 | /*---------------------- cfree ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 324 | |
| 325 | // cfree |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 326 | FREE(m_libstdcxx_soname, cfree, free ); |
| 327 | FREE(m_libc_soname, cfree, free ); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 328 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 329 | |
| 330 | /*---------------------- delete ----------------------*/ |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 331 | // operator delete(void*), not mangled (for gcc 2.96) |
sewardj | 2682038 | 2007-05-02 16:24:30 +0000 | [diff] [blame] | 332 | FREE(m_libstdcxx_soname, __builtin_delete, __builtin_delete ); |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 333 | FREE(m_libc_soname, __builtin_delete, __builtin_delete ); |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 334 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 335 | // operator delete(void*), GNU mangling |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 336 | FREE(m_libstdcxx_soname, _ZdlPv, __builtin_delete ); |
| 337 | FREE(m_libc_soname, _ZdlPv, __builtin_delete ); |
| 338 | |
| 339 | // operator delete(void*), ARM/cfront mangling |
| 340 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 341 | FREE(m_libC_dot_a, __dl__FPv, __builtin_delete ); |
| 342 | #endif |
| 343 | |
| 344 | |
| 345 | /*---------------------- delete nothrow ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 346 | |
| 347 | // operator delete(void*, std::nothrow_t const&), GNU mangling |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 348 | FREE(m_libstdcxx_soname, _ZdlPvRKSt9nothrow_t, __builtin_delete ); |
| 349 | FREE(m_libc_soname, _ZdlPvRKSt9nothrow_t, __builtin_delete ); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 350 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 351 | |
| 352 | /*---------------------- delete [] ----------------------*/ |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 353 | // operator delete[](void*), not mangled (for gcc 2.96) |
sewardj | 2682038 | 2007-05-02 16:24:30 +0000 | [diff] [blame] | 354 | FREE(m_libstdcxx_soname, __builtin_vec_delete, __builtin_vec_delete ); |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 355 | FREE(m_libc_soname, __builtin_vec_delete, __builtin_vec_delete ); |
sewardj | 7c1fa87 | 2006-05-21 01:52:09 +0000 | [diff] [blame] | 356 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 357 | // operator delete[](void*), GNU mangling |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 358 | FREE(m_libstdcxx_soname, _ZdaPv, __builtin_vec_delete ); |
| 359 | FREE(m_libc_soname, _ZdaPv, __builtin_vec_delete ); |
| 360 | |
| 361 | // operator delete[](void*), ARM/cfront mangling |
| 362 | #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
| 363 | FREE(m_libC_dot_a, __vd__FPv, __builtin_vec_delete ); |
| 364 | #endif |
| 365 | |
| 366 | |
| 367 | /*---------------------- delete [] nothrow ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 368 | |
| 369 | // operator delete[](void*, std::nothrow_t const&), GNU mangling |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 370 | FREE(m_libstdcxx_soname, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); |
| 371 | FREE(m_libc_soname, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 372 | |
| 373 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 374 | /*---------------------- calloc ----------------------*/ |
| 375 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 376 | #define CALLOC(soname, fnname) \ |
| 377 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 378 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ); \ |
| 379 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 380 | { \ |
| 381 | void* v; \ |
| 382 | \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 383 | if (!init_done) init(); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 384 | MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 385 | \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 386 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ |
| 387 | MALLOC_TRACE(" = %p", v ); \ |
| 388 | return v; \ |
| 389 | } |
| 390 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 391 | CALLOC(m_libc_soname, calloc); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 392 | |
| 393 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 394 | /*---------------------- realloc ----------------------*/ |
| 395 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 396 | #define REALLOC(soname, fnname) \ |
| 397 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 398 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size );\ |
| 399 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 400 | { \ |
| 401 | void* v; \ |
| 402 | \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 403 | if (!init_done) init(); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 404 | MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 405 | \ |
| 406 | if (ptrV == NULL) \ |
| 407 | /* We need to call a malloc-like function; so let's use \ |
| 408 | one which we know exists. */ \ |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 409 | return VG_REPLACE_FUNCTION_ZU(m_libc_soname,malloc) (new_size); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 410 | if (new_size <= 0) { \ |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 411 | VG_REPLACE_FUNCTION_ZU(m_libc_soname,free)(ptrV); \ |
njn | 1277109 | 2005-06-18 02:18:04 +0000 | [diff] [blame] | 412 | MALLOC_TRACE(" = 0"); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 413 | return NULL; \ |
| 414 | } \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 415 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \ |
| 416 | MALLOC_TRACE(" = %p", v ); \ |
| 417 | return v; \ |
| 418 | } |
| 419 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 420 | REALLOC(m_libc_soname, realloc); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 421 | |
| 422 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 423 | /*---------------------- memalign ----------------------*/ |
| 424 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 425 | #define MEMALIGN(soname, fnname) \ |
| 426 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 427 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ); \ |
| 428 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 429 | { \ |
| 430 | void* v; \ |
| 431 | \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 432 | if (!init_done) init(); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 433 | MALLOC_TRACE("memalign(al %llu, size %llu)", \ |
| 434 | (ULong)alignment, (ULong)n ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 435 | \ |
| 436 | /* Round up to minimum alignment if necessary. */ \ |
| 437 | if (alignment < VG_MIN_MALLOC_SZB) \ |
| 438 | alignment = VG_MIN_MALLOC_SZB; \ |
| 439 | \ |
| 440 | /* Round up to nearest power-of-two if necessary (like glibc). */ \ |
| 441 | while (0 != (alignment & (alignment - 1))) alignment++; \ |
| 442 | \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 443 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ |
| 444 | MALLOC_TRACE(" = %p", v ); \ |
| 445 | return v; \ |
| 446 | } |
| 447 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 448 | MEMALIGN(m_libc_soname, memalign); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 449 | |
| 450 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 451 | /*---------------------- valloc ----------------------*/ |
| 452 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 453 | #define VALLOC(soname, fnname) \ |
| 454 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 455 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \ |
| 456 | void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 457 | { \ |
sewardj | e66f2e0 | 2006-12-30 17:45:08 +0000 | [diff] [blame] | 458 | static int pszB = 0; \ |
| 459 | extern int getpagesize (void); \ |
| 460 | if (pszB == 0) \ |
| 461 | pszB = getpagesize(); \ |
| 462 | return VG_REPLACE_FUNCTION_ZU(m_libc_soname,memalign) \ |
| 463 | ((SizeT)pszB, size); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 464 | } |
| 465 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 466 | VALLOC(m_libc_soname, valloc); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 467 | |
| 468 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 469 | /*---------------------- mallopt ----------------------*/ |
| 470 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 471 | /* Various compatibility wrapper functions, for glibc and libstdc++. */ |
| 472 | |
| 473 | #define MALLOPT(soname, fnname) \ |
| 474 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 475 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ); \ |
| 476 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 477 | { \ |
| 478 | /* In glibc-2.2.4, 1 denotes a successful return value for \ |
| 479 | mallopt */ \ |
| 480 | return 1; \ |
| 481 | } |
| 482 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 483 | MALLOPT(m_libc_soname, mallopt); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 484 | |
| 485 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 486 | /*---------------------- malloc_trim ----------------------*/ |
njn | ceb0266 | 2006-07-08 08:29:20 +0000 | [diff] [blame] | 487 | // Documentation says: |
| 488 | // malloc_trim(size_t pad); |
| 489 | // |
| 490 | // If possible, gives memory back to the system (via negative arguments to |
| 491 | // sbrk) if there is unused memory at the `high' end of the malloc pool. |
| 492 | // You can call this after freeing large blocks of memory to potentially |
| 493 | // reduce the system-level memory requirements of a program. However, it |
| 494 | // cannot guarantee to reduce memory. Under some allocation patterns, |
| 495 | // some large free blocks of memory will be locked between two used |
| 496 | // chunks, so they cannot be given back to the system. |
| 497 | // |
| 498 | // The `pad' argument to malloc_trim represents the amount of free |
| 499 | // trailing space to leave untrimmed. If this argument is zero, only the |
| 500 | // minimum amount of memory to maintain internal data structures will be |
| 501 | // left (one page or less). Non-zero arguments can be supplied to maintain |
| 502 | // enough trailing space to service future expected allocations without |
| 503 | // having to re-obtain memory from the system. |
| 504 | // |
| 505 | // Malloc_trim returns 1 if it actually released any memory, else 0. On |
| 506 | // systems that do not support "negative sbrks", it will always return 0. |
| 507 | // |
| 508 | // For simplicity, we always return 0. |
| 509 | #define MALLOC_TRIM(soname, fnname) \ |
| 510 | \ |
| 511 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ); \ |
| 512 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ) \ |
| 513 | { \ |
| 514 | /* 0 denotes that malloc_trim() either wasn't able \ |
| 515 | to do anything, or was not implemented */ \ |
| 516 | return 0; \ |
| 517 | } |
| 518 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 519 | MALLOC_TRIM(m_libc_soname, malloc_trim); |
njn | ceb0266 | 2006-07-08 08:29:20 +0000 | [diff] [blame] | 520 | |
| 521 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 522 | /*---------------------- posix_memalign ----------------------*/ |
| 523 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 524 | #define POSIX_MEMALIGN(soname, fnname) \ |
| 525 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 526 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \ |
| 527 | SizeT alignment, SizeT size ); \ |
| 528 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \ |
| 529 | SizeT alignment, SizeT size ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 530 | { \ |
| 531 | void *mem; \ |
| 532 | \ |
| 533 | /* Test whether the alignment argument is valid. It must be \ |
| 534 | a power of two multiple of sizeof (void *). */ \ |
| 535 | if (alignment % sizeof (void *) != 0 \ |
| 536 | || (alignment & (alignment - 1)) != 0) \ |
| 537 | return VKI_EINVAL; \ |
| 538 | \ |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 539 | mem = VG_REPLACE_FUNCTION_ZU(m_libc_soname,memalign)(alignment, size); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 540 | \ |
| 541 | if (mem != NULL) { \ |
| 542 | *memptr = mem; \ |
| 543 | return 0; \ |
| 544 | } \ |
| 545 | \ |
| 546 | return VKI_ENOMEM; \ |
| 547 | } |
| 548 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 549 | POSIX_MEMALIGN(m_libc_soname, posix_memalign); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 550 | |
| 551 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 552 | /*---------------------- malloc_usable_size ----------------------*/ |
| 553 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 554 | #define MALLOC_USABLE_SIZE(soname, fnname) \ |
| 555 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 556 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ); \ |
| 557 | int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 558 | { \ |
| 559 | SizeT pszB; \ |
| 560 | \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 561 | if (!init_done) init(); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 562 | MALLOC_TRACE("malloc_usable_size(%p)", p ); \ |
| 563 | if (NULL == p) \ |
| 564 | return 0; \ |
| 565 | \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 566 | pszB = (SizeT)VALGRIND_NON_SIMD_CALL2( info.arena_payload_szB, \ |
| 567 | VG_AR_CLIENT, p ); \ |
| 568 | MALLOC_TRACE(" = %llu", (ULong)pszB ); \ |
| 569 | \ |
| 570 | return pszB; \ |
| 571 | } |
| 572 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 573 | MALLOC_USABLE_SIZE(m_libc_soname, malloc_usable_size); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 574 | |
| 575 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 576 | /*---------------------- (unimplemented) ----------------------*/ |
| 577 | |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 578 | /* Bomb out if we get any of these. */ |
| 579 | |
| 580 | static void panic(const char *str) |
| 581 | { |
| 582 | VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s", str); |
| 583 | _exit(99); |
| 584 | *(int *)0 = 'x'; |
| 585 | } |
| 586 | |
| 587 | #define PANIC(soname, fnname) \ |
| 588 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 589 | void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \ |
| 590 | void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 591 | { \ |
| 592 | panic(#fnname); \ |
| 593 | } |
| 594 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 595 | PANIC(m_libc_soname, pvalloc); |
| 596 | PANIC(m_libc_soname, malloc_stats); |
| 597 | PANIC(m_libc_soname, malloc_get_state); |
| 598 | PANIC(m_libc_soname, malloc_set_state); |
| 599 | |
| 600 | |
| 601 | /*---------------------- mallinfo ----------------------*/ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 602 | |
njn | 088bfb4 | 2005-08-17 05:01:37 +0000 | [diff] [blame] | 603 | // mi must be static; if it is auto then Memcheck thinks it is |
| 604 | // uninitialised when used by the caller of this function, because Memcheck |
| 605 | // doesn't know that the call to mallinfo fills in mi. |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 606 | #define MALLINFO(soname, fnname) \ |
| 607 | \ |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 608 | struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \ |
| 609 | struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 610 | { \ |
njn | 088bfb4 | 2005-08-17 05:01:37 +0000 | [diff] [blame] | 611 | static struct vg_mallinfo mi; \ |
njn | 088bfb4 | 2005-08-17 05:01:37 +0000 | [diff] [blame] | 612 | if (!init_done) init(); \ |
sewardj | cf64bd2 | 2006-01-19 03:35:37 +0000 | [diff] [blame] | 613 | MALLOC_TRACE("mallinfo()"); \ |
njn | 088bfb4 | 2005-08-17 05:01:37 +0000 | [diff] [blame] | 614 | (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \ |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 615 | return mi; \ |
| 616 | } |
| 617 | |
sewardj | ec92a07 | 2006-10-17 01:50:31 +0000 | [diff] [blame] | 618 | MALLINFO(m_libc_soname, mallinfo); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 619 | |
| 620 | |
| 621 | /* All the code in here is unused until this function is called */ |
| 622 | |
| 623 | static void init(void) |
| 624 | { |
| 625 | int res; |
| 626 | |
| 627 | if (init_done) |
| 628 | return; |
| 629 | |
| 630 | init_done = 1; |
| 631 | |
sewardj | 0ec07f3 | 2006-01-12 12:32:32 +0000 | [diff] [blame] | 632 | VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info, |
sewardj | 9af10a1 | 2006-02-01 14:59:42 +0000 | [diff] [blame] | 633 | 0, 0, 0, 0); |
sewardj | 9ee81f5 | 2005-04-02 17:38:59 +0000 | [diff] [blame] | 634 | } |
| 635 | |
| 636 | /*--------------------------------------------------------------------*/ |
| 637 | /*--- end vg_replace_malloc.c ---*/ |
| 638 | /*--------------------------------------------------------------------*/ |