about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/mcheck.h4
-rw-r--r--malloc/Makefile3
-rw-r--r--malloc/Versions9
-rw-r--r--malloc/hooks.c61
-rw-r--r--malloc/malloc-debug.c173
-rw-r--r--malloc/mcheck-impl.c406
-rw-r--r--malloc/mcheck.c398
-rw-r--r--posix/Makefile8
-rw-r--r--sysdeps/mach/hurd/i386/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist8
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist8
41 files changed, 861 insertions, 465 deletions
diff --git a/include/mcheck.h b/include/mcheck.h
index 8883c3d53e..5ad7cd1313 100644
--- a/include/mcheck.h
+++ b/include/mcheck.h
@@ -3,9 +3,5 @@
 #include <malloc/mcheck.h>
 
 # ifndef _ISOMAC
-
-libc_hidden_proto (mcheck)
-libc_hidden_proto (mcheck_check_all)
-
 # endif /* !_ISOMAC */
 #endif
diff --git a/malloc/Makefile b/malloc/Makefile
index cafe427097..eb5f5560bb 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -92,9 +92,6 @@ tests-exclude-mcheck = tst-mallocstate \
 	tst-malloc-thread-fail \
 	tst-malloc-usable-tunables \
 	tst-malloc_info \
-	tst-memalign \
-	tst-posix_memalign \
-	tst-realloc \
 	tst-pvalloc-fortify \
 	tst-reallocarray \
 	tst-compathooks-off tst-compathooks-on
diff --git a/malloc/Versions b/malloc/Versions
index c87f6df8ca..6548970419 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -110,8 +110,17 @@ libc_malloc_debug {
     realloc;
     valloc;
 
+    __free_hook;
+    __malloc_hook;
+    __memalign_hook;
+    __realloc_hook;
+
+    mcheck;
+    mprobe;
   }
   GLIBC_2.2 {
+    mcheck_check_all;
+    mcheck_pedantic;
     posix_memalign;
   }
   GLIBC_2.16 {
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 3cd44eeb84..8e9fefe6c3 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -34,65 +34,10 @@ void *(*__morecore)(ptrdiff_t);
 compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);
 #endif
 
-static void *malloc_hook_ini (size_t, const void *) __THROW;
-static void *realloc_hook_ini (void *, size_t, const void *) __THROW;
-static void *memalign_hook_ini (size_t, size_t, const void *) __THROW;
-
 void weak_variable (*__free_hook) (void *, const void *) = NULL;
-void *weak_variable (*__malloc_hook)
-  (size_t, const void *) = malloc_hook_ini;
-void *weak_variable (*__realloc_hook)
-  (void *, size_t, const void *) = realloc_hook_ini;
-void *weak_variable (*__memalign_hook)
-  (size_t, size_t, const void *) = memalign_hook_ini;
-
-/* Hooks for debugging versions.  The initial hooks just call the
-   initialization routine, then do the normal work. */
-
-/* These hooks will get executed only through the interposed allocator
-   functions in libc_malloc_debug.so.  This means that the calls to malloc,
-   realloc, etc. will lead back into the interposed functions, which is what we
-   want.
-
-   These initial hooks are assumed to be called in a single-threaded context,
-   so it is safe to reset all hooks at once upon initialization.  */
-
-static void
-generic_hook_ini (void)
-{
-  __malloc_hook = NULL;
-  __realloc_hook = NULL;
-  __memalign_hook = NULL;
-  ptmalloc_init ();
-
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_24)
-  void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
-  if (hook != NULL)
-    (*hook)();
-#endif
-  __malloc_initialized = 1;
-}
-
-static void *
-malloc_hook_ini (size_t sz, const void *caller)
-{
-  generic_hook_ini ();
-  return malloc (sz);
-}
-
-static void *
-realloc_hook_ini (void *ptr, size_t sz, const void *caller)
-{
-  generic_hook_ini ();
-  return realloc (ptr, sz);
-}
-
-static void *
-memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
-{
-  generic_hook_ini ();
-  return memalign (alignment, sz);
-}
+void *weak_variable (*__malloc_hook) (size_t, const void *) = NULL;
+void *weak_variable (*__realloc_hook) (void *, size_t, const void *) = NULL;
+void *weak_variable (*__memalign_hook) (size_t, size_t, const void *) = NULL;
 
 #include "malloc-check.c"
 
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
index 41dfcd3369..7c3a1e26b5 100644
--- a/malloc/malloc-debug.c
+++ b/malloc/malloc-debug.c
@@ -43,14 +43,96 @@ DEBUG_FN(valloc);
 DEBUG_FN(pvalloc);
 DEBUG_FN(calloc);
 
-extern void (*__free_hook) (void *, const void *);
-compat_symbol_reference (libc, __free_hook, __free_hook, GLIBC_2_0);
-extern void * (*__malloc_hook) (size_t, const void *);
-compat_symbol_reference (libc, __malloc_hook, __malloc_hook, GLIBC_2_0);
-extern void * (*__realloc_hook) (void *, size_t, const void *);
-compat_symbol_reference (libc, __realloc_hook, __realloc_hook, GLIBC_2_0);
-extern void * (*__memalign_hook) (size_t, size_t, const void *);
-compat_symbol_reference (libc, __memalign_hook, __memalign_hook, GLIBC_2_0);
+static int debug_initialized = -1;
+
+enum malloc_debug_hooks
+{
+  MALLOC_NONE_HOOK = 0,
+  MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck()  */
+};
+static unsigned __malloc_debugging_hooks;
+
+static __always_inline bool
+__is_malloc_debug_enabled (enum malloc_debug_hooks flag)
+{
+  return __malloc_debugging_hooks & flag;
+}
+
+static __always_inline void
+__malloc_debug_enable (enum malloc_debug_hooks flag)
+{
+  __malloc_debugging_hooks |= flag;
+}
+
+static __always_inline void
+__malloc_debug_disable (enum malloc_debug_hooks flag)
+{
+  __malloc_debugging_hooks &= ~flag;
+}
+
+#include "mcheck.c"
+
+extern void (*__malloc_initialize_hook) (void);
+compat_symbol_reference (libc, __malloc_initialize_hook,
+			 __malloc_initialize_hook, GLIBC_2_0);
+
+static void *malloc_hook_ini (size_t, const void *) __THROW;
+static void *realloc_hook_ini (void *, size_t, const void *) __THROW;
+static void *memalign_hook_ini (size_t, size_t, const void *) __THROW;
+
+void (*__free_hook) (void *, const void *) = NULL;
+void *(*__malloc_hook) (size_t, const void *) = malloc_hook_ini;
+void *(*__realloc_hook) (void *, size_t, const void *) = realloc_hook_ini;
+void *(*__memalign_hook) (size_t, size_t, const void *) = memalign_hook_ini;
+
+/* Hooks for debugging versions.  The initial hooks just call the
+   initialization routine, then do the normal work. */
+
+/* These hooks will get executed only through the interposed allocator
+   functions in libc_malloc_debug.so.  This means that the calls to malloc,
+   realloc, etc. will lead back into the interposed functions, which is what we
+   want.
+
+   These initial hooks are assumed to be called in a single-threaded context,
+   so it is safe to reset all hooks at once upon initialization.  */
+
+static void
+generic_hook_ini (void)
+{
+  debug_initialized = 0;
+  __malloc_hook = NULL;
+  __realloc_hook = NULL;
+  __memalign_hook = NULL;
+  /* The compiler does not know that these functions are allocators, so it will
+     not try to optimize it away.  */
+  __libc_free (__libc_malloc (0));
+
+  void (*hook) (void) = __malloc_initialize_hook;
+  if (hook != NULL)
+    (*hook)();
+  debug_initialized = 1;
+}
+
+static void *
+malloc_hook_ini (size_t sz, const void *caller)
+{
+  generic_hook_ini ();
+  return __debug_malloc (sz);
+}
+
+static void *
+realloc_hook_ini (void *ptr, size_t sz, const void *caller)
+{
+  generic_hook_ini ();
+  return __debug_realloc (ptr, sz);
+}
+
+static void *
+memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
+{
+  generic_hook_ini ();
+  return __debug_memalign (alignment, sz);
+}
 
 static size_t pagesize;
 
