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-2015 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 #elif defined(VGO_solaris)
309 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
310 ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
311 ALLOC_or_NULL(VG_Z_LIBUMEM_SO_1, malloc, malloc);
312 ALLOC_or_NULL(SO_SYN_MALLOC, malloc, malloc);
313
314 #endif
315
316
317 /*---------------------- new ----------------------*/
318
319 #if defined(VGO_linux)
320 // operator new(unsigned int), not mangled (for gcc 2.96)
321 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
322 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
323 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
324 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
325 // operator new(unsigned int), GNU mangling
326 #if VG_WORDSIZE == 4
327 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
328 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
329 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new);
330 #endif
331 // operator new(unsigned long), GNU mangling
332 #if VG_WORDSIZE == 8
333 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
334 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
335 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new);
336 #endif
337
338 #elif defined(VGO_darwin)
339 // operator new(unsigned int), GNU mangling
340 #if VG_WORDSIZE == 4
341 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
342 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
343 #endif
344 // operator new(unsigned long), GNU mangling
345 #if 1 // FIXME: is this right?
346 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
347 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
348 #endif
349
350 #elif defined(VGO_solaris)
351 // operator new(unsigned int), GNU mangling
352 #if VG_WORDSIZE == 4
353 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
354 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new);
355 #endif
356 // operator new(unsigned long), GNU mangling
357 #if VG_WORDSIZE == 8
358 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
359 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new);
360 #endif
361
362 #endif
363
364
365 /*---------------------- new nothrow ----------------------*/
366
367 #if defined(VGO_linux)
368 // operator new(unsigned, std::nothrow_t const&), GNU mangling
369 #if VG_WORDSIZE == 4
370 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
371 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
372 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new);
373 #endif
374 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
375 #if VG_WORDSIZE == 8
376 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
377 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
378 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new);
379 #endif
380
381 #elif defined(VGO_darwin)
382 // operator new(unsigned, std::nothrow_t const&), GNU mangling
383 #if VG_WORDSIZE == 4
384 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
385 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
386 #endif
387 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
388 #if 1 // FIXME: is this right?
389 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
390 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
391 #endif
392
393 #elif defined(VGO_solaris)
394 // operator new(unsigned, std::nothrow_t const&), GNU mangling
395 #if VG_WORDSIZE == 4
396 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
397 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new);
398 #endif
399 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
400 #if VG_WORDSIZE == 8
401 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
402 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new);
403 #endif
404
405 #endif
406
407
408 /*---------------------- new [] ----------------------*/
409
410 #if defined(VGO_linux)
411 // operator new[](unsigned int), not mangled (for gcc 2.96)
412 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
413 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
414 // operator new[](unsigned int), GNU mangling
415 #if VG_WORDSIZE == 4
416 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
417 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
418 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new );
419 #endif
420 // operator new[](unsigned long), GNU mangling
421 #if VG_WORDSIZE == 8
422 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
423 ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
424 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new );
425 #endif
426
427 #elif defined(VGO_darwin)
428 // operator new[](unsigned int), GNU mangling
429 #if VG_WORDSIZE == 4
430 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
431 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
432 #endif
433 // operator new[](unsigned long), GNU mangling
434 #if 1 // FIXME: is this right?
435 //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
436 //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
437 #endif
438
439 #elif defined(VGO_solaris)
440 // operator new[](unsigned int), GNU mangling
441 #if VG_WORDSIZE == 4
442 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
443 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new );
444 #endif
445 // operator new[](unsigned long), GNU mangling
446 #if VG_WORDSIZE == 8
447 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
448 ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new );
449 #endif
450
451 #endif
452
453
454 /*---------------------- new [] nothrow ----------------------*/
455
456 #if defined(VGO_linux)
457 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
458 #if VG_WORDSIZE == 4
459 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
460 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
461 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new );
462 #endif
463 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
464 #if VG_WORDSIZE == 8
465 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
466 ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
467 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new );
468 #endif
469
470 #elif defined(VGO_darwin)
471 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
472 #if VG_WORDSIZE == 4
473 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
474 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
475 #endif
476 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
477 #if 1 // FIXME: is this right?
478 //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
479 //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
480 #endif
481
482 #elif defined(VGO_solaris)
483 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
484 #if VG_WORDSIZE == 4
485 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
486 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new );
487 #endif
488 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
489 #if VG_WORDSIZE == 8
490 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
491 ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new );
492 #endif
493
494 #endif
495
496
497 /*---------------------- free ----------------------*/
498
499 /* Generate a replacement for 'fnname' in object 'soname', which calls
500 'vg_replacement' to free previously allocated memory.
501 */
502 #define ZONEFREE(soname, fnname, vg_replacement) \
503 \
504 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
505 void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
506 { \
507 DO_INIT; \
508 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
509 MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
510 if (p == NULL) \
511 return; \
512 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
513 }
514
515 #define FREE(soname, fnname, vg_replacement) \
516 \
517 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
518 void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
519 { \
520 DO_INIT; \
521 MALLOC_TRACE(#fnname "(%p)\n", p ); \
522 if (p == NULL) \
523 return; \
524 (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
525 }
526
527
528 #if defined(VGO_linux)
529 FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
530 FREE(VG_Z_LIBC_SONAME, free, free );
531 FREE(SO_SYN_MALLOC, free, free );
532
533 #elif defined(VGO_darwin)
534 FREE(VG_Z_LIBC_SONAME, free, free );
535 FREE(SO_SYN_MALLOC, free, free );
536 ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
537 ZONEFREE(SO_SYN_MALLOC, malloc_zone_free, free );
538
539 #elif defined(VGO_solaris)
540 FREE(VG_Z_LIBC_SONAME, free, free );
541 FREE(VG_Z_LIBUMEM_SO_1, free, free );
542 FREE(SO_SYN_MALLOC, free, free );
543
544 #endif
545
546
547 /*---------------------- cfree ----------------------*/
548
549 // cfree
550 #if defined(VGO_linux)
551 FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
552 FREE(VG_Z_LIBC_SONAME, cfree, free );
553 FREE(SO_SYN_MALLOC, cfree, free );
554
555 #elif defined(VGO_darwin)
556 //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
557 //FREE(VG_Z_LIBC_SONAME, cfree, free );
558
559 #elif defined(VGO_solaris)
560 FREE(VG_Z_LIBC_SONAME, cfree, free );
561 /* libumem does not implement cfree(). */
562 //FREE(VG_Z_LIBUMEM_SO_1, cfree, free );
563 FREE(SO_SYN_MALLOC, cfree, free );
564
565 #endif
566
567
568 /*---------------------- delete ----------------------*/
569
570 #if defined(VGO_linux)
571 // operator delete(void*), not mangled (for gcc 2.96)
572 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
573 FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
574 // operator delete(void*), GNU mangling
575 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
576 FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
577 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete );
578
579 #elif defined(VGO_darwin)
580 // operator delete(void*), GNU mangling
581 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
582 //FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
583
584 #elif defined(VGO_solaris)
585 // operator delete(void*), GNU mangling
586 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
587 FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete );
588
589 #endif
590
591
592 /*---------------------- delete nothrow ----------------------*/
593
594 #if defined(VGO_linux)
595 // operator delete(void*, std::nothrow_t const&), GNU mangling
596 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
597 FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
598 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete );
599
600 #elif defined(VGO_darwin)
601 // operator delete(void*, std::nothrow_t const&), GNU mangling
602 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
603 //FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
604
605 #elif defined(VGO_solaris)
606 // operator delete(void*, std::nothrow_t const&), GNU mangling
607 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
608 FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete );
609
610 #endif
611
612
613 /*---------------------- delete [] ----------------------*/
614
615 #if defined(VGO_linux)
616 // operator delete[](void*), not mangled (for gcc 2.96)
617 FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
618 FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
619 // operator delete[](void*), GNU mangling
620 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
621 FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
622 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete );
623
624 #elif defined(VGO_darwin)
625 // operator delete[](void*), not mangled (for gcc 2.96)
626 //FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
627 //FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
628 // operator delete[](void*), GNU mangling
629 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
630 //FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
631
632 #elif defined(VGO_solaris)
633 // operator delete[](void*), GNU mangling
634 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
635 FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete );
636
637 #endif
638
639
640 /*---------------------- delete [] nothrow ----------------------*/
641
642 #if defined(VGO_linux)
643 // operator delete[](void*, std::nothrow_t const&), GNU mangling
644 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
645 FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
646 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
647
648 #elif defined(VGO_darwin)
649 // operator delete[](void*, std::nothrow_t const&), GNU mangling
650 //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
651 //FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
652
653 #elif defined(VGO_solaris)
654 // operator delete[](void*, std::nothrow_t const&), GNU mangling
655 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
656 FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
657
658 #endif
659
660
661 /*---------------------- calloc ----------------------*/
662
663 #define ZONECALLOC(soname, fnname) \
664 \
665 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
666 ( void *zone, SizeT nmemb, SizeT size ); \
667 void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
668 ( void *zone, SizeT nmemb, SizeT size ) \
669 { \
670 void* v; \
671 \
672 DO_INIT; \
673 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
674 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \
675 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
676 MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
677 \
678 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
679 MALLOC_TRACE(" = %p\n", v ); \
680 return v; \
681 }
682
683 #define CALLOC(soname, fnname) \
684 \
685 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
686 ( SizeT nmemb, SizeT size ); \
687 void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
688 ( SizeT nmemb, SizeT size ) \
689 { \
690 void* v; \
691 \
692 DO_INIT; \
693 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
694 \
695 /* Protect against overflow. See bug 24078. (that bug number is
696 invalid. Which one really?) */ \
697 /* But don't use division, since that produces an external symbol
698 reference on ARM, in the form of a call to __aeabi_uidiv. It's
699 normally OK, because ld.so manages to resolve it to something in the
700 executable, or one of its shared objects. But that isn't guaranteed
701 to be the case, and it has been observed to fail in rare cases, eg:
702 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
703 So instead compute the high word of the product and check it is zero. */ \
704 if (umulHW(size, nmemb) != 0) return NULL; \
705 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
706 MALLOC_TRACE(" = %p\n", v ); \
707 return v; \
708 }
709
710 #if defined(VGO_linux)
711 CALLOC(VG_Z_LIBC_SONAME, calloc);
712 CALLOC(SO_SYN_MALLOC, calloc);
713
714 #elif defined(VGO_darwin)
715 CALLOC(VG_Z_LIBC_SONAME, calloc);
716 CALLOC(SO_SYN_MALLOC, calloc);
717 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
718 ZONECALLOC(SO_SYN_MALLOC, malloc_zone_calloc);
719
720 #elif defined(VGO_solaris)
721 CALLOC(VG_Z_LIBC_SONAME, calloc);
722 CALLOC(VG_Z_LIBUMEM_SO_1, calloc);
723 CALLOC(SO_SYN_MALLOC, calloc);
724
725 #endif
726
727
728 /*---------------------- realloc ----------------------*/
729
730 #define ZONEREALLOC(soname, fnname) \
731 \
732 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
733 ( void *zone, void* ptrV, SizeT new_size ); \
734 void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
735 ( void *zone, void* ptrV, SizeT new_size ) \
736 { \
737 void* v; \
738 \
739 DO_INIT; \
740 MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
741 \
742 if (ptrV == NULL) \
743 /* We need to call a malloc-like function; so let's use \
744 one which we know exists. GrP fixme use zonemalloc instead? */ \
745 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
746 (new_size); \
747 if (new_size <= 0) { \
748 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
749 MALLOC_TRACE(" = 0\n"); \
750 return NULL; \
751 } \
752 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
753 MALLOC_TRACE(" = %p\n", v ); \
754 return v; \
755 }
756
757 #define REALLOC(soname, fnname) \
758 \
759 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
760 ( void* ptrV, SizeT new_size );\
761 void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
762 ( void* ptrV, SizeT new_size ) \
763 { \
764 void* v; \
765 \
766 DO_INIT; \
767 MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
768 \
769 if (ptrV == NULL) \
770 /* We need to call a malloc-like function; so let's use \
771 one which we know exists. */ \
772 return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
773 (new_size); \
774 if (new_size <= 0) { \
775 VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
776 MALLOC_TRACE(" = 0\n"); \
777 return NULL; \
778 } \
779 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
780 MALLOC_TRACE(" = %p\n", v ); \
781 return v; \
782 }
783
784 #if defined(VGO_linux)
785 REALLOC(VG_Z_LIBC_SONAME, realloc);
786 REALLOC(SO_SYN_MALLOC, realloc);
787
788 #elif defined(VGO_darwin)
789 REALLOC(VG_Z_LIBC_SONAME, realloc);
790 REALLOC(SO_SYN_MALLOC, realloc);
791 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
792 ZONEREALLOC(SO_SYN_MALLOC, malloc_zone_realloc);
793
794 #elif defined(VGO_solaris)
795 REALLOC(VG_Z_LIBC_SONAME, realloc);
796 REALLOC(VG_Z_LIBUMEM_SO_1, realloc);
797 REALLOC(SO_SYN_MALLOC, realloc);
798
799 #endif
800
801
802 /*---------------------- memalign ----------------------*/
803
804 #define ZONEMEMALIGN(soname, fnname) \
805 \
806 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
807 ( void *zone, SizeT alignment, SizeT n ); \
808 void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
809 ( void *zone, SizeT alignment, SizeT n ) \
810 { \
811 void* v; \
812 \
813 DO_INIT; \
814 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
815 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
816 MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
817 zone, (ULong)alignment, (ULong)n ); \
818 \
819 /* Round up to minimum alignment if necessary. */ \
820 if (alignment < VG_MIN_MALLOC_SZB) \
821 alignment = VG_MIN_MALLOC_SZB; \
822 \
823 /* Round up to nearest power-of-two if necessary (like glibc). */ \
824 while (0 != (alignment & (alignment - 1))) alignment++; \
825 \
826 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
827 MALLOC_TRACE(" = %p\n", v ); \
828 return v; \
829 }
830
831 #define MEMALIGN(soname, fnname) \
832 \
833 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
834 ( SizeT alignment, SizeT n ); \
835 void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
836 ( SizeT alignment, SizeT n ) \
837 { \
838 void* v; \
839 \
840 DO_INIT; \
841 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
842 MALLOC_TRACE("memalign(al %llu, size %llu)", \
843 (ULong)alignment, (ULong)n ); \
844 \
845 /* Round up to minimum alignment if necessary. */ \
846 if (alignment < VG_MIN_MALLOC_SZB) \
847 alignment = VG_MIN_MALLOC_SZB; \
848 \
849 /* Round up to nearest power-of-two if necessary (like glibc). */ \
850 while (0 != (alignment & (alignment - 1))) alignment++; \
851 \
852 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
853 MALLOC_TRACE(" = %p\n", v ); \
854 return v; \
855 }
856
857 #if defined(VGO_linux)
858 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
859 MEMALIGN(SO_SYN_MALLOC, memalign);
860
861 #elif defined(VGO_darwin)
862 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
863 MEMALIGN(SO_SYN_MALLOC, memalign);
864 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
865 ZONEMEMALIGN(SO_SYN_MALLOC, malloc_zone_memalign);
866
867 #elif defined(VGO_solaris)
868 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
869 MEMALIGN(VG_Z_LIBUMEM_SO_1, memalign);
870 MEMALIGN(SO_SYN_MALLOC, memalign);
871
872 #endif
873
874
875 /*---------------------- valloc ----------------------*/
876
877 #define VALLOC(soname, fnname) \
878 \
879 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
880 void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
881 { \
882 static int pszB = 0; \
883 if (pszB == 0) \
884 pszB = my_getpagesize(); \
885 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
886 ((SizeT)pszB, size); \
887 }
888
889 #define ZONEVALLOC(soname, fnname) \
890 \
891 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
892 ( void *zone, SizeT size ); \
893 void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
894 ( void *zone, SizeT size ) \
895 { \
896 static int pszB = 0; \
897 if (pszB == 0) \
898 pszB = my_getpagesize(); \
899 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
900 return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
901 ((SizeT)pszB, size); \
902 }
903
904 #if defined(VGO_linux)
905 VALLOC(VG_Z_LIBC_SONAME, valloc);
906 VALLOC(SO_SYN_MALLOC, valloc);
907
908 #elif defined(VGO_darwin)
909 VALLOC(VG_Z_LIBC_SONAME, valloc);
910 VALLOC(SO_SYN_MALLOC, valloc);
911 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
912 ZONEVALLOC(SO_SYN_MALLOC, malloc_zone_valloc);
913
914 #elif defined(VGO_solaris)
915 VALLOC(VG_Z_LIBC_SONAME, valloc);
916 VALLOC(VG_Z_LIBUMEM_SO_1, valloc);
917 VALLOC(SO_SYN_MALLOC, valloc);
918
919 #endif
920
921
922 /*---------------------- mallopt ----------------------*/
923
924 /* Various compatibility wrapper functions, for glibc and libstdc++. */
925
926 #define MALLOPT(soname, fnname) \
927 \
928 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
929 int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
930 { \
931 /* In glibc-2.2.4, 1 denotes a successful return value for \
932 mallopt */ \
933 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
934 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
935 return 1; \
936 }
937
938 #if defined(VGO_linux)
939 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
940 MALLOPT(SO_SYN_MALLOC, mallopt);
941
942 #elif defined(VGO_darwin)
943 //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
944
945 #endif
946
947
948 /*---------------------- malloc_trim ----------------------*/
949 // Documentation says:
950 // malloc_trim(size_t pad);
951 //
952 // If possible, gives memory back to the system (via negative arguments to
953 // sbrk) if there is unused memory at the `high' end of the malloc pool.
954 // You can call this after freeing large blocks of memory to potentially
955 // reduce the system-level memory requirements of a program. However, it
956 // cannot guarantee to reduce memory. Under some allocation patterns,
957 // some large free blocks of memory will be locked between two used
958 // chunks, so they cannot be given back to the system.
959 //
960 // The `pad' argument to malloc_trim represents the amount of free
961 // trailing space to leave untrimmed. If this argument is zero, only the
962 // minimum amount of memory to maintain internal data structures will be
963 // left (one page or less). Non-zero arguments can be supplied to maintain
964 // enough trailing space to service future expected allocations without
965 // having to re-obtain memory from the system.
966 //
967 // Malloc_trim returns 1 if it actually released any memory, else 0. On
968 // systems that do not support "negative sbrks", it will always return 0.
969 //
970 // For simplicity, we always return 0.
971 #define MALLOC_TRIM(soname, fnname) \
972 \
973 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
974 int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
975 { \
976 /* 0 denotes that malloc_trim() either wasn't able \
977 to do anything, or was not implemented */ \
978 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(pad); \
979 return 0; \
980 }
981
982 #if defined(VGO_linux)
983 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
984 MALLOC_TRIM(SO_SYN_MALLOC, malloc_trim);
985
986 #elif defined(VGO_darwin)
987 //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
988
989 #endif
990
991
992 /*---------------------- posix_memalign ----------------------*/
993
994 #define POSIX_MEMALIGN(soname, fnname) \
995 \
996 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
997 ( void **memptr, SizeT alignment, SizeT size ); \
998 int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
999 ( void **memptr, SizeT alignment, SizeT size ) \
1000 { \
1001 void *mem; \
1002 \
1003 /* Test whether the alignment argument is valid. It must be \
1004 a power of two multiple of sizeof (void *). */ \
1005 if (alignment % sizeof (void *) != 0 \
1006 || (alignment & (alignment - 1)) != 0) \
1007 return VKI_EINVAL; \
1008 \
1009 mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
1010 (alignment, size); \
1011 \
1012 if (mem != NULL) { \
1013 *memptr = mem; \
1014 return 0; \
1015 } \
1016 \
1017 return VKI_ENOMEM; \
1018 }
1019
1020 #if defined(VGO_linux)
1021 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1022 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign);
1023
1024 #elif defined(VGO_darwin)
1025 //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1026
1027 #elif defined(VGO_solaris)
1028 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
1029 POSIX_MEMALIGN(SO_SYN_MALLOC, posix_memalign);
1030
1031 #endif
1032
1033
1034 /*---------------------- malloc_usable_size ----------------------*/
1035
1036 #define MALLOC_USABLE_SIZE(soname, fnname) \
1037 \
1038 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
1039 SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
1040 { \
1041 SizeT pszB; \
1042 \
1043 DO_INIT; \
1044 MALLOC_TRACE("malloc_usable_size(%p)", p ); \
1045 if (NULL == p) \
1046 return 0; \
1047 \
1048 pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
1049 MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
1050 \
1051 return pszB; \
1052 }
1053
1054 #if defined(VGO_linux)
1055 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
1056 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_usable_size);
1057 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
1058 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
1059 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
1060 || defined(VGPV_mips32_linux_android)
1061 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
1062 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, dlmalloc_usable_size);
1063 # endif
1064
1065 #elif defined(VGO_darwin)
1066 //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
1067 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
1068 MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size);
1069
1070 #endif
1071
1072
1073 /*---------------------- (unimplemented) ----------------------*/
1074
1075 /* Bomb out if we get any of these. */
1076
1077 static void panic(const char *str) __attribute__((unused));
panic(const char * str)1078 static void panic(const char *str)
1079 {
1080 VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
1081 my_exit(1);
1082 }
1083
1084 #define PANIC(soname, fnname) \
1085 \
1086 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
1087 void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
1088 { \
1089 panic(#fnname); \
1090 }
1091
1092 #if defined(VGO_linux)
1093 PANIC(VG_Z_LIBC_SONAME, pvalloc);
1094 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1095 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1096
1097 #elif defined(VGO_darwin)
1098 PANIC(VG_Z_LIBC_SONAME, pvalloc);
1099 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
1100 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
1101
1102 #endif
1103
1104
1105 #define MALLOC_STATS(soname, fnname) \
1106 \
1107 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
1108 void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
1109 { \
1110 /* Valgrind's malloc_stats implementation does nothing. */ \
1111 }
1112
1113 #if defined(VGO_linux)
1114 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1115 MALLOC_STATS(SO_SYN_MALLOC, malloc_stats);
1116
1117 #elif defined(VGO_darwin)
1118 //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
1119
1120 #endif
1121
1122
1123 /*---------------------- mallinfo ----------------------*/
1124
1125 // mi must be static; if it is auto then Memcheck thinks it is
1126 // uninitialised when used by the caller of this function, because Memcheck
1127 // doesn't know that the call to mallinfo fills in mi.
1128 #define MALLINFO(soname, fnname) \
1129 \
1130 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
1131 struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
1132 { \
1133 static struct vg_mallinfo mi; \
1134 DO_INIT; \
1135 MALLOC_TRACE("mallinfo()\n"); \
1136 (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
1137 return mi; \
1138 }
1139
1140 #if defined(VGO_linux)
1141 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1142 MALLINFO(SO_SYN_MALLOC, mallinfo);
1143
1144 #elif defined(VGO_darwin)
1145 //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
1146
1147 #endif
1148
1149
1150 /*------------------ Darwin zone stuff ------------------*/
1151
1152 #if defined(VGO_darwin)
1153
my_malloc_size(void * zone,void * ptr)1154 static size_t my_malloc_size ( void* zone, void* ptr )
1155 {
1156 /* Implement "malloc_size" by handing the request through to the
1157 tool's .tl_usable_size method. */
1158 DO_INIT;
1159 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);
1160 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) ptr);
1161 size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
1162 info.tl_malloc_usable_size, ptr);
1163 return res;
1164 }
1165
1166 /* Note that the (void*) casts below are a kludge which stops
1167 compilers complaining about the fact that the replacement
1168 functions aren't really of the right type. */
1169 static vki_malloc_zone_t vg_default_zone = {
1170 NULL, // reserved1
1171 NULL, // reserved2
1172 (void*)my_malloc_size, // JRS fixme: is this right?
1173 (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
1174 (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
1175 (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
1176 (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
1177 (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
1178 NULL, // GrP fixme: destroy
1179 "ValgrindMallocZone",
1180 NULL, // batch_malloc
1181 NULL, // batch_free
1182 NULL, // GrP fixme: introspect
1183 2, // version (GrP fixme 3?)
1184 (void*)VG_REPLACE_FUNCTION_EZU(10100,VG_Z_LIBC_SONAME,malloc_zone_memalign), // DDD: this field exists in Mac OS 10.6+
1185 NULL, /* free_definite_size */
1186 NULL, /* pressure_relief */
1187 };
1188
1189
1190 #define DEFAULT_ZONE(soname, fnname) \
1191 \
1192 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
1193 void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
1194 { \
1195 return &vg_default_zone; \
1196 }
1197
1198 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
1199 DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_zone);
1200 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_purgeable_zone);
1201 DEFAULT_ZONE(SO_SYN_MALLOC, malloc_default_purgeable_zone);
1202
1203
1204 #define CREATE_ZONE(soname, fnname) \
1205 \
1206 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl); \
1207 void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl) \
1208 { \
1209 return &vg_default_zone; \
1210 }
1211 CREATE_ZONE(VG_Z_LIBC_SONAME, malloc_create_zone);
1212
1213
1214 #define ZONE_FROM_PTR(soname, fnname) \
1215 \
1216 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
1217 void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ) \
1218 { \
1219 return &vg_default_zone; \
1220 }
1221
1222 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
1223 ZONE_FROM_PTR(SO_SYN_MALLOC, malloc_zone_from_ptr);
1224
1225
1226 // GrP fixme bypass libc's use of zone->introspect->check
1227 #define ZONE_CHECK(soname, fnname) \
1228 \
1229 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
1230 int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone) \
1231 { \
1232 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1233 panic(#fnname); \
1234 return 1; \
1235 }
1236
1237 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
1238 ZONE_CHECK(SO_SYN_MALLOC, malloc_zone_check);
1239
1240
1241 #define ZONE_REGISTER(soname, fnname) \
1242 \
1243 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
1244 void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone) \
1245 { \
1246 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1247 }
1248
1249 ZONE_REGISTER(VG_Z_LIBC_SONAME, malloc_zone_register);
1250 ZONE_REGISTER(SO_SYN_MALLOC, malloc_zone_register);
1251
1252
1253 #define ZONE_UNREGISTER(soname, fnname) \
1254 \
1255 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
1256 void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone) \
1257 { \
1258 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1259 }
1260
1261 ZONE_UNREGISTER(VG_Z_LIBC_SONAME, malloc_zone_unregister);
1262 ZONE_UNREGISTER(SO_SYN_MALLOC, malloc_zone_unregister);
1263
1264
1265 #define ZONE_SET_NAME(soname, fnname) \
1266 \
1267 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm); \
1268 void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm) \
1269 { \
1270 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1271 }
1272
1273 ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_set_zone_name);
1274 ZONE_SET_NAME(SO_SYN_MALLOC, malloc_set_zone_name);
1275
1276
1277 #define ZONE_GET_NAME(soname, fnname) \
1278 \
1279 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
1280 const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone) \
1281 { \
1282 TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
1283 return vg_default_zone.zone_name; \
1284 }
1285
1286 ZONE_GET_NAME(VG_Z_LIBC_SONAME, malloc_get_zone_name);
1287 ZONE_GET_NAME(SO_SYN_MALLOC, malloc_get_zone_name);
1288
1289 #endif /* defined(VGO_darwin) */
1290
1291
1292 /*------------------ (startup related) ------------------*/
1293
1294 /* All the code in here is unused until this function is called */
1295
1296 __attribute__((constructor))
init(void)1297 static void init(void)
1298 {
1299 // This doesn't look thread-safe, but it should be ok... Bart says:
1300 //
1301 // Every program I know of calls malloc() at least once before calling
1302 // pthread_create(). So init_done gets initialized before any thread is
1303 // created, and is only read when multiple threads are active
1304 // simultaneously. Such an access pattern is safe.
1305 //
1306 // If the assignment to the variable init_done would be triggering a race
1307 // condition, both DRD and Helgrind would report this race.
1308 //
1309 // By the way, although the init() function in
1310 // coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
1311 // __attribute__((constructor)), it is not safe to remove the variable
1312 // init_done. This is because it is possible that malloc() and hence
1313 // init() gets called before shared library initialization finished.
1314 //
1315 if (init_done)
1316 return;
1317
1318 init_done = 1;
1319
1320 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
1321 0, 0, 0, 0);
1322 }
1323
1324 /*--------------------------------------------------------------------*/
1325 /*--- end ---*/
1326 /*--------------------------------------------------------------------*/
1327