diff --git a/include/malloc.h b/include/malloc.h
index b77761f74d..bb1123d9d3 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -4,6 +4,11 @@
 
 # ifndef _ISOMAC
 #  include <rtld-malloc.h>
+#  include <stdbool.h>
+#  include <mcheck.h>
+
+struct malloc_state;
+typedef struct malloc_state *mstate;
 
 /* In the GNU libc we rename the global variable
    `__malloc_initialized' to `__libc_malloc_initialized'.  */
@@ -11,8 +16,9 @@
 /* Nonzero if the malloc is already initialized.  */
 extern int __malloc_initialized attribute_hidden;
 
-struct malloc_state;
-typedef struct malloc_state *mstate;
+enum mcheck_status __mcheck_checkptr (const void *) attribute_hidden;
+extern int __mcheck_initialize (void (*) (enum mcheck_status), bool)
+     attribute_hidden;
 
 # endif /* !_ISOMAC */
 
diff --git a/malloc/Makefile b/malloc/Makefile
index 9b92f96813..7afeebbe2a 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -91,9 +91,7 @@ tests-exclude-mcheck = tst-mallocstate \
 	tst-malloc-usable-static \
 	tst-malloc-usable-static-tunables \
 	tst-malloc-usable-tunables \
-	tst-malloc_info \
-	tst-memalign \
-	tst-posix_memalign
+	tst-malloc_info
 
 tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
 
@@ -272,7 +270,7 @@ $(objpfx)memusage: memusage.sh
 
 # Extra dependencies
 $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
-hooks.c: malloc-check.c
+hooks.c: malloc-check.c mcheck-hooks.c
 
 # Compile the tests with a flag which suppresses the mallopt call in
 # the test skeleton.
diff --git a/malloc/Versions b/malloc/Versions
index 62e4698a08..e138eaa24b 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -67,6 +67,9 @@ libc {
   GLIBC_2.33 {
     mallinfo2;
   }
+  GLIBC_2.34 {
+    __libc_lmcheck;
+  }
   GLIBC_PRIVATE {
     # Internal startup hook for libpthread.
     __libc_malloc_pthread_startup;
diff --git a/malloc/arena.c b/malloc/arena.c
index 357a3b0b30..a8500a25c9 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -403,6 +403,11 @@ ptmalloc_init (void)
     __malloc_debug_enable (MALLOC_CHECK_HOOK);
 #endif
 
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
+  if (__libc_lmcheck)
+    __mcheck_initialize (NULL, false);
+#endif
+
 #if HAVE_MALLOC_INIT_HOOK
   void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
   if (hook != NULL)
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 77855801c8..7b500e5671 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -36,6 +36,7 @@ enum malloc_debug_hooks
 {
   MALLOC_NONE_HOOK = 0,
   MALLOC_CHECK_HOOK = 1 << 0,	/* MALLOC_CHECK_ or glibc.malloc.check.  */
+  MALLOC_MCHECK_HOOK = 1 << 1,	/* mcheck()  */
 };
 static unsigned __malloc_debugging_hooks;
 
@@ -77,113 +78,181 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
 }
 
 #include "malloc-check.c"
+#include "mcheck-hooks.c"
 
 static __always_inline bool
-_malloc_debug_before (size_t bytes, void **victimp, const void *address)
+_malloc_debug_before (size_t *bytesp, void **victimp, const void *address)
 {
   _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
-                  "PTRDIFF_MAX is not more than half of SIZE_MAX");
+		  "PTRDIFF_MAX is not more than half of SIZE_MAX");
 
   void *(*hook) (size_t, const void *)
     = atomic_forced_read (__malloc_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      *victimp = (*hook)(bytes, address);
+      *victimp = (*hook)(*bytesp, address);
       return true;
     }
 
-  if (__glibc_unlikely (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)))
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
-      *victimp = malloc_check (bytes);
-      return true;
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+	  && malloc_mcheck_before (bytesp, victimp))
+	return true;
+      if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+	{
+	  *victimp = malloc_check (*bytesp);
+	  return true;
+	}
     }
   return false;
 }
 
+static __always_inline void *
+_malloc_debug_after (void *mem, size_t bytes, const void *address)
+{
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+    mem = malloc_mcheck_after (mem, bytes);
+  return mem;
+}
+
 static __always_inline bool