@@ -63,7 +145,17 @@ __debug_malloc (size_t bytes)
   if (__builtin_expect (hook != NULL, 0))
     return (*hook)(bytes, RETURN_ADDRESS (0));
 
-  return __libc_malloc (bytes);
+  void *victim = NULL;
+  size_t orig_bytes = bytes;
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+      || !malloc_mcheck_before (&bytes, &victim))
+    {
+      victim = __libc_malloc (bytes);
+    }
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
+    victim = malloc_mcheck_after (victim, orig_bytes);
+
+  return victim;
 }
 strong_alias (__debug_malloc, malloc)
 
@@ -76,6 +168,10 @@ __debug_free (void *mem)
       (*hook)(mem, RETURN_ADDRESS (0));
       return;
     }
+
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+    mem = free_mcheck (mem);
+
   __libc_free (mem);
 }
 strong_alias (__debug_free, free)
@@ -88,7 +184,19 @@ __debug_realloc (void *oldmem, size_t bytes)
   if (__builtin_expect (hook != NULL, 0))
     return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
 
-  return __libc_realloc (oldmem, bytes);
+  size_t orig_bytes = bytes, oldsize = 0;
+  void *victim = NULL;
+
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+      || !realloc_mcheck_before (&oldmem, &bytes, &oldsize, &victim))
+    {
+      victim = __libc_realloc (oldmem, bytes);
+    }
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
+    victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
+				   oldsize);
+
+  return victim;
 }
 strong_alias (__debug_realloc, realloc)
 
@@ -100,7 +208,18 @@ _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
   if (__builtin_expect (hook != NULL, 0))
     return (*hook)(alignment, bytes, address);
 
-  return __libc_memalign (alignment, bytes);
+  void *victim = NULL;
+  size_t orig_bytes = bytes;
+
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+      || !memalign_mcheck_before (alignment, &bytes, &victim))
+    {
+      victim = __libc_memalign (alignment, bytes);
+    }
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
+    victim = memalign_mcheck_after (victim, alignment, orig_bytes);
+
+  return victim;
 }
 
 static void *
@@ -165,17 +284,17 @@ strong_alias (__debug_posix_memalign, posix_memalign)
 static void *
 __debug_calloc (size_t nmemb, size_t size)
 {
+  size_t bytes;
+
+  if (__glibc_unlikely (__builtin_mul_overflow (nmemb, size, &bytes)))
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+
   void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      size_t bytes;
-
-      if (__glibc_unlikely (__builtin_mul_overflow (nmemb, size, &bytes)))
-	{
-	  errno = ENOMEM;
-	  return NULL;
-	}
-
       void *mem = (*hook)(bytes, RETURN_ADDRESS (0));
 
       if (mem != NULL)
@@ -184,6 +303,20 @@ __debug_calloc (size_t nmemb, size_t size)
       return mem;
     }
 
-  return __libc_calloc (nmemb, size);
+  size_t orig_bytes = bytes;
+  void *victim = NULL;
+
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+      || !malloc_mcheck_before (&bytes, &victim))
+    {
+      victim = __libc_malloc (bytes);
+    }
+  if (victim != NULL)
+    {
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+	victim = malloc_mcheck_after (victim, orig_bytes);
+      memset (victim, 0, orig_bytes);
+    }
+  return victim;
 }
 strong_alias (__debug_calloc, calloc)
