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