-_free_debug_before (void *mem, const void *address)
+_free_debug_before (void **mem, const void *address)
 {
   void (*hook) (void *, const void *)
     = atomic_forced_read (__free_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      (*hook)(mem, address);
+      (*hook)(*mem, address);
       return true;
     }
 
-  if (__glibc_unlikely (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)))
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
-      free_check (mem);
-      return true;
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+	*mem = free_mcheck (*mem);
+      if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+	{
+	  free_check (*mem);
+	  return true;
+	}
     }
   return false;
 }
 
 static __always_inline bool
-_realloc_debug_before (void *oldmem, size_t bytes, void **victimp,
-			const void *address)
+_realloc_debug_before (void **oldmem, size_t *bytesp, size_t *oldsize,
+		       void **victimp, const void *address)
 {
   void *(*hook) (void *, size_t, const void *) =
     atomic_forced_read (__realloc_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      *victimp = (*hook)(oldmem, bytes, address);
+      *victimp = (*hook)(*oldmem, *bytesp, address);
       return true;
     }
 
-  if (__glibc_unlikely (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)))
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
-      *victimp = realloc_check (oldmem, bytes);
-      return true;
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+	  && realloc_mcheck_before (oldmem, bytesp, oldsize, victimp))
+	return true;
+      if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+	{
+	  *victimp = realloc_check (*oldmem, *bytesp);
+	  return true;
+	}
     }
 
   return false;
 }
 
+static __always_inline void *
+_realloc_debug_after (void *mem, void *oldmem, size_t bytes, size_t oldsize,
+		      const void *address)
+{
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+    mem = realloc_mcheck_after (mem, oldmem, bytes, oldsize);
+  return mem;
+}
+
 static __always_inline bool
-_memalign_debug_before (size_t alignment, size_t bytes, void **victimp,
-			 const void *address)
+_memalign_debug_before (size_t alignment, size_t *bytesp, void **victimp,
+			const void *address)
 {
   void *(*hook) (size_t, size_t, const void *) =
     atomic_forced_read (__memalign_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      *victimp = (*hook)(alignment, bytes, address);
+      *victimp = (*hook)(alignment, *bytesp, address);
       return true;
     }
-
-  if (__glibc_unlikely (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)))
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
-      *victimp = memalign_check (alignment, bytes);
-      return true;
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+	  && memalign_mcheck_before (alignment, bytesp, victimp))
+	return true;
+      if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+	{
+	  *victimp = memalign_check (alignment, *bytesp);
+	  return true;
+	}
     }
 
   return false;
 }
 
+static __always_inline void *
+_memalign_debug_after (void *mem, size_t alignment, size_t bytes,
+		       const void *address)
+{
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+    mem = memalign_mcheck_after (mem, alignment, bytes);
+  return mem;
+}
+
 static __always_inline bool
-_calloc_debug_before (size_t bytes, void **victimp, const void *address)
+_calloc_debug_before (size_t *bytesp, void **victimp, const void *address)
 {
   void *(*hook) (size_t, const void *) =
     atomic_forced_read (__malloc_hook);
   if (__builtin_expect (hook != NULL, 0))
     {
-      *victimp = (*hook)(bytes, address);
+      *victimp = (*hook)(*bytesp, address);
+
       if (*victimp != NULL)
-	memset (*victimp, 0, bytes);
+	memset (*victimp, 0, *bytesp);
+
       return true;
     }
 
-  if (__glibc_unlikely (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)))
+  /* Memory is zeroed out in the AFTER hook.  */
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
-      *victimp = malloc_check (bytes);
-      if (*victimp != NULL)
-	memset (*victimp, 0, bytes);
-      return true;
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+	  && malloc_mcheck_before (bytesp, victimp))
+	return true;
+      if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+	{
+	  *victimp = malloc_check (*bytesp);
+	  return true;
+	}
     }
   return false;
 }
 
+static __always_inline void *
+_calloc_debug_after (void *mem, size_t bytes, const void *address)
+{
+  if (__glibc_unlikely (__malloc_debugging_hooks) && mem != NULL)
+    {
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+	mem = malloc_mcheck_after (mem, bytes);
+      memset (mem, 0, bytes);
+    }
+  return mem;
+}
+
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
 
 /* Support for restoring dumped heaps contained in historic Emacs
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 60753446a1..c899619e50 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3191,13 +3191,14 @@ void *
 __libc_malloc (size_t bytes)
 {
   mstate ar_ptr;
-  void *victim;
+  void *victim = NULL;
+  size_t orig_bytes = bytes;
 
   if (__malloc_initialized < 0)
     ptmalloc_init ();
 
-  if (_malloc_debug_before (bytes, &victim, RETURN_ADDRESS (0)))
-    return victim;
+  if (_malloc_debug_before (&bytes, &victim, RETURN_ADDRESS (0)))
+    goto out;
 
 #if USE_TCACHE
   /* int_free also calls request2size, be careful to not pad twice.  */