diff --git a/malloc/mcheck-impl.c b/malloc/mcheck-impl.c
new file mode 100644
index 0000000000..8857e6b179
--- /dev/null
+++ b/malloc/mcheck-impl.c
@@ -0,0 +1,406 @@
+/* mcheck debugging hooks for malloc.
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written May 1989 by Mike Haertel.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <malloc-internal.h>
+#include <mcheck.h>
+#include <libintl.h>
+#include <stdint.h>
+#include <stdio.h>
+
+/* Arbitrary magical numbers.  */
+#define MAGICWORD       0xfedabeeb
+#define MAGICFREE       0xd8675309
+#define MAGICBYTE       ((char) 0xd7)
+#define MALLOCFLOOD     ((char) 0x93)
+#define FREEFLOOD       ((char) 0x95)
+
+/* Function to call when something awful happens.  */
+static void (*abortfunc) (enum mcheck_status);
+
+struct hdr
+{
+  size_t size;                  /* Exact size requested by user.  */
+  unsigned long int magic;      /* Magic number to check header integrity.  */
+  struct hdr *prev;
+  struct hdr *next;
+  void *block;                  /* Real block allocated, for memalign.  */
+  unsigned long int magic2;     /* Extra, keeps us doubleword aligned.  */
+} __attribute__ ((aligned (MALLOC_ALIGNMENT)));
+
+/* This is the beginning of the list of all memory blocks allocated.
+   It is only constructed if the pedantic testing is requested.  */
+static struct hdr *root;
+
+/* Nonzero if pedentic checking of all blocks is requested.  */
+static bool pedantic;
+
+#if defined _LIBC || defined STDC_HEADERS || defined USG
+# include <string.h>
+# define flood memset
+#else
+static void flood (void *, int, size_t);
+static void
+flood (void *ptr, int val, size_t size)
+{
+  char *cp = ptr;
+  while (size--)
+    *cp++ = val;
+}
+#endif
+
+static enum mcheck_status
+checkhdr (const struct hdr *hdr)
+{
+  enum mcheck_status status;
+  bool mcheck_used = __is_malloc_debug_enabled (MALLOC_MCHECK_HOOK);
+
+  if (!mcheck_used)
+    /* Maybe the mcheck used is disabled?  This happens when we find
+       an error and report it.  */
+    return MCHECK_OK;
+
+  switch (hdr->magic ^ ((uintptr_t) hdr->prev + (uintptr_t) hdr->next))
+    {
+    default:
+      status = MCHECK_HEAD;
+      break;
+    case MAGICFREE:
+      status = MCHECK_FREE;
+      break;
+    case MAGICWORD:
+      if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
+	status = MCHECK_TAIL;
+      else if ((hdr->magic2 ^ (uintptr_t) hdr->block) != MAGICWORD)
+	status = MCHECK_HEAD;
+      else
+	status = MCHECK_OK;
+      break;
+    }
+  if (status != MCHECK_OK)
+    {
+      mcheck_used = 0;
+      (*abortfunc) (status);
+      mcheck_used = 1;
+    }
+  return status;
+}
+
+static enum mcheck_status
+__mcheck_checkptr (const void *ptr)
+{
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+      return MCHECK_DISABLED;
+
+  if (ptr != NULL)
+    return checkhdr (((struct hdr *) ptr) - 1);
+
+  /* Walk through all the active blocks and test whether they were tampered
+     with.  */
+  struct hdr *runp = root;
+
+  /* Temporarily turn off the checks.  */
+  pedantic = false;
+
+  while (runp != NULL)
+    {
+      (void) checkhdr (runp);
+
+      runp = runp->next;
+    }
+
+  /* Turn checks on again.  */
+  pedantic = true;
+
+  return MCHECK_OK;
+}
+
+static void
+unlink_blk (struct hdr *ptr)
+{
+  if (ptr->next != NULL)
+    {
+      ptr->next->prev = ptr->prev;
+      ptr->next->magic = MAGICWORD ^ ((uintptr_t) ptr->next->prev
+                                      + (uintptr_t) ptr->next->next);
+    }
+  if (ptr->prev != NULL)
+    {
+      ptr->prev->next = ptr->next;
+      ptr->prev->magic = MAGICWORD ^ ((uintptr_t) ptr->prev->prev
+                                      + (uintptr_t) ptr->prev->next);
+    }
+  else
+    root = ptr->next;
+}
+
+static void
+link_blk (struct hdr *hdr)
+{
+  hdr->prev = NULL;
+  hdr->next = root;
+  root = hdr;
+  hdr->magic = MAGICWORD ^ (uintptr_t) hdr->next;
+
+  /* And the next block.  */
+  if (hdr->next != NULL)
+    {
+      hdr->next->prev = hdr;
+      hdr->next->magic = MAGICWORD ^ ((uintptr_t) hdr
+                                      + (uintptr_t) hdr->next->next);
+    }
+}
+
+static void *
+free_mcheck (void *ptr)
+{
+  if (pedantic)
+    __mcheck_checkptr (NULL);
+  if (ptr)
+    {
+      struct hdr *hdr = ((struct hdr *) ptr) - 1;
+      checkhdr (hdr);
+      hdr->magic = MAGICFREE;
+      hdr->magic2 = MAGICFREE;
+      unlink_blk (hdr);
+      hdr->prev = hdr->next = NULL;
+      flood (ptr, FREEFLOOD, hdr->size);
+      ptr = hdr->block;
+    }
+  return ptr;
+}
+
+static bool
+malloc_mcheck_before (size_t *sizep, void **victimp)
+{
+  size_t size = *sizep;
+
+  if (pedantic)
+    __mcheck_checkptr (NULL);
+
+  if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1))
+    {
+      __set_errno (ENOMEM);
+      *victimp = NULL;
+      return true;
+    }
+
+  *sizep = sizeof (struct hdr) + size + 1;
+  return false;
+}
+
+static void *
+malloc_mcheck_after (void *mem, size_t size)
+{
+  struct hdr *hdr = mem;
+
+  if (hdr == NULL)
+    return NULL;
+
+  hdr->size = size;
+  link_blk (hdr);
+  hdr->block = hdr;
+  hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD;
+  ((char *) &hdr[1])[size] = MAGICBYTE;
+  flood ((void *) (hdr + 1), MALLOCFLOOD, size);
+  return (void *) (hdr + 1);
+}
+
+static bool
+memalign_mcheck_before (size_t alignment, size_t *sizep, void **victimp)
+{
+  struct hdr *hdr;
+  size_t slop, size = *sizep;
+
+  /* Punt to malloc to avoid double headers.  */
+  if (alignment <= MALLOC_ALIGNMENT)
+    {
+      *victimp = __debug_malloc (size);
+      return true;
+    }
+
+  if (pedantic)
+    __mcheck_checkptr (NULL);
+
+  slop = (sizeof *hdr + alignment - 1) & - alignment;
+
+  if (size > ~((size_t) 0) - (slop + 1))
+    {
+      __set_errno (ENOMEM);
+      *victimp = NULL;
+      return true;
+    }
+
+  *sizep = slop + size + 1;
+  return false;
+}
+
+static void *
+memalign_mcheck_after (void *block, size_t alignment, size_t size)
+{
+  if (block == NULL)
+    return NULL;
+
+  /* This was served by __debug_malloc, so return as is.  */
+  if (alignment <= MALLOC_ALIGNMENT)
+    return block;
+
+  size_t slop = (sizeof (struct hdr) + alignment - 1) & - alignment;
+  struct hdr *hdr = ((struct hdr *) (block + slop)) - 1;
+
+  hdr->size = size;
+  link_blk (hdr);
+  hdr->block = (void *) block;
+  hdr->magic2 = (uintptr_t) block ^ MAGICWORD;
+  ((char *) &hdr[1])[size] = MAGICBYTE;
+  flood ((void *) (hdr + 1), MALLOCFLOOD, size);
+  return (void *) (hdr + 1);
+}
+
+static bool
+realloc_mcheck_before (void **ptrp, size_t *sizep, size_t *oldsize,
+		       void **victimp)
+{
+  size_t size = *sizep;
+  void *ptr = *ptrp;
+
+  if (ptr == NULL)
+    {
+      *victimp = __debug_malloc (size);
+      *oldsize = 0;
+      return true;
+    }
+
+  if (size == 0)
+    {
+      __debug_free (ptr);
+      *victimp = NULL;
+      return true;
+    }
+
+  if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1))
+    {
+      __set_errno (ENOMEM);
+      *victimp = NULL;
+      *oldsize = 0;
+      return true;
+    }
+
+  if (pedantic)
+    __mcheck_checkptr (NULL);
+
+  struct hdr *hdr;
+  size_t osize;
+
+  /* Update the oldptr for glibc realloc.  */
+  *ptrp = hdr = ((struct hdr *) ptr) - 1;
+
+  osize = hdr->size;
+
+  checkhdr (hdr);
+  unlink_blk (hdr);
+  if (size < osize)
+    flood ((char *) ptr + size, FREEFLOOD, osize - size);
+
+  *oldsize = osize;
+  *sizep = sizeof (struct hdr) + size + 1;
+  return false;
+}
+
+static void *
+realloc_mcheck_after (void *ptr, void *oldptr, size_t size, size_t osize)
+{
+  struct hdr *hdr = ptr;
+
+  if (hdr == NULL)
+    return NULL;
+
+  /* Malloc already added the header so don't tamper with it.  */
+  if (oldptr == NULL)
+    return ptr;
+
+  hdr->size = size;
+  link_blk (hdr);
+  hdr->block = hdr;
+  hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD;
+  ((char *) &hdr[1])[size] = MAGICBYTE;
+  if (size > osize)
+    flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
+  return (void *) (hdr + 1);
+}
+
+__attribute__ ((noreturn))
+static void
+mabort (enum mcheck_status status)
+{
+  const char *msg;
+  switch (status)
+    {
+    case MCHECK_OK:
+      msg = _ ("memory is consistent, library is buggy\n");
+      break;
+    case MCHECK_HEAD:
+      msg = _ ("memory clobbered before allocated block\n");
+      break;
+    case MCHECK_TAIL:
+      msg = _ ("memory clobbered past end of allocated block\n");
+      break;
+    case MCHECK_FREE:
+      msg = _ ("block freed twice\n");
+      break;
+    default:
+      msg = _ ("bogus mcheck_status, library is buggy\n");
+      break;
+    }
+#ifdef _LIBC
+  __libc_fatal (msg);
+#else
+  fprintf (stderr, "mcheck: %s", msg);
+  fflush (stderr);
+  abort ();
+#endif
+}
+
+/* Memory barrier so that GCC does not optimize out the argument.  */
+#define malloc_opt_barrier(x) \
+  ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
+
+static int
+__mcheck_initialize (void (*func) (enum mcheck_status), bool in_pedantic)
+{
+  abortfunc = (func != NULL) ? func : &mabort;
+
+  switch (debug_initialized)
+    {
+    case -1:
+      /* Called before the first malloc was called.  */
+      __debug_free (__debug_malloc (0));
+      /* FALLTHROUGH */
+    case 0:
+      /* Called through the initializer hook.  */
+      __malloc_debug_enable (MALLOC_MCHECK_HOOK);
+      break;
+    case 1:
+    default:
+      /* Malloc was already called.  Fail.  */
+      return -1;
+    }
+
+  pedantic = in_pedantic;
+  return 0;
+}
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 1e68cedbf5..74c20ffe25 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -1,4 +1,4 @@
-/* Standard debugging hooks for `malloc'.
+/* The mcheck() interface.
    Copyright (C) 1990-2021 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written May 1989 by Mike Haertel.
@@ -17,402 +17,46 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _MALLOC_INTERNAL
-# define _MALLOC_INTERNAL
-# include <malloc.h>
-# include <malloc-size.h>
-# include <mcheck.h>
-# include <stdint.h>
-# include <stdio.h>
-# include <libintl.h>
-# include <errno.h>
-# include <malloc-internal.h>
-#endif
-
-/* Old hook values.  */
-static void (*old_free_hook)(void *ptr, const void *);
-static void *(*old_malloc_hook) (size_t size, const void *);
-static void *(*old_memalign_hook) (size_t alignment, size_t size,
-				   const void *);
-static void *(*old_realloc_hook) (void *ptr, size_t size,
-				  const void *);
-
-/* Function to call when something awful happens.  */
-static void (*abortfunc) (enum mcheck_status);
-
-/* Arbitrary magical numbers.  */
-#define MAGICWORD       0xfedabeeb
-#define MAGICFREE       0xd8675309
-#define MAGICBYTE       ((char) 0xd7)
-#define MALLOCFLOOD     ((char) 0x93)
-#define FREEFLOOD       ((char) 0x95)
-
-struct hdr
-{
-  size_t size;                  /* Exact size requested by user.  */
-  unsigned long int magic;      /* Magic number to check header integrity.  */
-  struct hdr *prev;
-  struct hdr *next;
-  void *block;                  /* Real block allocated, for memalign.  */
-  unsigned long int magic2;     /* Extra, keeps us doubleword aligned.  */
-} __attribute__ ((aligned (MALLOC_ALIGNMENT)));
-
-/* This is the beginning of the list of all memory blocks allocated.
-   It is only constructed if the pedantic testing is requested.  */
-static struct hdr *root;
-
-static int mcheck_used;
-
-/* Nonzero if pedentic checking of all blocks is requested.  */
-static int pedantic;
-
-#if defined _LIBC || defined STDC_HEADERS || defined USG
-# include <string.h>
-# define flood memset
+#if !IS_IN (libc)
+# include "mcheck-impl.c"
 #else
