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
11 Copyright (C) 2000-2013 Julian Seward
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 /* ---------------------------------------------------------------------
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.
38
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
41 the functions that will be called via 'info'.
42
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.
45
46 IMPORTANT: this file must not contain any floating point code, nor
47 any integer division. This is because on ARM these can cause calls
48 to helper functions, which will be unresolved within this .so.
49 Although it is usually the case that the client's ld.so instance
50 can bind them at runtime to the relevant functions in the client
51 executable, there is no guarantee of this; and so the client may
52 die via a runtime link failure. Hence the only safe approach is to
53 avoid such function calls in the first place. See "#define CALLOC"
54 below for a specific example.
55
56 A useful command is
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
59 done
60
61 to see all the undefined symbols in all the preload shared objects.
62 ------------------------------------------------------------------ */
63
64 #include "pub_core_basics.h"
65 #include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM
66 #include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF,
67 // VALGRIND_NON_SIMD_CALL[12]
68 #include "pub_core_debuginfo.h" // needed for pub_core_redir.h :(
69 #include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
70 #include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_*
71 #include "pub_core_replacemalloc.h"
72
73 /* Assignment of behavioural equivalence class tags: 1NNNP is intended
74 to be reserved for the Valgrind core. Current usage:
75
76 10010 ALLOC_or_NULL
77 10020 ZONEALLOC_or_NULL
78 10030 ALLOC_or_BOMB
79 10040 ZONEFREE
80 10050 FREE
81 10060 ZONECALLOC
82 10070 CALLOC
83 10080 ZONEREALLOC
84 10090 REALLOC
85 10100 ZONEMEMALIGN
86 10110 MEMALIGN
87 10120 VALLOC
88 10130 ZONEVALLOC
89 10140 MALLOPT
90 10150 MALLOC_TRIM
91 10160 POSIX_MEMALIGN
92 10170 MALLOC_USABLE_SIZE
93 10180 PANIC
94 10190 MALLOC_STATS
95 10200 MALLINFO
96 10210 DEFAULT_ZONE
97 10220 CREATE_ZONE
98 10230 ZONE_FROM_PTR
99 10240 ZONE_CHECK
100 10250 ZONE_REGISTER
101 10260 ZONE_UNREGISTER
102 10270 ZONE_SET_NAME
103 10280 ZONE_GET_NAME
104 */
105
106 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
107 mangling, could be supported properly by the redirects in this
108 module. Except we can't because it doesn't put its allocation
109 functions in libpgc.so but instead hardwires them into the
110 compilation unit holding main(), which makes them impossible to
111 intercept directly. Fortunately those fns seem to route everything
112 through to malloc/free.
113
114 mid-06: could be improved, since we can now intercept in the main
115 executable too.
116 */
117
118
119
120 /* Call here to exit if we can't continue. On Android we can't call
121 _exit for some reason, so we have to blunt-instrument it. */
122 __attribute__ ((__noreturn__))
my_exit(int x)123 static inline void my_exit ( int x )
124 {
125 # if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
126 || defined(VGPV_arm64_linux_android)
127 __asm__ __volatile__(".word 0xFFFFFFFF");
128 while (1) {}
129 # elif defined(VGPV_x86_linux_android)
130 __asm__ __volatile__("ud2");
131 while (1) {}
132 # else
133 extern __attribute__ ((__noreturn__)) void _exit(int status);
134 _exit(x);
135 # endif
136 }
137
138 /* Same problem with getpagesize. */
my_getpagesize(void)139 static inline int my_getpagesize ( void )
140 {
141 # if defined(VGPV_arm_linux_android) \
142 || defined(VGPV_x86_linux_android) \
143 || defined(VGPV_mips32_linux_android) \
144 || defined(VGPV_arm64_linux_android)
145 return 4096; /* kludge - link failure on Android, for some reason */
146 # else
147 extern int getpagesize (void);
148 return getpagesize();
149 # endif
150 }
151
152
153 /* Compute the high word of the double-length unsigned product of U
154 and V. This is for calloc argument overflow checking; see comments
155 below. Algorithm as described in Hacker's Delight, chapter 8. */
umulHW(UWord u,UWord v)156 static UWord umulHW ( UWord u, UWord v )
157 {
158 UWord u0, v0, w0, rHi;
159 UWord u1, v1, w1,w2,t;
160 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF
161 : (UWord)0xFFFFFFFFULL;
162 UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
163 u0 = u & halfMask;
164 u1 = u >> halfShift;
165 v0 = v & halfMask;
166 v1 = v >> halfShift;
167 w0 = u0 * v0;
168 t = u1 * v0 + (w0 >> halfShift);
169 w1 = t & halfMask;
170 w2 = t >> halfShift;
171 w1 = u0 * v1 + w1;
172 rHi = u1 * v1 + w2 + (w1 >> halfShift);
173 return rHi;
174 }
175
176
177 /*------------------------------------------------------------*/
178 /*--- Replacing malloc() et al ---*/
179 /*------------------------------------------------------------*/
180
181 /* This struct is initially empty. Before the first use of any of
182 these functions, we make a client request which fills in the
183 fields.
184 */
185 static struct vg_mallocfunc_info info;
186 static int init_done;
187 #define DO_INIT if (UNLIKELY(!init_done)) init()
188
189 /* Startup hook - called as init section */
190 __attribute__((constructor))
191 static void init(void);
192
193 #define MALLOC_TRACE(format, args...) \
194 if (info.clo_trace_malloc) { \
195 VALGRIND_INTERNAL_PRINTF(format, ## args ); }
196
197 /* Below are new versions of malloc, __builtin_new, free,
198 __builtin_delete, calloc, realloc, memalign, and friends.
199
200 None of these functions are called directly - they are not meant to
201 be found by the dynamic linker. But ALL client calls to malloc()
202 and friends wind up here eventually. They get called because
203 vg_replace_malloc installs a bunch of code redirects which causes
204 Valgrind to use these functions rather than the ones they're
205 replacing.
206 */
207
208 /* The replacement functions are running on the simulated CPU.
209 The code on the simulated CPU does not necessarily use
210 all arguments. E.g. args can be ignored and/or only given
211 to a NON SIMD call.
212 The definedness of such 'unused' arguments will not be verified
213 by memcheck.
214 The macro 'TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED' allows
215 memcheck to detect such errors for the otherwise unused args.
216 Apart of allowing memcheck to detect an error, the macro
217 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED has no effect and
218 has a minimal cost for other tools replacing malloc functions.
219 */
220 #define TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(x) \
221 if ((ULong)x == 0) __asm__ __volatile__( "" ::: "memory" )
222
223 /*---------------------- malloc ----------------------*/
224
225 /* Generate a replacement for 'fnname' in object 'soname', which calls
226 'vg_replacement' to allocate memory. If that fails, return NULL.
227 */
228 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
229 \
230 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
231 void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \
232 { \
233 void* v; \
234 \
235 DO_INIT; \
236 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
237 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
238 \
239 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
240 MALLOC_TRACE(" = %p\n", v ); \
241 return v; \
242 }
243
244 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
245 \
246 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
247 void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \
248 { \
249 void* v; \
250 \
251 DO_INIT; \
252 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
253 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
254 MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
255 \
256 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
257 MALLOC_TRACE(" = %p\n", v ); \
258 return v; \
259 }
260
261
262 /* Generate a replacement for 'fnname' in object 'soname', which calls
263 'vg_replacement' to allocate memory. If that fails, it bombs the
264 system.
265 */
266 #define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
267 \
268 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
269 void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \
270 { \
271 void* v; \
272 \
273 DO_INIT; \
274 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
275 MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
276 \
277 v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
278 MALLOC_TRACE(" = %p\n", v ); \
279 if (NULL == v) { \
280 VALGRIND_PRINTF( \
281 "new/new[] failed and should throw an exception, but Valgrind\n"); \
282 VALGRIND_PRINTF_BACKTRACE( \
283 " cannot throw exceptions and so is aborting instead. Sorry.\n"); \
284 my_exit(1); \
285 } \
286 return v; \
287 }
288
289 // Each of these lines generates a replacement function:
290 // (from_so, from_fn, v's replacement)
291 // For some lines, we will also define a replacement function
292 // whose only purpose is to be a soname synonym place holder
293 // that can be replaced using --soname-synonyms.
294 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
295
296 // malloc
297 #if defined(VGO_linux)
298 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
299 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
300 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
301
302 #elif defined(VGO_darwin)
303 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
304 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
305 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
306 ZONEALLOC_or_NULL(SO_SYN_MALLOC, malloc_zone_malloc, malloc);
307
308 #endif
309
310
311 /*---------------------- new ----------------------*/
312
313 #if defined(VGO_linux)
314 // operator new(unsigned int), not mangled (for gcc 2.96)
315 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
316 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
317 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
318 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
319 // operator new(unsigned int), GNU mangling
320 #if VG_WORDSIZE == 4
321 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
322 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
323 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new);
324 #endif
325 // operator new(unsigned long), GNU mangling
326 #if VG_WORDSIZE == 8
327 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
328 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
329 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new);
330 #endif
331
332 #elif defined(VGO_darwin)
333 // operator new(unsigned int), GNU mangling
334 #if VG_WORDSIZE == 4
335 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
336 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
337 #endif
338 // operator new(unsigned long), GNU mangling
339 #if 1 // FIXME: is this right?
340 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
341 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
342 #endif
343
344 #endif
345
346
347 /*---------------------- new nothrow ----------------------*/
348
349 #if defined(VGO_linux)
350 // operator new(unsigned, std::nothrow_t const&), GNU mangling
351 #if VG_WORDSIZE == 4
352 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
353 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
354 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new);
355 #endif
356 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
357 #if VG_WORDSIZE == 8
358 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
359 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
360 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new);
361 #endif
362
363 #elif defined(VGO_darwin)
364 // operator new(unsigned, std::nothrow_t const&), GNU mangling
365 #if VG_WORDSIZE == 4
366 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
367 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
368 #endif
369 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
370 #if 1 // FIXME: is this right?
371 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
372 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
373 #endif
374
375 #endif
376
377
378 /*---------------------- new [] ----------------------*/
379
380 #if defined(VGO_linux)
381 // operator new[](unsigned int), not mangled (for gcc 2.96)
382 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
383 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
384 // operator new[](unsigned int), GNU mangling
385 #if VG_WORDSIZE == 4
386 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
387 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
388 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new );
389 #endif
390 // operator new[](unsigned long), GNU mangling
391 #if VG_WORDSIZE == 8
392 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
393 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
394 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new );
395 #endif
396
397 #elif defined(VGO_darwin)
398 // operator new[](unsigned int), GNU mangling
399 #if VG_WORDSIZE == 4
400 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
401 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
402 #endif
403 // operator new[](unsigned long), GNU mangling
404 #if 1 // FIXME: is this right?
405 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
406 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
407 #endif
408
409 #endif
410
411
412 /*---------------------- new [] nothrow ----------------------*/
413
414 #if defined(VGO_linux)
415 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
416 #if VG_WORDSIZE == 4
417 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
418 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
419 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new );
420 #endif
421 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
422 #if VG_WORDSIZE == 8
423 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
424 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
425 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new );
426 #endif
427
428 #elif defined(VGO_darwin)
429 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
430 #if VG_WORDSIZE == 4
431 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
432 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
433 #endif
434 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
435 #if 1 // FIXME: is this right?
436 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
437 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
438 #endif
439
440 #endif
441
442
443 /*---------------------- free ----------------------*/
444
445 /* Generate a replacement for 'fnname' in object 'soname', which calls
446 'vg_replacement' to free previously allocated memory.
447 */
448 #define ZONEFREE(soname, fnname, vg_replacement) \
449 \
450 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
451 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
452 { \
453 DO_INIT; \
454 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
455 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
456 if (p == NULL) \
457 return; \
458 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
459 }
460
461 #define FREE(soname, fnname, vg_replacement) \
462 \
463 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
464 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
465 { \
466 DO_INIT; \
467 MALLOC_TRACE(#fnname "(%p)\n", p ); \
468 if (p == NULL) \
469 return; \
470 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
471 }
472
473
474 #if defined(VGO_linux)
475 FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
476 FREE(VG_Z_LIBC_SONAME, free, free );
477 FREE(SO_SYN_MALLOC, free, free );
478
479 #elif defined(VGO_darwin)
480 FREE(VG_Z_LIBC_SONAME, free, free );
481 FREE(SO_SYN_MALLOC, free, free );
482 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
483 ZONEFREE(SO_SYN_MALLOC, malloc_zone_free, free );
484
485 #endif
486
487
488 /*---------------------- cfree ----------------------*/
489
490 // cfree
491 #if defined(VGO_linux)
492 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
493 FREE(VG_Z_LIBC_SONAME, cfree, free );
494 FREE(SO_SYN_MALLOC, cfree, free );
495
496 #elif defined(VGO_darwin)
497 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
498 //FREE(VG_Z_LIBC_SONAME, cfree, free );
499
500 #endif
501
502
503 /*---------------------- delete ----------------------*/
504
505 #if defined(VGO_linux)
506 // operator delete(void*), not mangled (for gcc 2.96)
507 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
508 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
509 // operator delete(void*), GNU mangling
510 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
511 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
512 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete );
513
514 #elif defined(VGO_darwin)
515 // operator delete(void*), GNU mangling
516 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
517 //FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
518
519 #endif
520
521
522 /*---------------------- delete nothrow ----------------------*/
523
524 #if defined(VGO_linux)
525 // operator delete(void*, std::nothrow_t const&), GNU mangling
526 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
527 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
528 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete );
529
530 #elif defined(VGO_darwin)
531 // operator delete(void*, std::nothrow_t const&), GNU mangling
532 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
533 //FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
534
535 #endif
536
537
538 /*---------------------- delete [] ----------------------*/
539
540 #if defined(VGO_linux)
541 // operator delete[](void*), not mangled (for gcc 2.96)
542 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
543 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
544 // operator delete[](void*), GNU mangling
545 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
546 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
547 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete );
548
549 #elif defined(VGO_darwin)
550 // operator delete[](void*), not mangled (for gcc 2.96)
551 //FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
552 //FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
553 // operator delete[](void*), GNU mangling
554 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
555 //FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
556
557 #endif
558
559
560 /*---------------------- delete [] nothrow ----------------------*/
561
562 #if defined(VGO_linux)
563 // operator delete[](void*, std::nothrow_t const&), GNU mangling
564 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
565 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
566 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
567
568 #elif defined(VGO_darwin)
569 // operator delete[](void*, std::nothrow_t const&), GNU mangling
570 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
571 //FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
572
573 #endif
574
575
576 /*---------------------- calloc ----------------------*/
577
578 #define ZONECALLOC(soname, fnname) \
579 \
580 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
581 ( void *zone, SizeT nmemb, SizeT size ); \
582 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
583 ( void *zone, SizeT nmemb, SizeT size ) \
584 { \
585 void* v; \
586 \
587 DO_INIT; \
588 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
589 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \
590 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
591 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
592 \
593 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
594 MALLOC_TRACE(" = %p\n", v ); \
595 return v; \
596 }
597
598 #define CALLOC(soname, fnname) \
599 \
600 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
601 ( SizeT nmemb, SizeT size ); \
602 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
603 ( SizeT nmemb, SizeT size ) \
604 { \
605 void* v; \
606 \
607 DO_INIT; \
608 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
609 \
610 /* Protect against overflow. See bug 24078. (that bug number is
611 invalid. Which one really?) */ \
612 /* But don't use division, since that produces an external symbol
613 reference on ARM, in the form of a call to __aeabi_uidiv. It's
614 normally OK, because ld.so manages to resolve it to something in the
615 executable, or one of its shared objects. But that isn't guaranteed
616 to be the case, and it has been observed to fail in rare cases, eg:
617 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
618 So instead compute the high word of the product and check it is zero. */ \
619 if (umulHW(size, nmemb) != 0) return NULL; \
620 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
621 MALLOC_TRACE(" = %p\n", v ); \
622 return v; \
623 }
624
625 #if defined(VGO_linux)
626 CALLOC(VG_Z_LIBC_SONAME, calloc);
627 CALLOC(SO_SYN_MALLOC, calloc);
628
629 #elif defined(VGO_darwin)
630 CALLOC(VG_Z_LIBC_SONAME, calloc);
631 CALLOC(SO_SYN_MALLOC, calloc);
632 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
633 ZONECALLOC(SO_SYN_MALLOC, malloc_zone_calloc);
634
635 #endif
636
637
638 /*---------------------- realloc ----------------------*/
639
640 #define ZONEREALLOC(soname, fnname) \
641 \
642 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
643 ( void *zone, void* ptrV, SizeT new_size ); \
644 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
645 ( void *zone, void* ptrV, SizeT new_size ) \
646 { \
647 void* v; \
648 \
649 DO_INIT; \
650 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
651 \
652 if (ptrV == NULL) \
653 /* We need to call a malloc-like function; so let's use \
654 one which we know exists. GrP fixme use zonemalloc instead? */ \
655 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
656 (new_size); \
657 if (new_size <= 0) { \
658 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
659 MALLOC_TRACE(" = 0\n"); \
660 return NULL; \
661 } \
662 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
663 MALLOC_TRACE(" = %p\n", v ); \
664 return v; \
665 }
666
667 #define REALLOC(soname, fnname) \
668 \
669 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
670 ( void* ptrV, SizeT new_size );\
671 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
672 ( void* ptrV, SizeT new_size ) \
673 { \
674 void* v; \
675 \
676 DO_INIT; \
677 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
678 \
679 if (ptrV == NULL) \
680 /* We need to call a malloc-like function; so let's use \
681 one which we know exists. */ \
682 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
683 (new_size); \
684 if (new_size <= 0) { \
685 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
686 MALLOC_TRACE(" = 0\n"); \
687 return NULL; \
688 } \
689 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
690 MALLOC_TRACE(" = %p\n", v ); \
691 return v; \
692 }
693
694 #if defined(VGO_linux)
695 REALLOC(VG_Z_LIBC_SONAME, realloc);
696 REALLOC(SO_SYN_MALLOC, realloc);
697
698 #elif defined(VGO_darwin)
699 REALLOC(VG_Z_LIBC_SONAME, realloc);
700 REALLOC(SO_SYN_MALLOC, realloc);
701 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
702 ZONEREALLOC(SO_SYN_MALLOC, malloc_zone_realloc);
703
704 #endif
705
706
707 /*---------------------- memalign ----------------------*/
708
709 #define ZONEMEMALIGN(soname, fnname) \
710 \
711 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
712 ( void *zone, SizeT alignment, SizeT n ); \
713 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
714 ( void *zone, SizeT alignment, SizeT n ) \
715 { \
716 void* v; \
717 \
718 DO_INIT; \
719 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
720 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
721 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
722 zone, (ULong)alignment, (ULong)n ); \
723 \
724 /* Round up to minimum alignment if necessary. */ \
725 if (alignment < VG_MIN_MALLOC_SZB) \
726 alignment = VG_MIN_MALLOC_SZB; \
727 \
728 /* Round up to nearest power-of-two if necessary (like glibc). */ \
729 while (0 != (alignment & (alignment - 1))) alignment++; \
730 \
731 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
732 MALLOC_TRACE(" = %p\n", v ); \
733 return v; \
734 }
735
736 #define MEMALIGN(soname, fnname) \
737 \
738 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
739 ( SizeT alignment, SizeT n ); \
740 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
741 ( SizeT alignment, SizeT n ) \
742 { \
743 void* v; \
744 \
745 DO_INIT; \
746 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
747 MALLOC_TRACE("memalign(al %llu, size %llu)", \
748 (ULong)alignment, (ULong)n ); \
749 \
750 /* Round up to minimum alignment if necessary. */ \
751 if (alignment < VG_MIN_MALLOC_SZB) \
752 alignment = VG_MIN_MALLOC_SZB; \
753 \
754 /* Round up to nearest power-of-two if necessary (like glibc). */ \
755 while (0 != (alignment & (alignment - 1))) alignment++; \
756 \
757 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
758 MALLOC_TRACE(" = %p\n", v ); \
759 return v; \
760 }
761
762 #if defined(VGO_linux)
763 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
764 MEMALIGN(SO_SYN_MALLOC, memalign);
765
766 #elif defined(VGO_darwin)
767 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
768 MEMALIGN(SO_SYN_MALLOC, memalign);
769 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
770 ZONEMEMALIGN(SO_SYN_MALLOC, malloc_zone_memalign);
771
772 #endif
773
774
775 /*---------------------- valloc ----------------------*/
776
777 #define VALLOC(soname, fnname) \
778 \
779 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
780 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
781 { \
782 static int pszB = 0; \
783 if (pszB == 0) \
784 pszB = my_getpagesize(); \
785 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
786 ((SizeT)pszB, size); \
787 }
788
789 #define ZONEVALLOC(soname, fnname) \
790 \
791 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
792 ( void *zone, SizeT size ); \
793 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
794 ( void *zone, SizeT size ) \
795 { \
796 static int pszB = 0; \
797 if (pszB == 0) \
798 pszB = my_getpagesize(); \
799 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
800 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
801 ((SizeT)pszB, size); \
802 }
803
804 #if defined(VGO_linux)
805 VALLOC(VG_Z_LIBC_SONAME, valloc);
806 VALLOC(SO_SYN_MALLOC, valloc);
807
808 #elif defined(VGO_darwin)
809 VALLOC(VG_Z_LIBC_SONAME, valloc);
810 VALLOC(SO_SYN_MALLOC, valloc);
811 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
812 ZONEVALLOC(SO_SYN_MALLOC, malloc_zone_valloc);
813
814 #endif
815
816
817 /*---------------------- mallopt ----------------------*/
818
819 /* Various compatibility wrapper functions, for glibc and libstdc++. */
820
821 #define MALLOPT(soname, fnname) \
822 \
823 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
824 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
825 { \
826 /* In glibc-2.2.4, 1 denotes a successful return value for \
827 mallopt */ \
828 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
829 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
830 return 1; \
831 }
832
833 #if defined(VGO_linux)
834 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
835 MALLOPT(SO_SYN_MALLOC, mallopt);
836
837 #elif defined(VGO_darwin)
838 //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
839
840 #endif
841
842
843 /*---------------------- malloc_trim ----------------------*/
844 // Documentation says:
845 // malloc_trim(size_t pad);
846 //
847 // If possible, gives memory back to the system (via negative arguments to
848 // sbrk) if there is unused memory at the `high' end of the malloc pool.
849 // You can call this after freeing large blocks of memory to potentially
850 // reduce the system-level memory requirements of a program. However, it
851 // cannot guarantee to reduce memory. Under some allocation patterns,
852 // some large free blocks of memory will be locked between two used
853 // chunks, so they cannot be given back to the system.
854 //
855 // The `pad' argument to malloc_trim represents the amount of free
856 // trailing space to leave untrimmed. If this argument is zero, only the
857 // minimum amount of memory to maintain internal data structures will be
858 // left (one page or less). Non-zero arguments can be supplied to maintain
859 // enough trailing space to service future expected allocations without
860 // having to re-obtain memory from the system.
861 //
862 // Malloc_trim returns 1 if it actually released any memory, else 0. On
863 // systems that do not support "negative sbrks", it will always return 0.
864 //
865 // For simplicity, we always return 0.
866 #define MALLOC_TRIM(soname, fnname) \
867 \
868 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
869 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
870 { \
871 /* 0 denotes that malloc_trim() either wasn't able \
872 to do anything, or was not implemented */ \
873 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(pad); \
874 return 0; \
875 }
876
877 #if defined(VGO_linux)
878 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
879 MALLOC_TRIM(SO_SYN_MALLOC, malloc_trim);
880
881 #elif defined(VGO_darwin)
882 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
883
884 #endif
885
886
887 /*---------------------- posix_memalign ----------------------*/
888
889 #define POSIX_MEMALIGN(soname, fnname) \
890 \
891 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
892 ( void **memptr, SizeT alignment, SizeT size ); \
893 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
894 ( void **memptr, SizeT alignment, SizeT size ) \
895 { \
896 void *mem; \
897 \
898 /* Test whether the alignment argument is valid. It must be \
899 a power of two multiple of sizeof (void *). */ \
900 if (alignment % sizeof (void *) != 0 \
901 || (alignment & (alignment - 1)) != 0) \
902 return VKI_EINVAL; \
903 \
904 mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
905 (alignment, size); \
906 \
907 if (mem != NULL) { \
908 *memptr = mem; \
909 return 0; \
910 } \
911 \
912 return VKI_ENOMEM; \
913 }
914
915 #if defined(VGO_linux)
916 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
917 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign);
918
919 #elif defined(VGO_darwin)
920 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
921
922 #endif
923
924
925 /*---------------------- malloc_usable_size ----------------------*/
926
927 #define MALLOC_USABLE_SIZE(soname, fnname) \
928 \
929 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
930 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
931 { \
932 SizeT pszB; \
933 \
934 DO_INIT; \
935 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
936 if (NULL == p) \
937 return 0; \
938 \
939 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
940 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
941 \
942 return pszB; \
943 }
944
945 #if defined(VGO_linux)
946 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
947 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_usable_size);
948 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
949 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
950 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
951 || defined(VGPV_mips32_linux_android)
952 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
953 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, dlmalloc_usable_size);
954 # endif
955
956 #elif defined(VGO_darwin)
957 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
958 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
959 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
960
961 #endif
962
963
964 /*---------------------- (unimplemented) ----------------------*/
965
966 /* Bomb out if we get any of these. */
967
panic(const char * str)968 static void panic(const char *str)
969 {
970 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
971 my_exit(99);
972 *(volatile int *)0 = 'x';
973 }
974
975 #define PANIC(soname, fnname) \
976 \
977 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
978 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
979 { \
980 panic(#fnname); \
981 }
982
983 #if defined(VGO_linux)
984 PANIC(VG_Z_LIBC_SONAME, pvalloc);
985 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
986 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
987
988 #elif defined(VGO_darwin)
989 PANIC(VG_Z_LIBC_SONAME, pvalloc);
990 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
991 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
992
993 #endif
994
995
996 #define MALLOC_STATS(soname, fnname) \
997 \
998 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
999 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
1000 { \
1001 /* Valgrind's malloc_stats implementation does nothing. */ \
1002 }
1003
1004 #if defined(VGO_linux)
1005 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1006 MALLOC_STATS(SO_SYN_MALLOC, malloc_stats);
1007
1008 #elif defined(VGO_darwin)
1009 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1010
1011 #endif
1012
1013
1014 /*---------------------- mallinfo ----------------------*/
1015
1016 // mi must be static; if it is auto then Memcheck thinks it is
1017 // uninitialised when used by the caller of this function, because Memcheck
1018 // doesn't know that the call to mallinfo fills in mi.
1019 #define MALLINFO(soname, fnname) \
1020 \
1021 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1022 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
1023 { \
1024 static struct vg_mallinfo mi; \
1025 DO_INIT; \
1026 MALLOC_TRACE("mallinfo()\n"); \
1027 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1028 return mi; \
1029 }
1030
1031 #if defined(VGO_linux)
1032 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1033 MALLINFO(SO_SYN_MALLOC, mallinfo);
1034
1035 #elif defined(VGO_darwin)
1036 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1037
1038 #endif
1039
1040
1041 /*------------------ Darwin zone stuff ------------------*/
1042
1043 #if defined(VGO_darwin)
1044
my_malloc_size(void * zone,void * ptr)1045 static size_t my_malloc_size ( void* zone, void* ptr )
1046 {
1047 /* Implement "malloc_size" by handing the request through to the
1048 tool's .tl_usable_size method. */
1049 DO_INIT;
1050 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);
1051 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) ptr);
1052 size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1053 info.tl_malloc_usable_size, ptr);
1054 return res;
1055 }
1056
1057 /* Note that the (void*) casts below are a kludge which stops
1058 compilers complaining about the fact that the the replacement
1059 functions aren't really of the right type. */
1060 static vki_malloc_zone_t vg_default_zone = {
1061 NULL, // reserved1
1062 NULL, // reserved2
1063 (void*)my_malloc_size, // JRS fixme: is this right?
1064 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1065 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1066 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1067 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1068 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
1069 NULL, // GrP fixme: destroy
1070 "ValgrindMallocZone",
1071 NULL, // batch_malloc
1072 NULL, // batch_free
1073 NULL, // GrP fixme: introspect
1074 2, // version (GrP fixme 3?)
1075 NULL, /* memalign */ // DDD: this field exists in Mac OS 10.6, but not 10.5.
1076 NULL, /* free_definite_size */
1077 NULL, /* pressure_relief */
1078 };
1079
1080
1081 #define DEFAULT_ZONE(soname, fnname) \
1082 \
1083 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1084 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
1085 { \
1086 return &vg_default_zone; \
1087 }
1088
1089 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
1090 DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_zone);
1091 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_purgeable_zone);
1092 DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_purgeable_zone);
1093
1094
1095 #define CREATE_ZONE(soname, fnname) \
1096 \
1097 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl); \
1098 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl) \
1099 { \
1100 return &vg_default_zone; \
1101 }
1102 CREATE_ZONE(VG_Z_LIBC_SONAME, malloc_create_zone);
1103
1104
1105 #define ZONE_FROM_PTR(soname, fnname) \
1106 \
1107 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
1108 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ) \
1109 { \
1110 return &vg_default_zone; \
1111 }
1112
1113 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
1114 ZONE_FROM_PTR(SO_SYN_MALLOC, malloc_zone_from_ptr);
1115
1116
1117 // GrP fixme bypass libc's use of zone->introspect->check
1118 #define ZONE_CHECK(soname, fnname) \
1119 \
1120 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
1121 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone) \
1122 { \
1123 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1124 panic(#fnname); \
1125 return 1; \
1126 }
1127
1128 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1129 ZONE_CHECK(SO_SYN_MALLOC, malloc_zone_check);
1130
1131
1132 #define ZONE_REGISTER(soname, fnname) \
1133 \
1134 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
1135 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone) \
1136 { \
1137 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1138 }
1139
1140 ZONE_REGISTER(VG_Z_LIBC_SONAME, malloc_zone_register);
1141 ZONE_REGISTER(SO_SYN_MALLOC, malloc_zone_register);
1142
1143
1144 #define ZONE_UNREGISTER(soname, fnname) \
1145 \
1146 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
1147 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone) \
1148 { \
1149 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1150 }
1151
1152 ZONE_UNREGISTER(VG_Z_LIBC_SONAME, malloc_zone_unregister);
1153 ZONE_UNREGISTER(SO_SYN_MALLOC, malloc_zone_unregister);
1154
1155
1156 #define ZONE_SET_NAME(soname, fnname) \
1157 \
1158 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm); \
1159 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm) \
1160 { \
1161 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1162 }
1163
1164 ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_set_zone_name);
1165 ZONE_SET_NAME(SO_SYN_MALLOC, malloc_set_zone_name);
1166
1167
1168 #define ZONE_GET_NAME(soname, fnname) \
1169 \
1170 char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
1171 char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone) \
1172 { \
1173 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1174 return vg_default_zone.zone_name; \
1175 }
1176
1177 ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_get_zone_name);
1178 ZONE_SET_NAME(SO_SYN_MALLOC, malloc_get_zone_name);
1179
1180 #endif /* defined(VGO_darwin) */
1181
1182
1183 /*------------------ (startup related) ------------------*/
1184
1185 /* All the code in here is unused until this function is called */
1186
1187 __attribute__((constructor))
init(void)1188 static void init(void)
1189 {
1190 // This doesn't look thread-safe, but it should be ok... Bart says:
1191 //
1192 // Every program I know of calls malloc() at least once before calling
1193 // pthread_create(). So init_done gets initialized before any thread is
1194 // created, and is only read when multiple threads are active
1195 // simultaneously. Such an access pattern is safe.
1196 //
1197 // If the assignment to the variable init_done would be triggering a race
1198 // condition, both DRD and Helgrind would report this race.
1199 //
1200 // By the way, although the init() function in
1201 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1202 // __attribute__((constructor)), it is not safe to remove the variable
1203 // init_done. This is because it is possible that malloc() and hence
1204 // init() gets called before shared library initialization finished.
1205 //
1206 if (init_done)
1207 return;
1208
1209 init_done = 1;
1210
1211 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1212 0, 0, 0, 0);
1213 }
1214
1215 /*--------------------------------------------------------------------*/
1216 /*--- end ---*/
1217 /*--------------------------------------------------------------------*/
1218