@@ -3205,7 +3206,8 @@ __libc_malloc (size_t bytes)
   if (!checked_request2size (bytes, &tbytes))
     {
       __set_errno (ENOMEM);
-      return NULL;
+      victim = NULL;
+      goto out;
     }
   size_t tc_idx = csize2tidx (tbytes);
 
@@ -3217,7 +3219,8 @@ __libc_malloc (size_t bytes)
       && tcache->counts[tc_idx] > 0)
     {
       victim = tcache_get (tc_idx);
-      return tag_new_usable (victim);
+      victim = tag_new_usable (victim);
+      goto out;
     }
   DIAG_POP_NEEDS_COMMENT;
 #endif
@@ -3227,7 +3230,7 @@ __libc_malloc (size_t bytes)
       victim = tag_new_usable (_int_malloc (&main_arena, bytes));
       assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
 	      &main_arena == arena_for_chunk (mem2chunk (victim)));
-      return victim;
+      goto out;
     }
 
   arena_get (ar_ptr, bytes);
@@ -3249,7 +3252,9 @@ __libc_malloc (size_t bytes)
 
   assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
           ar_ptr == arena_for_chunk (mem2chunk (victim)));
-  return victim;
+
+out:
+  return _malloc_debug_after (victim, orig_bytes, RETURN_ADDRESS (0));
 }
 libc_hidden_def (__libc_malloc)
 
@@ -3262,7 +3267,7 @@ __libc_free (void *mem)
   if (__malloc_initialized < 0)
     ptmalloc_init ();
 
-  if (_free_debug_before (mem, RETURN_ADDRESS (0)))
+  if (_free_debug_before (&mem, RETURN_ADDRESS (0)))
     return;
 
   if (mem == 0)                              /* free(0) has no effect */
@@ -3315,23 +3320,30 @@ __libc_realloc (void *oldmem, size_t bytes)
   INTERNAL_SIZE_T nb;         /* padded request size */
 
   void *newp;             /* chunk to return */
+  size_t orig_bytes = bytes, debug_osize = 0;
 
   if (__malloc_initialized < 0)
     ptmalloc_init ();
 
-  if (_realloc_debug_before (oldmem, bytes, &newp, RETURN_ADDRESS (0)))
-    return newp;
+  if (_realloc_debug_before (&oldmem, &bytes, &debug_osize, &newp,
+			     RETURN_ADDRESS (0)))
+    goto out;
 
 #if REALLOC_ZERO_BYTES_FREES
   if (bytes == 0 && oldmem != NULL)
     {
-      __libc_free (oldmem); return 0;
+      __libc_free (oldmem);
+      newp = NULL;
+      goto out;
     }
 #endif
 
   /* realloc of null is supposed to be same as malloc */
   if (oldmem == 0)
-    return __libc_malloc (bytes);
+    {
+      newp = __libc_malloc (bytes);
+      goto out;
+    }
 
   /* Perform a quick check to ensure that the pointer's tag matches the
      memory's tag.  */
@@ -3365,7 +3377,8 @@ __libc_realloc (void *oldmem, size_t bytes)
   if (!checked_request2size (bytes, &nb))
     {
       __set_errno (ENOMEM);
-      return NULL;
+      newp = NULL;
+      goto out;
     }
 
   if (chunk_is_mmapped (oldp))
@@ -3377,7 +3390,10 @@ __libc_realloc (void *oldmem, size_t bytes)
 	  /* Must alloc, copy, free. */
 	  void *newmem = __libc_malloc (bytes);
 	  if (newmem == 0)
