[powerpc] Tighten contraints for asm constant parameters
[glibc.git] / malloc / malloc-debug.c
blob3d7e6d44fdc9e17b8bb0ea6738974b611c464459
1 /* Malloc debug DSO.
2 Copyright (C) 2021 Free Software Foundation, Inc.
3 Copyright The GNU Toolchain Authors.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If
18 not, see <https://www.gnu.org/licenses/>. */
20 #include <atomic.h>
21 #include <libc-symbols.h>
22 #include <shlib-compat.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/param.h>
27 #if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_34)
28 /* Support only the glibc allocators. */
29 extern void *__libc_malloc (size_t);
30 extern void __libc_free (void *);
31 extern void *__libc_realloc (void *, size_t);
32 extern void *__libc_memalign (size_t, size_t);
33 extern void *__libc_valloc (size_t);
34 extern void *__libc_pvalloc (size_t);
35 extern void *__libc_calloc (size_t, size_t);
37 #define DEBUG_FN(fn) \
38 static __typeof (__libc_ ## fn) __debug_ ## fn
40 DEBUG_FN(malloc);
41 DEBUG_FN(free);
42 DEBUG_FN(realloc);
43 DEBUG_FN(memalign);
44 DEBUG_FN(valloc);
45 DEBUG_FN(pvalloc);
46 DEBUG_FN(calloc);
48 static int debug_initialized = -1;
50 enum malloc_debug_hooks
52 MALLOC_NONE_HOOK = 0,
53 MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck() */
54 MALLOC_MTRACE_HOOK = 1 << 1, /* mtrace() */
55 MALLOC_CHECK_HOOK = 1 << 2, /* MALLOC_CHECK_ or glibc.malloc.check. */
57 static unsigned __malloc_debugging_hooks;
59 static __always_inline bool
60 __is_malloc_debug_enabled (enum malloc_debug_hooks flag)
62 return __malloc_debugging_hooks & flag;
65 static __always_inline void
66 __malloc_debug_enable (enum malloc_debug_hooks flag)
68 __malloc_debugging_hooks |= flag;
71 static __always_inline void
72 __malloc_debug_disable (enum malloc_debug_hooks flag)
74 __malloc_debugging_hooks &= ~flag;
77 #include "mcheck.c"
78 #include "mtrace.c"
79 #include "malloc-check.c"
81 #if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
82 extern void (*__malloc_initialize_hook) (void);
83 compat_symbol_reference (libc, __malloc_initialize_hook,
84 __malloc_initialize_hook, GLIBC_2_0);
85 #endif
87 static void *malloc_hook_ini (size_t, const void *) __THROW;
88 static void *realloc_hook_ini (void *, size_t, const void *) __THROW;
89 static void *memalign_hook_ini (size_t, size_t, const void *) __THROW;
91 void (*__free_hook) (void *, const void *) = NULL;
92 void *(*__malloc_hook) (size_t, const void *) = malloc_hook_ini;
93 void *(*__realloc_hook) (void *, size_t, const void *) = realloc_hook_ini;
94 void *(*__memalign_hook) (size_t, size_t, const void *) = memalign_hook_ini;
96 /* Hooks for debugging versions. The initial hooks just call the
97 initialization routine, then do the normal work. */
99 /* These hooks will get executed only through the interposed allocator
100 functions in libc_malloc_debug.so. This means that the calls to malloc,
101 realloc, etc. will lead back into the interposed functions, which is what we
102 want.
104 These initial hooks are assumed to be called in a single-threaded context,
105 so it is safe to reset all hooks at once upon initialization. */
107 static void
108 generic_hook_ini (void)
110 debug_initialized = 0;
111 __malloc_hook = NULL;
112 __realloc_hook = NULL;
113 __memalign_hook = NULL;
115 /* malloc check does not quite co-exist with libc malloc, so initialize
116 either on or the other. */
117 if (!initialize_malloc_check ())
118 /* The compiler does not know that these functions are allocators, so it
119 will not try to optimize it away. */
120 __libc_free (__libc_malloc (0));
122 #if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
123 void (*hook) (void) = __malloc_initialize_hook;
124 if (hook != NULL)
125 (*hook)();
126 #endif
128 debug_initialized = 1;
131 static void *
132 malloc_hook_ini (size_t sz, const void *caller)
134 generic_hook_ini ();
135 return __debug_malloc (sz);
138 static void *
139 realloc_hook_ini (void *ptr, size_t sz, const void *caller)
141 generic_hook_ini ();
142 return __debug_realloc (ptr, sz);
145 static void *
146 memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
148 generic_hook_ini ();
149 return __debug_memalign (alignment, sz);
152 static size_t pagesize;
154 /* These variables are used for undumping support. Chunked are marked
155 as using mmap, but we leave them alone if they fall into this
156 range. NB: The chunk size for these chunks only includes the
157 initial size field (of SIZE_SZ bytes), there is no trailing size
158 field (unlike with regular mmapped chunks). */
159 static mchunkptr dumped_main_arena_start; /* Inclusive. */
160 static mchunkptr dumped_main_arena_end; /* Exclusive. */
162 /* True if the pointer falls into the dumped arena. Use this after
163 chunk_is_mmapped indicates a chunk is mmapped. */
164 #define DUMPED_MAIN_ARENA_CHUNK(p) \
165 ((p) >= dumped_main_arena_start && (p) < dumped_main_arena_end)
167 /* The allocator functions. */
169 static void *
170 __debug_malloc (size_t bytes)
172 void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
173 if (__builtin_expect (hook != NULL, 0))
174 return (*hook)(bytes, RETURN_ADDRESS (0));
176 void *victim = NULL;
177 size_t orig_bytes = bytes;
178 if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
179 || !malloc_mcheck_before (&bytes, &victim)))
181 victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
182 ? malloc_check (bytes) : __libc_malloc (bytes));
184 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
185 victim = malloc_mcheck_after (victim, orig_bytes);
186 if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
187 malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
189 return victim;
191 strong_alias (__debug_malloc, malloc)
193 static void
194 __debug_free (void *mem)
196 void (*hook) (void *, const void *) = atomic_forced_read (__free_hook);
197 if (__builtin_expect (hook != NULL, 0))
199 (*hook)(mem, RETURN_ADDRESS (0));
200 return;
203 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
204 mem = free_mcheck (mem);
206 if (DUMPED_MAIN_ARENA_CHUNK (mem2chunk (mem)))
207 /* Do nothing. */;
208 else if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
209 free_check (mem);
210 else
211 __libc_free (mem);
212 if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
213 free_mtrace (mem, RETURN_ADDRESS (0));
215 strong_alias (__debug_free, free)
217 static void *
218 __debug_realloc (void *oldmem, size_t bytes)
220 void *(*hook) (void *, size_t, const void *) =
221 atomic_forced_read (__realloc_hook);
222 if (__builtin_expect (hook != NULL, 0))
223 return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
225 size_t orig_bytes = bytes, oldsize = 0;
226 void *victim = NULL;
228 if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
229 || !realloc_mcheck_before (&oldmem, &bytes, &oldsize, &victim)))
231 mchunkptr oldp = mem2chunk (oldmem);
233 /* If this is a faked mmapped chunk from the dumped main arena,
234 always make a copy (and do not free the old chunk). */
235 if (DUMPED_MAIN_ARENA_CHUNK (oldp))
237 if (bytes == 0 && oldmem != NULL)
238 victim = NULL;
239 else
241 const INTERNAL_SIZE_T osize = chunksize (oldp);
242 /* Must alloc, copy, free. */
243 victim = __debug_malloc (bytes);
244 /* Copy as many bytes as are available from the old chunk
245 and fit into the new size. NB: The overhead for faked
246 mmapped chunks is only SIZE_SZ, not CHUNK_HDR_SZ as for
247 regular mmapped chunks. */
248 if (victim != NULL)
250 if (bytes > osize - SIZE_SZ)
251 bytes = osize - SIZE_SZ;
252 memcpy (victim, oldmem, bytes);
256 else if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
257 victim = realloc_check (oldmem, bytes);
258 else
259 victim = __libc_realloc (oldmem, bytes);
261 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
262 victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
263 oldsize);
264 if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
265 realloc_mtrace_after (victim, oldmem, orig_bytes, RETURN_ADDRESS (0));
267 return victim;
269 strong_alias (__debug_realloc, realloc)
271 static void *
272 _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
274 void *(*hook) (size_t, size_t, const void *) =
275 atomic_forced_read (__memalign_hook);
276 if (__builtin_expect (hook != NULL, 0))
277 return (*hook)(alignment, bytes, address);
279 void *victim = NULL;
280 size_t orig_bytes = bytes;
282 if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
283 || !memalign_mcheck_before (alignment, &bytes, &victim)))
285 victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
286 ? memalign_check (alignment, bytes)
287 : __libc_memalign (alignment, bytes));
289 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
290 victim = memalign_mcheck_after (victim, alignment, orig_bytes);
291 if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
292 memalign_mtrace_after (victim, orig_bytes, address);
294 return victim;
297 static void *
298 __debug_memalign (size_t alignment, size_t bytes)
300 return _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
302 strong_alias (__debug_memalign, memalign)
303 strong_alias (__debug_memalign, aligned_alloc)
305 static void *
306 __debug_pvalloc (size_t bytes)
308 size_t rounded_bytes;
310 if (!pagesize)
311 pagesize = sysconf (_SC_PAGESIZE);
313 /* ALIGN_UP with overflow check. */
314 if (__glibc_unlikely (__builtin_add_overflow (bytes,
315 pagesize - 1,
316 &rounded_bytes)))
318 errno = ENOMEM;
319 return NULL;
321 rounded_bytes = rounded_bytes & -(pagesize - 1);
323 return _debug_mid_memalign (pagesize, rounded_bytes, RETURN_ADDRESS (0));
325 strong_alias (__debug_pvalloc, pvalloc)
327 static void *
328 __debug_valloc (size_t bytes)
330 if (!pagesize)
331 pagesize = sysconf (_SC_PAGESIZE);
333 return _debug_mid_memalign (pagesize, bytes, RETURN_ADDRESS (0));
335 strong_alias (__debug_valloc, valloc)
337 static int
338 __debug_posix_memalign (void **memptr, size_t alignment, size_t bytes)
340 /* Test whether the SIZE argument is valid. It must be a power of
341 two multiple of sizeof (void *). */
342 if (alignment % sizeof (void *) != 0
343 || !powerof2 (alignment / sizeof (void *))
344 || alignment == 0)
345 return EINVAL;
347 *memptr = _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
349 if (*memptr == NULL)
350 return ENOMEM;
352 return 0;
354 strong_alias (__debug_posix_memalign, posix_memalign)
356 static void *
357 __debug_calloc (size_t nmemb, size_t size)
359 size_t bytes;
361 if (__glibc_unlikely (__builtin_mul_overflow (nmemb, size, &bytes)))
363 errno = ENOMEM;
364 return NULL;
367 void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
368 if (__builtin_expect (hook != NULL, 0))
370 void *mem = (*hook)(bytes, RETURN_ADDRESS (0));
372 if (mem != NULL)
373 memset (mem, 0, bytes);
375 return mem;
378 size_t orig_bytes = bytes;
379 void *victim = NULL;
381 if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
382 || !malloc_mcheck_before (&bytes, &victim)))
384 victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
385 ? malloc_check (bytes) : __libc_malloc (bytes));
387 if (victim != NULL)
389 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
390 victim = malloc_mcheck_after (victim, orig_bytes);
391 memset (victim, 0, orig_bytes);
393 if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
394 malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
396 return victim;
398 strong_alias (__debug_calloc, calloc)
400 size_t
401 malloc_usable_size (void *mem)
403 if (mem == NULL)
404 return 0;
406 if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
407 return mcheck_usable_size (mem);
408 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
409 return malloc_check_get_size (mem);
411 mchunkptr p = mem2chunk (mem);
412 if (DUMPED_MAIN_ARENA_CHUNK (p))
413 return chunksize (p) - SIZE_SZ;
415 return musable (mem);
418 #define LIBC_SYMBOL(sym) libc_ ## sym
419 #define SYMHANDLE(sym) sym ## _handle
421 #define LOAD_SYM(sym) ({ \
422 static void *SYMHANDLE (sym); \
423 if (SYMHANDLE (sym) == NULL) \
424 SYMHANDLE (sym) = dlsym (RTLD_NEXT, #sym); \
425 SYMHANDLE (sym); \
429 malloc_info (int options, FILE *fp)
431 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
432 return __malloc_info (options, fp);
434 int (*LIBC_SYMBOL (malloc_info)) (int, FILE *) = LOAD_SYM (malloc_info);
435 if (LIBC_SYMBOL (malloc_info) == NULL)
436 return -1;
438 return LIBC_SYMBOL (malloc_info) (options, fp);
442 mallopt (int param_number, int value)
444 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
445 return __libc_mallopt (param_number, value);
447 int (*LIBC_SYMBOL (mallopt)) (int, int) = LOAD_SYM (mallopt);
448 if (LIBC_SYMBOL (mallopt) == NULL)
449 return 0;
451 return LIBC_SYMBOL (mallopt) (param_number, value);
454 void
455 malloc_stats (void)
457 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
458 return __malloc_stats ();
460 void (*LIBC_SYMBOL (malloc_stats)) (void) = LOAD_SYM (malloc_stats);
461 if (LIBC_SYMBOL (malloc_stats) == NULL)
462 return;
464 LIBC_SYMBOL (malloc_stats) ();
467 struct mallinfo2
468 mallinfo2 (void)
470 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
471 return __libc_mallinfo2 ();
473 struct mallinfo2 (*LIBC_SYMBOL (mallinfo2)) (void) = LOAD_SYM (mallinfo2);
474 if (LIBC_SYMBOL (mallinfo2) == NULL)
476 struct mallinfo2 ret = {0};
477 return ret;
480 return LIBC_SYMBOL (mallinfo2) ();
483 struct mallinfo
484 mallinfo (void)
486 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
487 return __libc_mallinfo ();
489 struct mallinfo (*LIBC_SYMBOL (mallinfo)) (void) = LOAD_SYM (mallinfo);
490 if (LIBC_SYMBOL (mallinfo) == NULL)
492 struct mallinfo ret = {0};
493 return ret;
496 return LIBC_SYMBOL (mallinfo) ();
500 malloc_trim (size_t s)
502 if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
503 return __malloc_trim (s);
505 int (*LIBC_SYMBOL (malloc_trim)) (size_t) = LOAD_SYM (malloc_trim);
506 if (LIBC_SYMBOL (malloc_trim) == NULL)
507 return 0;
509 return LIBC_SYMBOL (malloc_trim) (s);
512 #if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_25)
514 /* Support for restoring dumped heaps contained in historic Emacs
515 executables. The heap saving feature (malloc_get_state) is no
516 longer implemented in this version of glibc, but we have a heap
517 rewriter in malloc_set_state which transforms the heap into a
518 version compatible with current malloc. */
520 #define MALLOC_STATE_MAGIC 0x444c4541l
521 #define MALLOC_STATE_VERSION (0 * 0x100l + 5l) /* major*0x100 + minor */
523 struct malloc_save_state
525 long magic;
526 long version;
527 mbinptr av[NBINS * 2 + 2];
528 char *sbrk_base;
529 int sbrked_mem_bytes;
530 unsigned long trim_threshold;
531 unsigned long top_pad;
532 unsigned int n_mmaps_max;
533 unsigned long mmap_threshold;
534 int check_action;
535 unsigned long max_sbrked_mem;
536 unsigned long max_total_mem; /* Always 0, for backwards compatibility. */
537 unsigned int n_mmaps;
538 unsigned int max_n_mmaps;
539 unsigned long mmapped_mem;
540 unsigned long max_mmapped_mem;
541 int using_malloc_checking;
542 unsigned long max_fast;
543 unsigned long arena_test;
544 unsigned long arena_max;
545 unsigned long narenas;
548 /* Dummy implementation which always fails. We need to provide this
549 symbol so that existing Emacs binaries continue to work with
550 BIND_NOW. */
551 void *
552 malloc_get_state (void)
554 __set_errno (ENOSYS);
555 return NULL;
557 compat_symbol (libc_malloc_debug, malloc_get_state, malloc_get_state,
558 GLIBC_2_0);
561 malloc_set_state (void *msptr)
563 struct malloc_save_state *ms = (struct malloc_save_state *) msptr;
565 if (ms->magic != MALLOC_STATE_MAGIC)
566 return -1;
568 /* Must fail if the major version is too high. */
569 if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
570 return -2;
572 if (debug_initialized == 1)
573 return -1;
575 bool check_was_enabled = __is_malloc_debug_enabled (MALLOC_CHECK_HOOK);
577 /* It's not too late, so disable MALLOC_CHECK_ and all of the hooks. */
578 __malloc_hook = NULL;
579 __realloc_hook = NULL;
580 __free_hook = NULL;
581 __memalign_hook = NULL;
582 __malloc_debug_disable (MALLOC_CHECK_HOOK);
584 /* We do not need to perform locking here because malloc_set_state
585 must be called before the first call into the malloc subsytem (usually via
586 __malloc_initialize_hook). pthread_create always calls calloc and thus
587 must be called only afterwards, so there cannot be more than one thread
588 when we reach this point. Also handle initialization if either we ended
589 up being called before the first malloc or through the hook when
590 malloc-check was enabled. */
591 if (debug_initialized < 0)
592 generic_hook_ini ();
593 else if (check_was_enabled)
594 __libc_free (__libc_malloc (0));
596 /* Patch the dumped heap. We no longer try to integrate into the
597 existing heap. Instead, we mark the existing chunks as mmapped.
598 Together with the update to dumped_main_arena_start and
599 dumped_main_arena_end, realloc and free will recognize these
600 chunks as dumped fake mmapped chunks and never free them. */
602 /* Find the chunk with the lowest address with the heap. */
603 mchunkptr chunk = NULL;
605 size_t *candidate = (size_t *) ms->sbrk_base;
606 size_t *end = (size_t *) (ms->sbrk_base + ms->sbrked_mem_bytes);
607 while (candidate < end)
608 if (*candidate != 0)
610 chunk = mem2chunk ((void *) (candidate + 1));
611 break;
613 else
614 ++candidate;
616 if (chunk == NULL)
617 return 0;
619 /* Iterate over the dumped heap and patch the chunks so that they
620 are treated as fake mmapped chunks. */
621 mchunkptr top = ms->av[2];
622 while (chunk < top)
624 if (inuse (chunk))
626 /* Mark chunk as mmapped, to trigger the fallback path. */
627 size_t size = chunksize (chunk);
628 set_head (chunk, size | IS_MMAPPED);
630 chunk = next_chunk (chunk);
633 /* The dumped fake mmapped chunks all lie in this address range. */
634 dumped_main_arena_start = (mchunkptr) ms->sbrk_base;
635 dumped_main_arena_end = top;
637 return 0;
639 compat_symbol (libc_malloc_debug, malloc_set_state, malloc_set_state,
640 GLIBC_2_0);
641 #endif
643 /* Do not allow linking against the library. */
644 compat_symbol (libc_malloc_debug, aligned_alloc, aligned_alloc, GLIBC_2_16);
645 compat_symbol (libc_malloc_debug, calloc, calloc, GLIBC_2_0);
646 compat_symbol (libc_malloc_debug, free, free, GLIBC_2_0);
647 compat_symbol (libc_malloc_debug, mallinfo2, mallinfo2, GLIBC_2_33);
648 compat_symbol (libc_malloc_debug, mallinfo, mallinfo, GLIBC_2_0);
649 compat_symbol (libc_malloc_debug, malloc_info, malloc_info, GLIBC_2_10);
650 compat_symbol (libc_malloc_debug, malloc, malloc, GLIBC_2_0);
651 compat_symbol (libc_malloc_debug, malloc_stats, malloc_stats, GLIBC_2_0);
652 compat_symbol (libc_malloc_debug, malloc_trim, malloc_trim, GLIBC_2_0);
653 compat_symbol (libc_malloc_debug, malloc_usable_size, malloc_usable_size,
654 GLIBC_2_0);
655 compat_symbol (libc_malloc_debug, mallopt, mallopt, GLIBC_2_0);
656 compat_symbol (libc_malloc_debug, mcheck_check_all, mcheck_check_all,
657 GLIBC_2_2);
658 compat_symbol (libc_malloc_debug, mcheck, mcheck, GLIBC_2_0);
659 compat_symbol (libc_malloc_debug, mcheck_pedantic, mcheck_pedantic, GLIBC_2_2);
660 compat_symbol (libc_malloc_debug, memalign, memalign, GLIBC_2_0);
661 compat_symbol (libc_malloc_debug, mprobe, mprobe, GLIBC_2_0);
662 compat_symbol (libc_malloc_debug, mtrace, mtrace, GLIBC_2_0);
663 compat_symbol (libc_malloc_debug, muntrace, muntrace, GLIBC_2_0);
664 compat_symbol (libc_malloc_debug, posix_memalign, posix_memalign, GLIBC_2_2);
665 compat_symbol (libc_malloc_debug, pvalloc, pvalloc, GLIBC_2_0);
666 compat_symbol (libc_malloc_debug, realloc, realloc, GLIBC_2_0);
667 compat_symbol (libc_malloc_debug, valloc, valloc, GLIBC_2_0);
668 compat_symbol (libc_malloc_debug, __free_hook, __free_hook, GLIBC_2_0);
669 compat_symbol (libc_malloc_debug, __malloc_hook, __malloc_hook, GLIBC_2_0);
670 compat_symbol (libc_malloc_debug, __realloc_hook, __realloc_hook, GLIBC_2_0);
671 compat_symbol (libc_malloc_debug, __memalign_hook, __memalign_hook, GLIBC_2_0);
672 #endif