-static void flood (void *, int, size_t);
-static void
-flood (void *ptr, int val, size_t size)
-{
-  char *cp = ptr;
-  while (size--)
-    *cp++ = val;
-}
+# include <mcheck.h>
 #endif
 
-static enum mcheck_status
-checkhdr (const struct hdr *hdr)
-{
-  enum mcheck_status status;
-
-  if (!mcheck_used)
-    /* Maybe the mcheck used is disabled?  This happens when we find
-       an error and report it.  */
-    return MCHECK_OK;
-
-  switch (hdr->magic ^ ((uintptr_t) hdr->prev + (uintptr_t) hdr->next))
-    {
-    default:
-      status = MCHECK_HEAD;
-      break;
-    case MAGICFREE:
-      status = MCHECK_FREE;
-      break;
-    case MAGICWORD:
-      if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
-        status = MCHECK_TAIL;
-      else if ((hdr->magic2 ^ (uintptr_t) hdr->block) != MAGICWORD)
-        status = MCHECK_HEAD;
-      else
-        status = MCHECK_OK;
-      break;
-    }
-  if (status != MCHECK_OK)
-    {
-      mcheck_used = 0;
-      (*abortfunc) (status);
-      mcheck_used = 1;
-    }
-  return status;
-}
-
 void
 mcheck_check_all (void)
 {
-  /* Walk through all the active blocks and test whether they were tampered
-     with.  */
-  struct hdr *runp = root;
-
-  /* Temporarily turn off the checks.  */
-  pedantic = 0;
-
-  while (runp != NULL)
-    {
-      (void) checkhdr (runp);
-
-      runp = runp->next;
-    }
-
-  /* Turn checks on again.  */
-  pedantic = 1;
-}
-#ifdef _LIBC
-libc_hidden_def (mcheck_check_all)
+#if !IS_IN (libc)
+  __mcheck_checkptr (NULL);
 #endif