-	    return NULL;
+	    {
+	      newp = NULL;
+	      goto out;
+	    }
 	  /* Copy as many bytes as are available from the old chunk
 	     and fit into the new size.  NB: The overhead for faked
 	     mmapped chunks is only SIZE_SZ, not CHUNK_HDR_SZ as for
@@ -3385,7 +3401,8 @@ __libc_realloc (void *oldmem, size_t bytes)
 	  if (bytes > oldsize - SIZE_SZ)
 	    bytes = oldsize - SIZE_SZ;
 	  memcpy (newmem, oldmem, bytes);
-	  return newmem;
+	  newp = newmem;
+	  goto out;
 	}
 
       void *newmem;
@@ -3400,21 +3417,29 @@ __libc_realloc (void *oldmem, size_t bytes)
 	     reused.  There's a performance hit for both us and the
 	     caller for doing this, so we might want to
 	     reconsider.  */
-	  return tag_new_usable (newmem);
+	  newp = tag_new_usable (newmem);
+	  goto out;
 	}
 #endif
       /* Note the extra SIZE_SZ overhead. */
       if (oldsize - SIZE_SZ >= nb)
-        return oldmem;                         /* do nothing */
+	{
+	  newp = oldmem;                         /* do nothing */
+	  goto out;
+	}
 
       /* Must alloc, copy, free. */
       newmem = __libc_malloc (bytes);
       if (newmem == 0)
-        return 0;              /* propagate failure */
+	{
+	  newp = NULL;              /* propagate failure */
+	  goto out;
+	}
 
       memcpy (newmem, oldmem, oldsize - CHUNK_HDR_SZ);
       munmap_chunk (oldp);
-      return newmem;
+      newp = newmem;
+      goto out;
     }
 
   if (SINGLE_THREAD_P)
@@ -3423,7 +3448,7 @@ __libc_realloc (void *oldmem, size_t bytes)
       assert (!newp || chunk_is_mmapped (mem2chunk (newp)) ||
 	      ar_ptr == arena_for_chunk (mem2chunk (newp)));
 
-      return newp;
+      goto out;
     }
 
   __libc_lock_lock (ar_ptr->mutex);
@@ -3448,7 +3473,9 @@ __libc_realloc (void *oldmem, size_t bytes)
         }
     }
 
-  return newp;
+out:
+  return _realloc_debug_after (newp, oldmem, orig_bytes, debug_osize,
+			       RETURN_ADDRESS (0));
 }
 libc_hidden_def (__libc_realloc)
 
@@ -3467,13 +3494,17 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
 {
   mstate ar_ptr;
   void *p;
+  size_t orig_bytes = bytes;
 
-  if (_memalign_debug_before (alignment, bytes, &p, address))
-    return p;
+  if (_memalign_debug_before (alignment, &bytes, &p, address))
+    goto out;
 
   /* If we need less alignment than we give anyway, just relay to malloc.  */
   if (alignment <= MALLOC_ALIGNMENT)
-    return __libc_malloc (bytes);
+    {
+      p = __libc_malloc (bytes);
+      goto out;
+    }
 
   /* Otherwise, ensure that it is at least a minimum chunk size */
   if (alignment < MINSIZE)
@@ -3484,7 +3515,8 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
   if (alignment > SIZE_MAX / 2 + 1)
     {
       __set_errno (EINVAL);
-      return 0;
+      p = NULL;
+      goto out;
     }
 
 
@@ -3502,7 +3534,8 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
       p = _int_memalign (&main_arena, alignment, bytes);
       assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
 	      &main_arena == arena_for_chunk (mem2chunk (p)));
-      return tag_new_usable (p);
+      p = tag_new_usable (p);
+      goto out;
     }
 
   arena_get (ar_ptr, bytes + alignment + MINSIZE);
@@ -3520,7 +3553,9 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
 
   assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
           ar_ptr == arena_for_chunk (mem2chunk (p)));
-  return tag_new_usable (p);
+  p = tag_new_usable (p);
+out:
+  return _memalign_debug_after (p, alignment, orig_bytes, RETURN_ADDRESS (0));
 }
 /* For ISO C11.  */
 weak_alias (__libc_memalign, aligned_alloc)
@@ -3582,8 +3617,8 @@ __libc_calloc (size_t n, size_t elem_size)
   if (__malloc_initialized < 0)
     ptmalloc_init ();
 
-  if (_calloc_debug_before (sz, &mem, RETURN_ADDRESS (0)))
-    return mem;
+  if (_calloc_debug_before (&sz, &mem, RETURN_ADDRESS (0)))
+    goto out;
 
   MAYBE_INIT_TCACHE ();
 
@@ -3639,7 +3674,10 @@ __libc_calloc (size_t n, size_t elem_size)
 
   /* Allocation failed even after a retry.  */
   if (mem == 0)
