njn | 3e88418 | 2003-04-15 13:03:23 +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, an extensible x86 protected-mode |
| 9 | emulator for monitoring program execution on x86-Unixes. |
| 10 | |
nethercote | bb1c991 | 2004-01-04 16:43:23 +0000 | [diff] [blame] | 11 | Copyright (C) 2000-2004 Julian Seward |
njn | 3e88418 | 2003-04-15 13:03:23 +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 | /* --------------------------------------------------------------------- |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 33 | All the code in this file runs on the SIMULATED CPU. It is intended |
| 34 | for various reasons as drop-in replacements for malloc() and friends. |
| 35 | These functions have global scope, but are not intended to be called |
| 36 | directly. See the comments in coregrind/vg_intercept.c.base for the |
| 37 | gory details. |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 38 | |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 39 | This file can be linked into the injected so file for any tool that |
| 40 | wishes to know about calls to malloc(). It should define functions |
| 41 | SK_(malloc) et al that will be called. |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 42 | ------------------------------------------------------------------ */ |
| 43 | |
njn | 7271864 | 2003-07-24 08:45:32 +0000 | [diff] [blame] | 44 | #include "valgrind.h" /* for VALGRIND_NON_SIMD_CALL[12] */ |
rjwalsh | 7109a8c | 2004-09-02 00:31:02 +0000 | [diff] [blame] | 45 | #include "core.h" |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 46 | |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 47 | #define LIBALIAS(ret, name, args) \ |
| 48 | ret VG_INTERCEPT(soname:libstdc++*, __libc_##name) args \ |
| 49 | __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name)), \ |
| 50 | visibility("protected"))); \ |
| 51 | ret VG_INTERCEPT(soname:libc.so.6, __libc_##name) args \ |
| 52 | __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name)), \ |
| 53 | visibility("protected"))); \ |
| 54 | ret VG_INTERCEPT(soname:libstdc++*, __##name) args \ |
| 55 | __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name)), \ |
| 56 | visibility("protected"))); \ |
| 57 | ret VG_INTERCEPT(soname:libc.so.6, __##name) args \ |
| 58 | __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name)), \ |
| 59 | visibility("protected"))); \ |
| 60 | ret VG_INTERCEPT(soname:libstdc++*, ##name) args \ |
| 61 | __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name)), \ |
| 62 | visibility("protected"))); \ |
| 63 | ret VG_INTERCEPT(soname:libc.so.6, ##name) args |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 64 | |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 65 | extern void _exit(int); |
| 66 | |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 67 | /*------------------------------------------------------------*/ |
| 68 | /*--- Replacing malloc() et al ---*/ |
| 69 | /*------------------------------------------------------------*/ |
| 70 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 71 | static struct vg_mallocfunc_info info; |
| 72 | static int init_done; |
| 73 | |
| 74 | /* Startup hook - called as init section */ |
| 75 | static void init(void) __attribute__((constructor)); |
| 76 | |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 77 | /* Below are new versions of malloc, __builtin_new, free, |
| 78 | __builtin_delete, calloc, realloc, memalign, and friends. |
| 79 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 80 | None of these functions are called directly - they are not meant to |
| 81 | be found by the dynamic linker. They get called because |
| 82 | vg_replace_malloc installs a bunch of code redirects which causes |
| 83 | Valgrind to use these functions rather than the ones they're |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 84 | replacing. |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 85 | */ |
| 86 | |
| 87 | #define MALLOC_TRACE(format, args...) \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 88 | if (info.clo_trace_malloc) \ |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 89 | VALGRIND_INTERNAL_PRINTF(format, ## args ) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 90 | |
| 91 | #define MAYBE_SLOPPIFY(n) \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 92 | if (info.clo_sloppy_malloc) { \ |
nethercote | 2d5b816 | 2004-08-11 09:40:52 +0000 | [diff] [blame] | 93 | n = (n+(VG_SLOPPY_MALLOC_SZB-1)) & ~(VG_SLOPPY_MALLOC_SZB-1); \ |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 94 | } |
| 95 | |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 96 | /* ALL calls to malloc() and friends wind up here. */ |
| 97 | #define ALLOC(fff, vgfff) \ |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 98 | LIBALIAS(void *, fff, (SizeT n)) \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 99 | { \ |
| 100 | void* v; \ |
| 101 | \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 102 | MALLOC_TRACE(#fff "(%d)", n ); \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 103 | MAYBE_SLOPPIFY(n); \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 104 | if (!init_done) init(); \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 105 | \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 106 | v = (void*)VALGRIND_NON_SIMD_CALL1( info.sk_##vgfff, n ); \ |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 107 | MALLOC_TRACE(" = %p", v ); \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 108 | return v; \ |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 109 | } |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 110 | |
| 111 | #define ALLOC2(fff, vgfff) \ |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 112 | LIBALIAS(void *, fff, (SizeT n)) \ |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 113 | { \ |
| 114 | void* v; \ |
| 115 | \ |
| 116 | MALLOC_TRACE(#fff "(%d)", n ); \ |
| 117 | MAYBE_SLOPPIFY(n); \ |
| 118 | if (!init_done) init(); \ |
| 119 | \ |
| 120 | v = (void*)VALGRIND_NON_SIMD_CALL1( info.sk_##vgfff, n ); \ |
| 121 | MALLOC_TRACE(" = %p", v ); \ |
| 122 | if (NULL == v) { \ |
| 123 | VALGRIND_PRINTF_BACKTRACE( \ |
| 124 | "new/new[] failed and should throw an exception, but Valgrind\n" \ |
| 125 | " cannot throw exceptions and so is aborting instead. Sorry."); \ |
| 126 | _exit(1); \ |
| 127 | } \ |
| 128 | return v; \ |
| 129 | } |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 130 | ALLOC( malloc, malloc ); |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 131 | ALLOC2(__builtin_new, __builtin_new ); |
| 132 | ALLOC2(_Znwj, __builtin_new ); |
njn | 5cebf57 | 2003-10-09 15:40:38 +0000 | [diff] [blame] | 133 | |
| 134 | // operator new(unsigned, std::nothrow_t const&) |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 135 | ALLOC( _ZnwjRKSt9nothrow_t, __builtin_new ); |
njn | 5cebf57 | 2003-10-09 15:40:38 +0000 | [diff] [blame] | 136 | |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 137 | ALLOC2(__builtin_vec_new, __builtin_vec_new ); |
| 138 | ALLOC2(_Znaj, __builtin_vec_new ); |
njn | 5cebf57 | 2003-10-09 15:40:38 +0000 | [diff] [blame] | 139 | |
nethercote | d6447b4 | 2004-07-15 16:28:36 +0000 | [diff] [blame] | 140 | // operator new[](unsigned, std::nothrow_t const&) |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 141 | ALLOC( _ZnajRKSt9nothrow_t, __builtin_vec_new ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 142 | |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 143 | #define FREE(fff, vgfff) \ |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 144 | LIBALIAS(void, fff, (void *p)) \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 145 | { \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 146 | MALLOC_TRACE(#fff "(%p)", p ); \ |
njn | d0eab5f | 2003-09-30 16:52:47 +0000 | [diff] [blame] | 147 | if (p == NULL) \ |
| 148 | return; \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 149 | if (!init_done) init(); \ |
| 150 | (void)VALGRIND_NON_SIMD_CALL1( info.sk_##vgfff, p ); \ |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 151 | } |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 152 | FREE( free, free ); |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 153 | FREE( cfree, free ); |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 154 | FREE( __builtin_delete, __builtin_delete ); |
| 155 | FREE( _ZdlPv, __builtin_delete ); |
nethercote | 23cd8c0 | 2004-07-14 15:38:06 +0000 | [diff] [blame] | 156 | |
| 157 | // operator delete(void*, std::nothrow_t const&) |
| 158 | FREE( _ZdlPvRKSt9nothrow_t, __builtin_delete ); |
| 159 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 160 | FREE( __builtin_vec_delete, __builtin_vec_delete ); |
| 161 | FREE( _ZdaPv, __builtin_vec_delete ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 162 | |
nethercote | 23cd8c0 | 2004-07-14 15:38:06 +0000 | [diff] [blame] | 163 | // operator delete[](void*, std::nothrow_t const&) |
| 164 | FREE( _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); |
| 165 | |
| 166 | |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 167 | LIBALIAS(void*, calloc, ( SizeT nmemb, SizeT size )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 168 | { |
| 169 | void* v; |
| 170 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 171 | MALLOC_TRACE("calloc(%d,%d)", nmemb, size ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 172 | MAYBE_SLOPPIFY(size); |
| 173 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 174 | if (!init_done) init(); |
| 175 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.sk_calloc, nmemb, size ); |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 176 | MALLOC_TRACE(" = %p", v ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 177 | return v; |
| 178 | } |
| 179 | |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 180 | LIBALIAS(void*, realloc, ( void* ptrV, SizeT new_size )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 181 | { |
| 182 | void* v; |
| 183 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 184 | MALLOC_TRACE("realloc(%p,%d)", ptrV, new_size ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 185 | MAYBE_SLOPPIFY(new_size); |
| 186 | |
| 187 | if (ptrV == NULL) |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 188 | return VG_INTERCEPT(soname:libc.so.6, malloc)(new_size); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 189 | if (new_size <= 0) { |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 190 | VG_INTERCEPT(soname:libc.so.6, free)(ptrV); |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 191 | if (info.clo_trace_malloc) |
| 192 | VALGRIND_INTERNAL_PRINTF(" = 0" ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 193 | return NULL; |
| 194 | } |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 195 | if (!init_done) init(); |
| 196 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.sk_realloc, ptrV, new_size ); |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 197 | MALLOC_TRACE(" = %p", v ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 198 | return v; |
| 199 | } |
| 200 | |
| 201 | |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 202 | LIBALIAS(void*, memalign, ( SizeT alignment, SizeT n )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 203 | { |
| 204 | void* v; |
| 205 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 206 | MALLOC_TRACE("memalign(al %d, size %d)", alignment, n ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 207 | MAYBE_SLOPPIFY(n); |
| 208 | |
nethercote | 2d5b816 | 2004-08-11 09:40:52 +0000 | [diff] [blame] | 209 | // Round up to minimum alignment if necessary. |
| 210 | if (alignment < VG_MIN_MALLOC_SZB) alignment = VG_MIN_MALLOC_SZB; |
| 211 | |
| 212 | // Round up to nearest power-of-two if necessary (like glibc). |
| 213 | while (0 != (alignment & (alignment - 1))) alignment++; |
| 214 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 215 | if (!init_done) init(); |
| 216 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.sk_memalign, alignment, n ); |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 217 | MALLOC_TRACE(" = %p", v ); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 218 | return v; |
| 219 | } |
| 220 | |
| 221 | |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 222 | LIBALIAS(void*, valloc, ( SizeT size )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 223 | { |
nethercote | 5d4ac83 | 2004-10-31 18:58:05 +0000 | [diff] [blame] | 224 | return VG_INTERCEPT(soname:libc.so.6, memalign)(VKI_PAGE_SIZE, size); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | |
| 228 | /* Various compatibility wrapper functions, for glibc and libstdc++. */ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 229 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 230 | LIBALIAS(int, mallopt, ( int cmd, int value )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 231 | { |
| 232 | /* In glibc-2.2.4, 1 denotes a successful return value for mallopt */ |
| 233 | return 1; |
| 234 | } |
| 235 | |
| 236 | |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 237 | LIBALIAS(int, posix_memalign, ( void **memptr, SizeT alignment, SizeT size )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 238 | { |
| 239 | void *mem; |
| 240 | |
mueller | 211d05d | 2003-11-28 00:15:57 +0000 | [diff] [blame] | 241 | /* Test whether the alignment argument is valid. It must be a power of |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 242 | two multiple of sizeof (void *). */ |
mueller | 211d05d | 2003-11-28 00:15:57 +0000 | [diff] [blame] | 243 | if (alignment % sizeof (void *) != 0 || (alignment & (alignment - 1)) != 0) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 244 | return VKI_EINVAL /*22*/ /*EINVAL*/; |
| 245 | |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 246 | mem = VG_INTERCEPT(soname:libc.so.6, memalign)(alignment, size); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 247 | |
| 248 | if (mem != NULL) { |
| 249 | *memptr = mem; |
| 250 | return 0; |
| 251 | } |
| 252 | |
| 253 | return VKI_ENOMEM /*12*/ /*ENOMEM*/; |
| 254 | } |
| 255 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 256 | LIBALIAS(int, malloc_usable_size, ( void* p )) |
njn | 8a6b6c0 | 2003-04-22 22:45:55 +0000 | [diff] [blame] | 257 | { |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 258 | SizeT pszB; |
njn | 8a6b6c0 | 2003-04-22 22:45:55 +0000 | [diff] [blame] | 259 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 260 | MALLOC_TRACE("malloc_usable_size(%p)", p ); |
njn | 8a6b6c0 | 2003-04-22 22:45:55 +0000 | [diff] [blame] | 261 | if (NULL == p) |
| 262 | return 0; |
| 263 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 264 | if (!init_done) init(); |
nethercote | 928a5f7 | 2004-11-03 18:10:37 +0000 | [diff] [blame] | 265 | pszB = (SizeT)VALGRIND_NON_SIMD_CALL2( info.arena_payload_szB, |
| 266 | VG_AR_CLIENT, p ); |
fitzhardinge | 7fae3e0 | 2003-10-31 07:13:41 +0000 | [diff] [blame] | 267 | MALLOC_TRACE(" = %d", pszB ); |
njn | 8a6b6c0 | 2003-04-22 22:45:55 +0000 | [diff] [blame] | 268 | |
| 269 | return pszB; |
| 270 | } |
| 271 | |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 272 | |
| 273 | /* Bomb out if we get any of these. */ |
njn | 8a6b6c0 | 2003-04-22 22:45:55 +0000 | [diff] [blame] | 274 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 275 | static void panic(const char *str) |
| 276 | { |
| 277 | VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s", str); |
| 278 | |
| 279 | _exit(99); |
| 280 | *(int *)0 = 'x'; |
| 281 | } |
| 282 | |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 283 | #define PANIC(x) \ |
| 284 | void VG_INTERCEPT(soname:libc.so.6, ## x)(void) \ |
| 285 | { \ |
| 286 | panic(#x); \ |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 287 | } |
| 288 | |
| 289 | PANIC(pvalloc); |
| 290 | PANIC(malloc_stats); |
| 291 | PANIC(malloc_trim); |
| 292 | PANIC(malloc_get_state); |
| 293 | PANIC(malloc_set_state); |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 294 | |
| 295 | |
| 296 | /* Yet another ugly hack. Cannot include <malloc.h> because we |
| 297 | implement functions implemented there with different signatures. |
| 298 | This struct definition MUST match the system one. */ |
| 299 | |
| 300 | /* SVID2/XPG mallinfo structure */ |
| 301 | struct mallinfo { |
| 302 | int arena; /* total space allocated from system */ |
| 303 | int ordblks; /* number of non-inuse chunks */ |
| 304 | int smblks; /* unused -- always zero */ |
| 305 | int hblks; /* number of mmapped regions */ |
| 306 | int hblkhd; /* total space in mmapped regions */ |
| 307 | int usmblks; /* unused -- always zero */ |
| 308 | int fsmblks; /* unused -- always zero */ |
| 309 | int uordblks; /* total allocated space */ |
| 310 | int fordblks; /* total non-inuse space */ |
| 311 | int keepcost; /* top-most, releasable (via malloc_trim) space */ |
| 312 | }; |
| 313 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 314 | LIBALIAS(struct mallinfo, mallinfo, ( void )) |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 315 | { |
| 316 | /* Should really try to return something a bit more meaningful */ |
sewardj | 05bcdcb | 2003-05-18 10:05:38 +0000 | [diff] [blame] | 317 | UInt i; |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 318 | struct mallinfo mi; |
| 319 | UChar* pmi = (UChar*)(&mi); |
| 320 | for (i = 0; i < sizeof(mi); i++) |
| 321 | pmi[i] = 0; |
| 322 | return mi; |
| 323 | } |
| 324 | |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 325 | /* All the code in here is unused until this function is called */ |
| 326 | |
| 327 | static void init(void) |
| 328 | { |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 329 | int res; |
| 330 | |
| 331 | if (init_done) |
| 332 | return; |
| 333 | |
| 334 | init_done = 1; |
| 335 | |
rjwalsh | e4e779d | 2004-04-16 23:02:29 +0000 | [diff] [blame] | 336 | VALGRIND_MAGIC_SEQUENCE(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info, |
| 337 | 0, 0, 0); |
fitzhardinge | 98abfc7 | 2003-12-16 02:05:15 +0000 | [diff] [blame] | 338 | } |
| 339 | |
njn | 3e88418 | 2003-04-15 13:03:23 +0000 | [diff] [blame] | 340 | /*--------------------------------------------------------------------*/ |
| 341 | /*--- end vg_replace_malloc.c ---*/ |
| 342 | /*--------------------------------------------------------------------*/ |