-
-static void
-unlink_blk (struct hdr *ptr)
-{
-  if (ptr->next != NULL)
-    {
-      ptr->next->prev = ptr->prev;
-      ptr->next->magic = MAGICWORD ^ ((uintptr_t) ptr->next->prev
-                                      + (uintptr_t) ptr->next->next);
-    }
-  if (ptr->prev != NULL)
-    {
-      ptr->prev->next = ptr->next;
-      ptr->prev->magic = MAGICWORD ^ ((uintptr_t) ptr->prev->prev
-                                      + (uintptr_t) ptr->prev->next);
-    }
-  else
-    root = ptr->next;
-}
-
-static void
-link_blk (struct hdr *hdr)
-{
-  hdr->prev = NULL;
-  hdr->next = root;
-  root = hdr;
-  hdr->magic = MAGICWORD ^ (uintptr_t) hdr->next;
-
-  /* And the next block.  */
-  if (hdr->next != NULL)
-    {
-      hdr->next->prev = hdr;
-      hdr->next->magic = MAGICWORD ^ ((uintptr_t) hdr
-                                      + (uintptr_t) hdr->next->next);
-    }
 }
-static void
-freehook (void *ptr, const void *caller)
-{
-  if (pedantic)
-    mcheck_check_all ();
-  if (ptr)
-    {
-      struct hdr *hdr = ((struct hdr *) ptr) - 1;
-      checkhdr (hdr);
-      hdr->magic = MAGICFREE;
-      hdr->magic2 = MAGICFREE;
-      unlink_blk (hdr);
-      hdr->prev = hdr->next = NULL;
-      flood (ptr, FREEFLOOD, hdr->size);
-      ptr = hdr->block;
-    }
-  __free_hook = old_free_hook;
-  if (old_free_hook != NULL)
-    (*old_free_hook)(ptr, caller);
-  else
-    free (ptr);
-  __free_hook = freehook;
-}
-
-static void *
-mallochook (size_t size, const void *caller)
-{
-  struct hdr *hdr;
-
-  if (pedantic)
-    mcheck_check_all ();
-
-  if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1))
-    {
-      __set_errno (ENOMEM);
-      return NULL;
-    }
-
-  __malloc_hook = old_malloc_hook;
-  if (old_malloc_hook != NULL)
-    hdr = (struct hdr *) (*old_malloc_hook)(sizeof (struct hdr) + size + 1,
-                                            caller);
-  else
-    hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
-  __malloc_hook = mallochook;
-  if (hdr == NULL)
-    return NULL;
-
-  hdr->size = size;
-  link_blk (hdr);
-  hdr->block = hdr;
-  hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD;
-  ((char *) &hdr[1])[size] = MAGICBYTE;
-  flood ((void *) (hdr + 1), MALLOCFLOOD, size);
-  return (void *) (hdr + 1);
-}
-
-static void *
-memalignhook (size_t alignment, size_t size,
-              const void *caller)
-{
-  struct hdr *hdr;
-  size_t slop;
-  char *block;
-
-  if (pedantic)
-    mcheck_check_all ();
-
-  slop = (sizeof *hdr + alignment - 1) & - alignment;
-
-  if (size > ~((size_t) 0) - (slop + 1))
-    {
-      __set_errno (ENOMEM);
-      return NULL;
-    }
-
-  __memalign_hook = old_memalign_hook;
-  if (old_memalign_hook != NULL)
-    block = (*old_memalign_hook)(alignment, slop + size + 1, caller);
-  else
-    block = memalign (alignment, slop + size + 1);
-  __memalign_hook = memalignhook;
-  if (block == NULL)
-    return NULL;
-
-  hdr = ((struct hdr *) (block + slop)) - 1;
-
-  hdr->size = size;
-  link_blk (hdr);
-  hdr->block = (void *) block;
-  hdr->magic2 = (uintptr_t) block ^ MAGICWORD;
-  ((char *) &hdr[1])[size] = MAGICBYTE;
-  flood ((void *) (hdr + 1), MALLOCFLOOD, size);
-  return (void *) (hdr + 1);
-}
-
-static void *
-reallochook (void *ptr, size_t size, const void *caller)
-{
-  if (size == 0)
-    {
-      freehook (ptr, caller);
-      return NULL;
-    }
-
-  struct hdr *hdr;
-  size_t osize;
-
-  if (pedantic)
-    mcheck_check_all ();
-
-  if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1))
-    {
-      __set_errno (ENOMEM);
-      return NULL;
-    }
-
-  if (ptr)
-    {
-      hdr = ((struct hdr *) ptr) - 1;
-      osize = hdr->size;
-
-      checkhdr (hdr);
-      unlink_blk (hdr);
-      if (size < osize)
-        flood ((char *) ptr + size, FREEFLOOD, osize - size);
-    }
-  else
-    {
-      osize = 0;
-      hdr = NULL;
-    }
-  __free_hook = old_free_hook;
-  __malloc_hook = old_malloc_hook;
-  __memalign_hook = old_memalign_hook;
-  __realloc_hook = old_realloc_hook;
-  if (old_realloc_hook != NULL)
-    hdr = (struct hdr *) (*old_realloc_hook)((void *) hdr,
-                                             sizeof (struct hdr) + size + 1,
-                                             caller);
-  else
-    hdr = (struct hdr *) realloc ((void *) hdr,
-                                  sizeof (struct hdr) + size + 1);
-  __free_hook = freehook;
-  __malloc_hook = mallochook;
-  __memalign_hook = memalignhook;
-  __realloc_hook = reallochook;
-  if (hdr == NULL)
-    return NULL;
-
-  hdr->size = size;
-  link_blk (hdr);
-  hdr->block = hdr;
-  hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD;
-  ((char *) &hdr[1])[size] = MAGICBYTE;
-  if (size > osize)
-    flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
-  return (void *) (hdr + 1);
-}
-
-__attribute__ ((noreturn))
-static void
-mabort (enum mcheck_status status)
-{
-  const char *msg;
-  switch (status)
-    {
-    case MCHECK_OK:
-      msg = _ ("memory is consistent, library is buggy\n");
-      break;
-    case MCHECK_HEAD:
-      msg = _ ("memory clobbered before allocated block\n");
-      break;
-    case MCHECK_TAIL:
-      msg = _ ("memory clobbered past end of allocated block\n");
-      break;
-    case MCHECK_FREE:
-      msg = _ ("block freed twice\n");
-      break;
-    default:
-      msg = _ ("bogus mcheck_status, library is buggy\n");
-      break;
-    }
-#ifdef _LIBC
-  __libc_fatal (msg);
-#else
-  fprintf (stderr, "mcheck: %s", msg);
-  fflush (stderr);
-  abort ();
-#endif
-}
-
-/* Memory barrier so that GCC does not optimize out the argument.  */
-#define malloc_opt_barrier(x) \
-  ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
 
 int
 mcheck (void (*func) (enum mcheck_status))
 {
-  abortfunc = (func != NULL) ? func : &mabort;
-
-  /* These hooks may not be safely inserted if malloc is already in use.  */
-  if (__malloc_initialized <= 0 && !mcheck_used)
-    {
-      /* We call malloc() once here to ensure it is initialized.  */
-      void *p = malloc (0);
-      /* GCC might optimize out the malloc/free pair without a barrier.  */
-      p = malloc_opt_barrier (p);
-      free (p);
-
-      old_free_hook = __free_hook;
-      __free_hook = freehook;
-      old_malloc_hook = __malloc_hook;
-      __malloc_hook = mallochook;
-      old_memalign_hook = __memalign_hook;
-      __memalign_hook = memalignhook;
-      old_realloc_hook = __realloc_hook;
-      __realloc_hook = reallochook;
-      mcheck_used = 1;
-    }
-
-  return mcheck_used ? 0 : -1;
-}
-#ifdef _LIBC
-libc_hidden_def (mcheck)
+#if IS_IN (libc)
+  return -1;
+#else
+  return __mcheck_initialize (func, false);
 #endif