-    return 0;
+    {
+      mem = NULL;
+      goto out;
+    }
 
   mchunkptr p = mem2chunk (mem);
 
@@ -3647,7 +3685,10 @@ __libc_calloc (size_t n, size_t elem_size)
      regardless of MORECORE_CLEARS, so we zero the whole block while
      doing so.  */
   if (__glibc_unlikely (mtag_enabled))
-    return tag_new_zero_region (mem, memsize (p));
+    {
+      mem = tag_new_zero_region (mem, memsize (p));
+      goto out;
+    }
 
   INTERNAL_SIZE_T csz = chunksize (p);
 
@@ -3655,9 +3696,9 @@ __libc_calloc (size_t n, size_t elem_size)
   if (chunk_is_mmapped (p))
     {
       if (__builtin_expect (perturb_byte, 0))
-        return memset (mem, 0, sz);
+        memset (mem, 0, sz);
 
-      return mem;
+      goto out;
     }
 
 #if MORECORE_CLEARS
@@ -3677,7 +3718,10 @@ __libc_calloc (size_t n, size_t elem_size)
   assert (nclears >= 3);
 
   if (nclears > 9)
-    return memset (d, 0, clearsize);
+    {
+      memset (d, 0, clearsize);
+      goto out;
+    }
 
   else
     {
@@ -3701,7 +3745,8 @@ __libc_calloc (size_t n, size_t elem_size)
         }
     }
 