+}
 
 int
 mcheck_pedantic (void (*func) (enum mcheck_status))
 {
-  int res = mcheck (func);
-  if (res == 0)
-    pedantic = 1;
-  return res;
+#if IS_IN (libc)
+  return -1;
+#else
+  return __mcheck_initialize (func, true);
+#endif
 }
 
 enum mcheck_status
 mprobe (void *ptr)
 {
-  return mcheck_used ? checkhdr (((struct hdr *) ptr) - 1) : MCHECK_DISABLED;
+#if IS_IN (libc)
+  return MCHECK_DISABLED;
+#else
+  return __mcheck_checkptr (ptr);
+#endif
 }
diff --git a/posix/Makefile b/posix/Makefile
index b895638865..059efb3cd2 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -87,7 +87,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
 		   tst-nice tst-nanosleep tst-regex2 \
 		   transbug tst-rxspencer tst-pcre tst-boost \
-		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 \
+		   bug-ga1 tst-vfork1 tst-vfork2 \
 		   tst-waitid tst-wait4 tst-wait3 \
 		   tst-getaddrinfo2 bug-glob2 bug-glob3 tst-sysconf \
 		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
@@ -122,7 +122,7 @@ endif
 
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
-tests-container := bug-ga2
+tests-container := bug-ga2 tst-vfork3
 tests-time64	:= tst-wait4-time64 tst-wait3-time64 tst-gnuglob64-time64
 xtests		:= tst-getaddrinfo4 tst-getaddrinfo5 tst-sched_rr_get_interval
 xtests-time64	:= tst-sched_rr_get_interval-time64
@@ -359,7 +359,9 @@ tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace \
 		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)tst-vfork3-mem.out: $(objpfx)tst-vfork3.out
-	$(common-objpfx)malloc/mtrace $(objpfx)tst-vfork3.mtrace > $@; \
+	{ test -r $(objpfx)tst-vfork3.mtrace \
+	|| ( echo "tst-vfork3.mtrace does not exist"; exit 77; ) \
+	&& $(common-objpfx)malloc/mtrace $(objpfx)tst-vfork3.mtrace; } > $@; \
 	$(evaluate-test)
 
 # tst-rxspencer.mtrace is not generated, only
diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
index 393ef2acd7..c5e1192b27 100644
--- a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
+++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2.6 __free_hook D 0x4
+GLIBC_2.2.6 __malloc_hook D 0x4
+GLIBC_2.2.6 __memalign_hook D 0x4
+GLIBC_2.2.6 __realloc_hook D 0x4
 GLIBC_2.2.6 calloc F
 GLIBC_2.2.6 free F
 GLIBC_2.2.6 malloc F
+GLIBC_2.2.6 mcheck F
+GLIBC_2.2.6 mcheck_check_all F
+GLIBC_2.2.6 mcheck_pedantic F
 GLIBC_2.2.6 memalign F
+GLIBC_2.2.6 mprobe F
 GLIBC_2.2.6 posix_memalign F
 GLIBC_2.2.6 pvalloc F
 GLIBC_2.2.6 realloc F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
index 2b183c90d4..cc6531b017 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.17 __free_hook D 0x8
+GLIBC_2.17 __malloc_hook D 0x8
+GLIBC_2.17 __memalign_hook D 0x8
+GLIBC_2.17 __realloc_hook D 0x8
 GLIBC_2.17 aligned_alloc F
 GLIBC_2.17 calloc F
 GLIBC_2.17 free F
 GLIBC_2.17 malloc F
+GLIBC_2.17 mcheck F
+GLIBC_2.17 mcheck_check_all F
+GLIBC_2.17 mcheck_pedantic F
 GLIBC_2.17 memalign F
+GLIBC_2.17 mprobe F
 GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
index 7621d1266e..5fe020dca6 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x8
+GLIBC_2.0 __malloc_hook D 0x8
+GLIBC_2.0 __memalign_hook D 0x8
+GLIBC_2.0 __realloc_hook D 0x8
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
index 3ec745c9ac..b5e9d10b9f 100644
--- a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.32 __free_hook D 0x4
+GLIBC_2.32 __malloc_hook D 0x4
+GLIBC_2.32 __memalign_hook D 0x4
+GLIBC_2.32 __realloc_hook D 0x4
 GLIBC_2.32 aligned_alloc F
 GLIBC_2.32 calloc F
 GLIBC_2.32 free F
 GLIBC_2.32 malloc F
+GLIBC_2.32 mcheck F
+GLIBC_2.32 mcheck_check_all F
+GLIBC_2.32 mcheck_pedantic F
 GLIBC_2.32 memalign F
+GLIBC_2.32 mprobe F
 GLIBC_2.32 posix_memalign F
 GLIBC_2.32 pvalloc F
 GLIBC_2.32 realloc F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
index f7938d075f..c90d894b22 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 __free_hook D 0x4
+GLIBC_2.4 __malloc_hook D 0x4
+GLIBC_2.4 __memalign_hook D 0x4
+GLIBC_2.4 __realloc_hook D 0x4
 GLIBC_2.4 calloc F
 GLIBC_2.4 free F
 GLIBC_2.4 malloc F
+GLIBC_2.4 mcheck F
+GLIBC_2.4 mcheck_check_all F
+GLIBC_2.4 mcheck_pedantic F
 GLIBC_2.4 memalign F
+GLIBC_2.4 mprobe F
 GLIBC_2.4 posix_memalign F
 GLIBC_2.4 pvalloc F
 GLIBC_2.4 realloc F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
index f7938d075f..c90d894b22 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 __free_hook D 0x4
+GLIBC_2.4 __malloc_hook D 0x4
+GLIBC_2.4 __memalign_hook D 0x4
+GLIBC_2.4 __realloc_hook D 0x4
 GLIBC_2.4 calloc F
 GLIBC_2.4 free F
 GLIBC_2.4 malloc F
+GLIBC_2.4 mcheck F
+GLIBC_2.4 mcheck_check_all F
+GLIBC_2.4 mcheck_pedantic F
 GLIBC_2.4 memalign F
+GLIBC_2.4 mprobe F
 GLIBC_2.4 posix_memalign F
 GLIBC_2.4 pvalloc F
 GLIBC_2.4 realloc F
diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
index 54da2c3e38..932cbbd382 100644
--- a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.29 __free_hook D 0x4
+GLIBC_2.29 __malloc_hook D 0x4
+GLIBC_2.29 __memalign_hook D 0x4
+GLIBC_2.29 __realloc_hook D 0x4
 GLIBC_2.29 aligned_alloc F
 GLIBC_2.29 calloc F
 GLIBC_2.29 free F
 GLIBC_2.29 malloc F
+GLIBC_2.29 mcheck F
+GLIBC_2.29 mcheck_check_all F
+GLIBC_2.29 mcheck_pedantic F
 GLIBC_2.29 memalign F
+GLIBC_2.29 mprobe F
 GLIBC_2.29 posix_memalign F
 GLIBC_2.29 pvalloc F
 GLIBC_2.29 realloc F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
index 3ea834d9a2..88ed3c09c8 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x4
+GLIBC_2.2 __malloc_hook D 0x4
+GLIBC_2.2 __memalign_hook D 0x4
+GLIBC_2.2 __realloc_hook D 0x4
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
index 3ea834d9a2..bc8a2be276 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x8
+GLIBC_2.2 __malloc_hook D 0x8
+GLIBC_2.2 __memalign_hook D 0x8
+GLIBC_2.2 __realloc_hook D 0x8
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
index f7938d075f..c90d894b22 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 __free_hook D 0x4
+GLIBC_2.4 __malloc_hook D 0x4
+GLIBC_2.4 __memalign_hook D 0x4
+GLIBC_2.4 __realloc_hook D 0x4
 GLIBC_2.4 calloc F
 GLIBC_2.4 free F
 GLIBC_2.4 malloc F
+GLIBC_2.4 mcheck F
+GLIBC_2.4 mcheck_check_all F
+GLIBC_2.4 mcheck_pedantic F
 GLIBC_2.4 memalign F
+GLIBC_2.4 mprobe F
 GLIBC_2.4 posix_memalign F
 GLIBC_2.4 pvalloc F
 GLIBC_2.4 realloc F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
index d02da8ef66..0502f3001e 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.18 __free_hook D 0x4
+GLIBC_2.18 __malloc_hook D 0x4
+GLIBC_2.18 __memalign_hook D 0x4
+GLIBC_2.18 __realloc_hook D 0x4
 GLIBC_2.18 aligned_alloc F
 GLIBC_2.18 calloc F
 GLIBC_2.18 free F
 GLIBC_2.18 malloc F
+GLIBC_2.18 mcheck F
+GLIBC_2.18 mcheck_check_all F
+GLIBC_2.18 mcheck_pedantic F
 GLIBC_2.18 memalign F
+GLIBC_2.18 mprobe F
 GLIBC_2.18 posix_memalign F
 GLIBC_2.18 pvalloc F
 GLIBC_2.18 realloc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
index d02da8ef66..0502f3001e 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.18 __free_hook D 0x4
+GLIBC_2.18 __malloc_hook D 0x4
+GLIBC_2.18 __memalign_hook D 0x4
+GLIBC_2.18 __realloc_hook D 0x4
 GLIBC_2.18 aligned_alloc F
 GLIBC_2.18 calloc F
 GLIBC_2.18 free F
 GLIBC_2.18 malloc F
+GLIBC_2.18 mcheck F
+GLIBC_2.18 mcheck_check_all F
+GLIBC_2.18 mcheck_pedantic F
 GLIBC_2.18 memalign F
+GLIBC_2.18 mprobe F
 GLIBC_2.18 posix_memalign F
 GLIBC_2.18 pvalloc F
 GLIBC_2.18 realloc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
index 7621d1266e..5fe020dca6 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x8
+GLIBC_2.0 __malloc_hook D 0x8
+GLIBC_2.0 __memalign_hook D 0x8
+GLIBC_2.0 __realloc_hook D 0x8
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
index 658c965b08..3a4599773d 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.21 __free_hook D 0x4
+GLIBC_2.21 __malloc_hook D 0x4
+GLIBC_2.21 __memalign_hook D 0x4
+GLIBC_2.21 __realloc_hook D 0x4
 GLIBC_2.21 aligned_alloc F
 GLIBC_2.21 calloc F
 GLIBC_2.21 free F
 GLIBC_2.21 malloc F
+GLIBC_2.21 mcheck F
+GLIBC_2.21 mcheck_check_all F
+GLIBC_2.21 mcheck_pedantic F
 GLIBC_2.21 memalign F