-  return mem;
+out:
+  return _calloc_debug_after (mem, bytes, RETURN_ADDRESS (0));
 }
 
 /*
diff --git a/malloc/mcheck-hooks.c b/malloc/mcheck-hooks.c
new file mode 100644
index 0000000000..f3520c7659
--- /dev/null
+++ b/malloc/mcheck-hooks.c
@@ -0,0 +1,411 @@
+/* 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 <mcheck.h>
+#include <libintl.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.  */
+};
+
+/* This is the beginning of the list of all memory blocks allocated.
+   It is only constructed if the pedantic testing is requested.  */
+struct hdr *__mcheck_root;
+
+/* Nonzero if pedentic checking of all blocks is requested.  */
+static bool pedantic;
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
+/* Flag to initialize mcheck on first malloc invocation through -lmcheck.
+   libmcheck.a overrides this with a strong symbol initialized to 1.  The
+   symbol cannot be linked against directly during build.  */
+const int __libc_lmcheck __attribute__ ((weak));
+compat_symbol (libc, __libc_lmcheck, __libc_lmcheck, GLIBC_2_34);
+#endif
+
+#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;
+}
+
+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 = __mcheck_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
+    __mcheck_root = ptr->next;
+}
+
+static void
+link_blk (struct hdr *hdr)
+{
+  hdr->prev = NULL;
+  hdr->next = __mcheck_root;
+  __mcheck_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 = __libc_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 __libc_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;
+
+  /* Handle special cases to avoid adding multiple headers.  */
+  if (size == 0)
+    {
+      __libc_free (ptr);
+      *victimp = NULL;
+      return true;
+    }
+
+  if (ptr == NULL)
+    {
+      *victimp = __libc_malloc (size);
+      *oldsize = 0;
+      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
+}
+
+int
+__mcheck_initialize (void (*func) (enum mcheck_status), bool in_pedantic)
+{
+  abortfunc = (func != NULL) ? func : &mabort;
+
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+    goto out;
+
+  switch (__malloc_initialized)
+    {
+    case -1:
+      ptmalloc_init ();
+      /* FALLTHROUGH */
+    case 0:
+      __malloc_debug_enable (MALLOC_MCHECK_HOOK);
+      break;
+    default:
+      break;
+    }
+
+  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+    return -1;
+
+out:
+  pedantic = in_pedantic;
+  return 0;
+}
diff --git a/malloc/mcheck-init.c b/malloc/mcheck-init.c
index 9ee69ee5f8..e3d08ae05f 100644
--- a/malloc/mcheck-init.c
+++ b/malloc/mcheck-init.c
@@ -17,17 +17,7 @@
 
 /* The object of this file should be installed as libmcheck.a,
    so one can do -lmcheck to turn on mcheck.  */
-
-#include <malloc.h>
-#include <mcheck.h>
 #include <shlib-compat.h>
 
-static void
-turn_on_mcheck (void)
-{
-  mcheck (NULL);
-}
-
-void (*__malloc_initialize_hook) (void) = turn_on_mcheck;
-compat_symbol_reference (libc, __malloc_initialize_hook,
-                         __malloc_initialize_hook, GLIBC_2_0);
+const int __libc_lmcheck = 1;
+compat_symbol_reference (libc, __libc_lmcheck, __libc_lmcheck, GLIBC_2_34);
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 2a1fc645d4..f60766eded 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.
@@ -23,378 +23,22 @@
 # include <mcheck.h>
 # include <stdint.h>
 # include <stdio.h>
-# include <libintl.h>
 # include <errno.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.  */
-};
-
-/* 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
-#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;
-
-  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;
+  __mcheck_checkptr (NULL);
 }
 #ifdef _LIBC
 libc_hidden_def (mcheck_check_all)
 #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;
+  return __mcheck_initialize (func, false);
 }
 #ifdef _LIBC
 libc_hidden_def (mcheck)
@@ -403,14 +47,11 @@ libc_hidden_def (mcheck)
 int
 mcheck_pedantic (void (*func) (enum mcheck_status))
 {
-  int res = mcheck (func);
-  if (res == 0)
-    pedantic = 1;
-  return res;
+  return __mcheck_initialize (func, true);
 }
 
 enum mcheck_status
 mprobe (void *ptr)
 {
-  return mcheck_used ? checkhdr (((struct hdr *) ptr) - 1) : MCHECK_DISABLED;
+  return __mcheck_checkptr (ptr);
 }
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index fcfe64f26b..27e8f14bb5 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2223,6 +2223,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 _hurd_libc_proc_init F
 GLIBC_2.34 dladdr F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index ea7fdabc5a..2265dad80a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2376,6 +2376,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 8b1adc918b..47fc4f6cf8 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2475,6 +2475,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 740f39add4..8d1471b667 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2135,6 +2135,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 6f41d2c0fa..dfd4103860 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -221,6 +221,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 695f809fce..d3f6b8fd8c 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -218,6 +218,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index cc017b487f..ecf3a8b659 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2349,6 +2349,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index b6b087d6ac..bb714a710c 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2302,6 +2302,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 40f740253b..a7b6d8b4ed 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2486,6 +2486,7 @@ GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 157f244ea0..23bfd68b8f 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2313,6 +2313,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index bbc40bb608..9e789900dd 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -222,6 +222,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 5aba59e956..94eb746dd4 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2429,6 +2429,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index bfa665f086..f45ba3758a 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2400,6 +2400,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index cf93327b44..bae3991de7 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2397,6 +2397,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 1ff01ce150..827a4845de 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2394,6 +2394,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 104d8cbc02..a8c7bade80 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2392,6 +2392,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 6285d3c8f8..f7b45b1c57 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2400,6 +2400,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 6a4c1816d4..ea313e3df3 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2364,6 +2364,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 4cc199dbdb..2b98816248 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2439,6 +2439,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 46a5759c0a..e0bb842406 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2456,6 +2456,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 10ac038d7c..3894dffc2e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2489,6 +2489,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index eaa36b3fc7..ed2e897c77 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2277,6 +2277,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 9d7c55a4b5..d7f68309ec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2572,6 +2572,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index b902197ee9..f710c934a5 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2137,6 +2137,7 @@ GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 9609912bd5..cbd15300df 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2337,6 +2337,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 8f11602d61..2b61b2bef5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2454,6 +2454,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 876aa5ea80..dd87763a14 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2314,6 +2314,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index c4b037321b..c27f302acd 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2309,6 +2309,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index fbceadac42..0f7542cc8b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2306,6 +2306,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 12f050136c..f8239149d7 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2449,6 +2449,7 @@ GLIBC_2.34 __glob64_time64 F
 GLIBC_2.34 __globfree64_time64 F
 GLIBC_2.34 __gmtime64 F
 GLIBC_2.34 __gmtime64_r F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __localtime64 F
 GLIBC_2.34 __localtime64_r F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index bc99f6f6d7..f2284b29ff 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2336,6 +2336,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 0d98e85292..7494e490cf 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2292,6 +2292,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index b6d917c71e..2ddc8b8de6 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2391,6 +2391,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 _Fork F
 GLIBC_2.34 __isnanf128 F
+GLIBC_2.34 __libc_lmcheck D 0x4
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 __mq_open_2 F
 GLIBC_2.34 __pthread_cleanup_routine F