+GLIBC_2.21 mprobe F
 GLIBC_2.21 posix_memalign F
 GLIBC_2.21 pvalloc F
 GLIBC_2.21 realloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
index 921079580c..0696d526d4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.3 __free_hook D 0x8
+GLIBC_2.3 __malloc_hook D 0x8
+GLIBC_2.3 __memalign_hook D 0x8
+GLIBC_2.3 __realloc_hook D 0x8
 GLIBC_2.3 calloc F
 GLIBC_2.3 free F
 GLIBC_2.3 malloc F
+GLIBC_2.3 mcheck F
+GLIBC_2.3 mcheck_check_all F
+GLIBC_2.3 mcheck_pedantic F
 GLIBC_2.3 memalign F
+GLIBC_2.3 mprobe F
 GLIBC_2.3 posix_memalign F
 GLIBC_2.3 pvalloc F
 GLIBC_2.3 realloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
index 2b183c90d4..cc6531b017 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.17 __free_hook D 0x8
+GLIBC_2.17 __malloc_hook D 0x8
+GLIBC_2.17 __memalign_hook D 0x8
+GLIBC_2.17 __realloc_hook D 0x8
 GLIBC_2.17 aligned_alloc F
 GLIBC_2.17 calloc F
 GLIBC_2.17 free F
 GLIBC_2.17 malloc F
+GLIBC_2.17 mcheck F
+GLIBC_2.17 mcheck_check_all F
+GLIBC_2.17 mcheck_pedantic F
 GLIBC_2.17 memalign F
+GLIBC_2.17 mprobe F
 GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
index 05c8ba8c9f..4ded2f9640 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.33 __free_hook D 0x4
+GLIBC_2.33 __malloc_hook D 0x4
+GLIBC_2.33 __memalign_hook D 0x4
+GLIBC_2.33 __realloc_hook D 0x4
 GLIBC_2.33 aligned_alloc F
 GLIBC_2.33 calloc F
 GLIBC_2.33 free F
 GLIBC_2.33 malloc F
+GLIBC_2.33 mcheck F
+GLIBC_2.33 mcheck_check_all F
+GLIBC_2.33 mcheck_pedantic F
 GLIBC_2.33 memalign F
+GLIBC_2.33 mprobe F
 GLIBC_2.33 posix_memalign F
 GLIBC_2.33 pvalloc F
 GLIBC_2.33 realloc F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
index 20531a7372..f878912895 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.27 __free_hook D 0x8
+GLIBC_2.27 __malloc_hook D 0x8
+GLIBC_2.27 __memalign_hook D 0x8
+GLIBC_2.27 __realloc_hook D 0x8
 GLIBC_2.27 aligned_alloc F
 GLIBC_2.27 calloc F
 GLIBC_2.27 free F
 GLIBC_2.27 malloc F
+GLIBC_2.27 mcheck F
+GLIBC_2.27 mcheck_check_all F
+GLIBC_2.27 mcheck_pedantic F
 GLIBC_2.27 memalign F
+GLIBC_2.27 mprobe F
 GLIBC_2.27 posix_memalign F
 GLIBC_2.27 pvalloc F
 GLIBC_2.27 realloc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
index 3ea834d9a2..bc8a2be276 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x8
+GLIBC_2.2 __malloc_hook D 0x8
+GLIBC_2.2 __memalign_hook D 0x8
+GLIBC_2.2 __realloc_hook D 0x8
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
index 3ea834d9a2..88ed3c09c8 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x4
+GLIBC_2.2 __malloc_hook D 0x4
+GLIBC_2.2 __memalign_hook D 0x4
+GLIBC_2.2 __realloc_hook D 0x4
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
index 3ea834d9a2..88ed3c09c8 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x4
+GLIBC_2.2 __malloc_hook D 0x4
+GLIBC_2.2 __memalign_hook D 0x4
+GLIBC_2.2 __realloc_hook D 0x4
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
index 7621d1266e..c847b1ee49 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
@@ -1,9 +1,17 @@
+GLIBC_2.0 __free_hook D 0x4
+GLIBC_2.0 __malloc_hook D 0x4
+GLIBC_2.0 __memalign_hook D 0x4
+GLIBC_2.0 __realloc_hook D 0x4
 GLIBC_2.0 calloc F
 GLIBC_2.0 free F
 GLIBC_2.0 malloc F
+GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
+GLIBC_2.0 mprobe F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
index 3ea834d9a2..bc8a2be276 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 __free_hook D 0x8
+GLIBC_2.2 __malloc_hook D 0x8
+GLIBC_2.2 __memalign_hook D 0x8
+GLIBC_2.2 __realloc_hook D 0x8
 GLIBC_2.2 calloc F
 GLIBC_2.2 free F
 GLIBC_2.2 malloc F
+GLIBC_2.2 mcheck F
+GLIBC_2.2 mcheck_check_all F
+GLIBC_2.2 mcheck_pedantic F
 GLIBC_2.2 memalign F
+GLIBC_2.2 mprobe F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
index 723c5f48f0..3fa0aa3cc3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.2.5 __free_hook D 0x8
+GLIBC_2.2.5 __malloc_hook D 0x8
+GLIBC_2.2.5 __memalign_hook D 0x8
+GLIBC_2.2.5 __realloc_hook D 0x8
 GLIBC_2.2.5 calloc F
 GLIBC_2.2.5 free F
 GLIBC_2.2.5 malloc F
+GLIBC_2.2.5 mcheck F
+GLIBC_2.2.5 mcheck_check_all F
+GLIBC_2.2.5 mcheck_pedantic F
 GLIBC_2.2.5 memalign F
+GLIBC_2.2.5 mprobe F
 GLIBC_2.2.5 posix_memalign F
 GLIBC_2.2.5 pvalloc F
 GLIBC_2.2.5 realloc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
index c506f45101..4c213fcbef 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
@@ -1,8 +1,16 @@
+GLIBC_2.16 __free_hook D 0x4
+GLIBC_2.16 __malloc_hook D 0x4
+GLIBC_2.16 __memalign_hook D 0x4
+GLIBC_2.16 __realloc_hook D 0x4
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.16 calloc F
 GLIBC_2.16 free F
 GLIBC_2.16 malloc F
+GLIBC_2.16 mcheck F
+GLIBC_2.16 mcheck_check_all F
+GLIBC_2.16 mcheck_pedantic F
 GLIBC_2.16 memalign F
+GLIBC_2.16 mprobe F
 GLIBC_2.16 posix_memalign F
 GLIBC_2.16 pvalloc F
 GLIBC_2.16 realloc F