unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v8 00/10] malloc hooks removal
@ 2021-07-13  7:38 Siddhesh Poyarekar via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier Siddhesh Poyarekar via Libc-alpha
                   ` (11 more replies)
  0 siblings, 12 replies; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

This patchset removes the malloc hooks __malloc_hook, __free_hook,
__realloc_hook and __memalign_hook from the API and leaves compatibility
symbols so that existing applications can continue to link to them.  The
reading and execution of the hooks has been moved to a DSO
libc_malloc_debug.so, which can be preloaded for applications that need
it.  By default these hooks no longer have any effect in the library.

Further, debugging features such as MALLOC_CHECK_, mcheck() and mtrace
have been weaned away from these hooks and also moved to
libc_malloc_debug.so.  With this change, these features are only enabled
when libc_malloc_debug.so is preloaded using LD_PRELOAD.

Finally, the __morecore, __morecore_after_hook and __default_morecore
hooks have also been moved to compat symbols and removed from the API.
Existing applications will continue to link to them but they won't have
any effect on malloc behaviour.

Testing:

The patchset has gone through a full build and test on x86_64, i686,
s390x, ppc64le, armv7l and aarch64 through a scratch build on Fedora
rawhide.  I also installed a test package on x86_64 and rebooted to make
sure the system boots to shell.  I did a build-many-glibcs run with
the patchset and it ran clean on all targets.

Changes from v7:
- Made mcheck tests conditional on GLIBC_2.24
- Added SHLIB_COMPAT guard around __malloc_initialize_hook usage in
  libc_malloc_debug.so
- Fixed hurd build failure.
- Add another patch to fix malloc_usable_size to mcheck

Changes from v6:
- Moved malloc-check into libc_malloc_debug.so. Tweaked malloc.c to
  allow building twice, once inside libc.so and next in
  libc_malloc_debug.so
- Included morecore.c into malloc.c
- Moved hook initialization too into libc_malloc_debug.so.
- Interposed more functions in libc_malloc_debug.so
- Versioned all symbols exported from libc_malloc_debug.so and finalized
  them so that the library cannot be linked against

Changes from v5:
- Rebased on latest master
- Fixed realloc-mcheck
- Removed residual mention of libmalloc_compathooks
- Removed LD_PRELOAD from elf/tst-setuid

Changes from v4:
- Patchset has a different approach, starting with moving out hooks
  first to restrict all major malloc.c changes to the first patch
- Renamed libmalloc_compathooks.so to libc_malloc_debug.so
- Moved all debugging features into libc_malloc_debug.so
- Made more documentation updates
- Simplified __malloc_initialized variable use
- Removed debugging tests on static variables since that is no longer
  supported

Changes from v3:
- Remove source file dependencies
- Commit mcheck tests

Changes from v2:
- Move hooks dependencies to malloc.o{,sS}

Changes from v1:

- Added makefile dependencies for the new hooks files
- Fixed memset call in calloc debugging hooks
- Added the tr_break deprecation patch and mcheck test patch to this
  series


Siddhesh Poyarekar (10):
  Make mcheck tests conditional on GLIBC_2.24 or earlier
  Remove __after_morecore_hook
  Remove __morecore and __default_morecore
  Move malloc hooks into a compat DSO
  mcheck: Wean away from malloc hooks
  Simplify __malloc_initialized
  mtrace: Wean away from malloc hooks
  glibc.malloc.check: Wean away from malloc hooks
  Remove malloc hooks
  mcheck Fix malloc_usable_size [BZ #22057]

 NEWS                                          |  21 +
 Rules                                         |   9 +-
 catgets/Makefile                              |   4 +-
 elf/Makefile                                  |  15 +-
 elf/tst-leaks1-static.c                       |   1 -
 iconvdata/Makefile                            |   3 +-
 include/malloc.h                              |   6 -
 include/mcheck.h                              |   4 -
 include/stdlib.h                              |   3 -
 intl/tst-gettext.sh                           |   1 +
 libio/Makefile                                |  12 +-
 localedata/Makefile                           |   3 +-
 malloc/Makefile                               |  56 +-
 malloc/Versions                               |  44 ++
 malloc/arena.c                                |  48 +-
 malloc/hooks.c                                |  71 ++-
 malloc/malloc-check.c                         |  63 ++-
 malloc/malloc-debug.c                         | 522 ++++++++++++++++++
 malloc/malloc-hooks.h                         |  24 -
 malloc/malloc.c                               | 163 ++----
 malloc/malloc.h                               |  27 -
 malloc/mcheck-impl.c                          | 412 ++++++++++++++
 malloc/mcheck.c                               | 397 +------------
 malloc/morecore.c                             |  34 +-
 malloc/mtrace-impl.c                          | 226 ++++++++
 malloc/mtrace.c                               | 313 +----------
 malloc/tst-compathooks-off.c                  | 145 +++++
 malloc/tst-compathooks-on.c                   |   2 +
 malloc/tst-malloc-usable-static-tunables.c    |   1 -
 malloc/tst-malloc-usable-static.c             |   1 -
 malloc/tst-mtrace.sh                          |   1 +
 manual/memory.texi                            | 207 +------
 manual/tunables.texi                          |   4 +-
 misc/Makefile                                 |   6 +-
 nptl/Makefile                                 |   3 +-
 posix/Makefile                                |  48 +-
 resolv/Makefile                               |   9 +-
 shlib-versions                                |   3 +
 stdio-common/Makefile                         |  15 +-
 sysdeps/aarch64/Makefile                      |   3 +
 sysdeps/generic/libc_malloc_debug.abilist     |   0
 sysdeps/generic/localplt.data                 |   1 -
 sysdeps/mach/hurd/Makefile                    |   1 +
 .../mach/hurd/i386/libc_malloc_debug.abilist  |  26 +
 sysdeps/mach/hurd/i386/localplt.data          |   1 -
 sysdeps/pthread/Makefile                      |   3 +-
 .../linux/aarch64/libc_malloc_debug.abilist   |  26 +
 sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
 .../linux/alpha/libc_malloc_debug.abilist     |  26 +
 sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
 .../sysv/linux/arc/libc_malloc_debug.abilist  |  26 +
 sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
 .../linux/arm/be/libc_malloc_debug.abilist    |  26 +
 .../linux/arm/le/libc_malloc_debug.abilist    |  26 +
 sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
 .../sysv/linux/csky/libc_malloc_debug.abilist |  26 +
 sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
 .../sysv/linux/hppa/libc_malloc_debug.abilist |  26 +
 sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/hppa/shlib-versions   |   2 +
 .../sysv/linux/i386/libc_malloc_debug.abilist |  26 +
 sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
 .../sysv/linux/ia64/libc_malloc_debug.abilist |  26 +
 sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/ia64/shlib-versions   |   2 +
 .../m68k/coldfire/libc_malloc_debug.abilist   |  26 +
 .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
 .../m68k/m680x0/libc_malloc_debug.abilist     |  26 +
 .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
 .../microblaze/be/libc_malloc_debug.abilist   |  26 +
 .../microblaze/le/libc_malloc_debug.abilist   |  26 +
 .../unix/sysv/linux/microblaze/localplt.data  |   1 -
 .../mips/mips32/fpu/libc_malloc_debug.abilist |  26 +
 .../mips32/nofpu/libc_malloc_debug.abilist    |  26 +
 .../mips/mips64/n32/libc_malloc_debug.abilist |  26 +
 .../mips/mips64/n64/libc_malloc_debug.abilist |  26 +
 sysdeps/unix/sysv/linux/mips/shlib-versions   |   2 +
 .../linux/nios2/libc_malloc_debug.abilist     |  26 +
 sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
 .../powerpc32/fpu/libc_malloc_debug.abilist   |  26 +
 .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
 .../powerpc32/nofpu/libc_malloc_debug.abilist |  26 +
 .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
 .../powerpc64/be/libc_malloc_debug.abilist    |  26 +
 .../powerpc64/le/libc_malloc_debug.abilist    |  26 +
 .../linux/powerpc/powerpc64/localplt.data     |   1 -
 sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
 .../riscv/rv32/libc_malloc_debug.abilist      |  26 +
 .../riscv/rv64/libc_malloc_debug.abilist      |  26 +
 sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
 .../s390/s390-32/libc_malloc_debug.abilist    |  26 +
 .../s390/s390-64/libc_malloc_debug.abilist    |  26 +
 .../linux/sh/be/libc_malloc_debug.abilist     |  26 +
 .../linux/sh/le/libc_malloc_debug.abilist     |  26 +
 sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
 sysdeps/unix/sysv/linux/sh/shlib-versions     |   1 +
 .../sparc/sparc32/libc_malloc_debug.abilist   |  26 +
 .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
 .../sparc/sparc64/libc_malloc_debug.abilist   |  26 +
 .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
 .../sysv/linux/sparc/sparc64/shlib-versions   |   1 +
 .../linux/x86_64/64/libc_malloc_debug.abilist |  26 +
 .../x86_64/x32/libc_malloc_debug.abilist      |  26 +
 sysdeps/x86_64/localplt.data                  |   1 -
 104 files changed, 2557 insertions(+), 1266 deletions(-)
 delete mode 100644 elf/tst-leaks1-static.c
 create mode 100644 malloc/malloc-debug.c
 delete mode 100644 malloc/malloc-hooks.h
 create mode 100644 malloc/mcheck-impl.c
 create mode 100644 malloc/mtrace-impl.c
 create mode 100644 malloc/tst-compathooks-off.c
 create mode 100644 malloc/tst-compathooks-on.c
 delete mode 100644 malloc/tst-malloc-usable-static-tunables.c
 delete mode 100644 malloc/tst-malloc-usable-static.c
 create mode 100644 sysdeps/generic/libc_malloc_debug.abilist
 create mode 100644 sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist

-- 
2.31.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 02/10] Remove __after_morecore_hook Siddhesh Poyarekar via Libc-alpha
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Targets with base versions later than 2.24 won't have
__malloc_initialize_hook because of which the tests will essentially
be the same as the regular malloc tests.  Avoid running them instead
and save time.
---
 malloc/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/malloc/Makefile b/malloc/Makefile
index 47369b6084..d15729569b 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -78,6 +78,8 @@ tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \
 # Run all tests with MALLOC_CHECK_=3
 tests-malloc-check = $(filter-out $(tests-exclude-malloc-check),$(tests))
 
+# -lmcheck needs __malloc_initialize_hook, which was deprecated in 2.24.
+ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)
 # Tests that don't play well with mcheck.  They are either bugs in mcheck or
 # the tests expect specific internal behavior that is changed due to linking to
 # libmcheck.a.
@@ -100,6 +102,7 @@ tests-exclude-mcheck = tst-mallocstate \
 	tst-reallocarray
 
 tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
+endif
 
 routines = malloc morecore mcheck mtrace obstack reallocarray \
   scratch_buffer_dupfree \
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 02/10] Remove __after_morecore_hook
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 03/10] Remove __morecore and __default_morecore Siddhesh Poyarekar via Libc-alpha
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Remove __after_morecore_hook from the API and finalize the symbol so
that it can no longer be used in new applications.  Old applications
using __after_morecore_hook will find that their hook is no longer
called.
---
 malloc/hooks.c  |  5 +++++
 malloc/malloc.c | 22 +---------------------
 malloc/malloc.h |  3 ---
 3 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/malloc/hooks.c b/malloc/hooks.c
index daa5c7cfae..45c91d6502 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -17,6 +17,11 @@
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, see <https://www.gnu.org/licenses/>.  */
 
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
+void weak_variable (*__after_morecore_hook) (void) = NULL;
+compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
+#endif
+
 /* Hooks for debugging versions.  The initial hooks just call the
    initialization routine, then do the normal work. */
 
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 154f6b460c..24e7854a0e 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2041,8 +2041,6 @@ void *weak_variable (*__realloc_hook)
 void *weak_variable (*__memalign_hook)
   (size_t __alignment, size_t __size, const void *)
   = memalign_hook_ini;
-void weak_variable (*__after_morecore_hook) (void) = NULL;
-
 /* This function is called from the arena shutdown hook, to free the
    thread cache (if it exists).  */
 static void tcache_thread_shutdown (void);
@@ -2668,14 +2666,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
           LIBC_PROBE (memory_sbrk_more, 2, brk, size);
         }
 
-      if (brk != (char *) (MORECORE_FAILURE))
-        {
-          /* Call the `morecore' hook if necessary.  */
-          void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
-          if (__builtin_expect (hook != NULL, 0))
-            (*hook)();
-        }
-      else
+      if (brk == (char *) (MORECORE_FAILURE))
         {
           /*
              If have mmap, try using it as a backup when MORECORE fails or
@@ -2814,13 +2805,6 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
                       correction = 0;
                       snd_brk = (char *) (MORECORE (0));
                     }
-                  else
-                    {
-                      /* Call the `morecore' hook if necessary.  */
-                      void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
-                      if (__builtin_expect (hook != NULL, 0))
-                        (*hook)();
-                    }
                 }
 
               /* handle non-contiguous cases */
@@ -2979,10 +2963,6 @@ systrim (size_t pad, mstate av)
        */
 
       MORECORE (-extra);
-      /* Call the `morecore' hook if necessary.  */
-      void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
-      if (__builtin_expect (hook != NULL, 0))
-        (*hook)();
       new_brk = (char *) (MORECORE (0));
 
       LIBC_PROBE (memory_sbrk_less, 2, new_brk, extra);
diff --git a/malloc/malloc.h b/malloc/malloc.h
index c1c0896d29..634b7db868 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -179,9 +179,6 @@ extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
                                                        size_t __size,
                                                        const void *)
 __MALLOC_DEPRECATED;
-extern void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void)
-  __MALLOC_DEPRECATED;
-
 
 __END_DECLS
 #endif /* malloc.h */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier Siddhesh Poyarekar via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 02/10] Remove __after_morecore_hook Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-14  7:01   ` Siddhesh Poyarekar
  2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 04/10] Move malloc hooks into a compat DSO Siddhesh Poyarekar via Libc-alpha
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Make the __morecore and __default_morecore symbols compat-only and
remove their declarations from the API.  Also, include morecore.c
directly into malloc.c; this should ideally get merged into malloc in
a future cleanup.
---
 NEWS              |  5 +++++
 include/stdlib.h  |  3 ---
 malloc/Makefile   |  2 +-
 malloc/arena.c    | 12 ++----------
 malloc/hooks.c    |  2 ++
 malloc/malloc.c   |  7 +++----
 malloc/malloc.h   |  8 --------
 malloc/morecore.c | 34 +++++++++++-----------------------
 8 files changed, 24 insertions(+), 49 deletions(-)

diff --git a/NEWS b/NEWS
index 13ffe627da..18d9e65eb2 100644
--- a/NEWS
+++ b/NEWS
@@ -113,6 +113,11 @@ Deprecated and removed features, and other changes affecting compatibility:
   mtrace.  Similar functionality can be achieved by using conditional
   breakpoints within mtrace functions from within gdb.
 
+* The __morecore and __after_morecore_hook malloc hooks and the default
+  implementation __default_morecore have been removed from the API.  Existing
+  applications will continue to link against these symbols but the interfaces
+  no longer have any effect on malloc.
+
 Changes to build and runtime requirements:
 
 * On Linux, the shm_open, sem_open, and related functions now expect the
diff --git a/include/stdlib.h b/include/stdlib.h
index 1f6e1508e4..1c6f70b082 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -306,9 +306,6 @@ libc_hidden_proto (__qfcvt_r)
 #  define MB_CUR_MAX (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX))
 # endif
 
-extern void *__default_morecore (ptrdiff_t) __THROW;
-libc_hidden_proto (__default_morecore)
-
 struct abort_msg_s
 {
   unsigned int size;
diff --git a/malloc/Makefile b/malloc/Makefile
index d15729569b..020f781b59 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -104,7 +104,7 @@ tests-exclude-mcheck = tst-mallocstate \
 tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
 endif
 
-routines = malloc morecore mcheck mtrace obstack reallocarray \
+routines = malloc mcheck mtrace obstack reallocarray \
   scratch_buffer_dupfree \
   scratch_buffer_grow scratch_buffer_grow_preserve \
   scratch_buffer_set_array_size \
diff --git a/malloc/arena.c b/malloc/arena.c
index 991fc21a7e..f1693ed48f 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -274,14 +274,6 @@ next_env_entry (char ***position)
 #endif
 
 
-#if defined(SHARED) || defined(USE_MTAG)
-static void *
-__failing_morecore (ptrdiff_t d)
-{
-  return (void *) MORECORE_FAILURE;
-}
-#endif
-
 #ifdef SHARED
 extern struct dl_open_hook *_dl_open_hook;
 libc_hidden_proto (_dl_open_hook);
@@ -310,7 +302,7 @@ ptmalloc_init (void)
 	 and that morecore does not support tagged regions, then
 	 disable it.  */
       if (__MTAG_SBRK_UNTAGGED)
-	__morecore = __failing_morecore;
+	__always_fail_morecore = true;
 
       mtag_enabled = true;
       mtag_mmap_flags = __MTAG_MMAP_FLAGS;
@@ -323,7 +315,7 @@ ptmalloc_init (void)
      generic sbrk implementation also enforces this, but it is not
      used on Hurd.  */
   if (!__libc_initial)
-    __morecore = __failing_morecore;
+    __always_fail_morecore = true;
 #endif
 
   thread_arena = &main_arena;
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 45c91d6502..4aa6dadcff 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -20,6 +20,8 @@
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
 void weak_variable (*__after_morecore_hook) (void) = NULL;
 compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
+void *(*__morecore)(ptrdiff_t);
+compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);
 #endif
 
 /* Hooks for debugging versions.  The initial hooks just call the
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 24e7854a0e..6e8fa9e424 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -384,12 +384,11 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
 #define TRIM_FASTBINS  0
 #endif
 
-
 /* Definition for getting more memory from the OS.  */
-#define MORECORE         (*__morecore)
+#include "morecore.c"
+
+#define MORECORE         (*__glibc_morecore)
 #define MORECORE_FAILURE 0
-void * __default_morecore (ptrdiff_t);
-void *(*__morecore)(ptrdiff_t) = __default_morecore;
 
 /* Memory tagging.  */
 
diff --git a/malloc/malloc.h b/malloc/malloc.h
index 634b7db868..17ab9ee345 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -76,14 +76,6 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__
 extern void *pvalloc (size_t __size) __THROW __attribute_malloc__
   __wur __attr_dealloc_free;
 
-/* Underlying allocation function; successive calls should return
-   contiguous pieces of memory.  */
-extern void *(*__morecore) (ptrdiff_t __size) __MALLOC_DEPRECATED;
-
-/* Default value of `__morecore'.  */
-extern void *__default_morecore (ptrdiff_t __size)
-__THROW __attribute_malloc__  __MALLOC_DEPRECATED;
-
 /* SVID2/XPG mallinfo structure */
 
 struct mallinfo
diff --git a/malloc/morecore.c b/malloc/morecore.c
index 047228779b..8168ef158c 100644
--- a/malloc/morecore.c
+++ b/malloc/morecore.c
@@ -15,39 +15,27 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _MALLOC_INTERNAL
-# define _MALLOC_INTERNAL
-# include <malloc.h>
-#endif
-
-#ifndef __GNU_LIBRARY__
-# define __sbrk  sbrk
-#endif
-
-#ifdef __GNU_LIBRARY__
-/* It is best not to declare this and cast its result on foreign operating
-   systems with potentially hostile include files.  */
-
-# include <stddef.h>
-# include <stdlib.h>
-extern void *__sbrk (ptrdiff_t increment) __THROW;
-libc_hidden_proto (__sbrk)
-#endif
-
-#ifndef NULL
-# define NULL 0
+#if defined(SHARED) || defined(USE_MTAG)
+static bool __always_fail_morecore = false;
 #endif
 
 /* Allocate INCREMENT more bytes of data space,
    and return the start of data space, or NULL on errors.
    If INCREMENT is negative, shrink data space.  */
 void *
-__default_morecore (ptrdiff_t increment)
+__glibc_morecore (ptrdiff_t increment)
 {
+#if defined(SHARED) || defined(USE_MTAG)
+  if (__always_fail_morecore)
+    return NULL;
+#endif
+
   void *result = (void *) __sbrk (increment);
   if (result == (void *) -1)
     return NULL;
 
   return result;
 }
-libc_hidden_def (__default_morecore)
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
+compat_symbol (libc, __glibc_morecore, __default_morecore, GLIBC_2_0);
+#endif
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 04/10] Move malloc hooks into a compat DSO
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (2 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 03/10] Remove __morecore and __default_morecore Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 05/10] mcheck: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Remove all malloc hook uses from core malloc functions and move it
into a new library libc_malloc_debug.so.  With this, the hooks now no
longer have any effect on the core library.

libc_malloc_debug.so is a malloc interposer that needs to be preloaded
to get hooks functionality back so that the debugging features that
depend on the hooks, i.e. malloc-check, mcheck and mtrace work again.
Without the preloaded DSO these debugging features will be nops.
These features will be ported away from hooks in subsequent patches.

Similarly, legacy applications that need hooks functionality need to
preload libc_malloc_debug.so.

The symbols exported by libc_malloc_debug.so are maintained at exactly
the same version as libc.so.

Finally, static binaries will no longer be able to use malloc
debugging features since they cannot preload the debugging DSO.
---
 NEWS                                          |   6 +
 Rules                                         |   9 +-
 catgets/Makefile                              |   4 +-
 elf/Makefile                                  |  15 +-
 elf/tst-leaks1-static.c                       |   1 -
 iconvdata/Makefile                            |   3 +-
 intl/tst-gettext.sh                           |   1 +
 libio/Makefile                                |  12 +-
 localedata/Makefile                           |   3 +-
 malloc/Makefile                               |  45 +++--
 malloc/Versions                               |  20 ++
 malloc/arena.c                                |   7 -
 malloc/hooks.c                                |  64 +++++-
 malloc/malloc-debug.c                         | 189 ++++++++++++++++++
 malloc/malloc.c                               |  85 ++------
 malloc/mcheck.c                               |   1 +
 malloc/mtrace.c                               |   1 +
 malloc/tst-compathooks-off.c                  | 145 ++++++++++++++
 malloc/tst-compathooks-on.c                   |   2 +
 malloc/tst-malloc-usable-static-tunables.c    |   1 -
 malloc/tst-malloc-usable-static.c             |   1 -
 malloc/tst-mtrace.sh                          |   1 +
 manual/memory.texi                            |  16 +-
 manual/tunables.texi                          |   4 +-
 misc/Makefile                                 |   6 +-
 nptl/Makefile                                 |   3 +-
 posix/Makefile                                |  40 ++--
 resolv/Makefile                               |   9 +-
 shlib-versions                                |   3 +
 stdio-common/Makefile                         |  15 +-
 sysdeps/generic/libc_malloc_debug.abilist     |   0
 sysdeps/mach/hurd/Makefile                    |   1 +
 .../mach/hurd/i386/libc_malloc_debug.abilist  |   9 +
 sysdeps/pthread/Makefile                      |   3 +-
 .../linux/aarch64/libc_malloc_debug.abilist   |   9 +
 .../linux/alpha/libc_malloc_debug.abilist     |   9 +
 .../sysv/linux/arc/libc_malloc_debug.abilist  |   9 +
 .../linux/arm/be/libc_malloc_debug.abilist    |   9 +
 .../linux/arm/le/libc_malloc_debug.abilist    |   9 +
 .../sysv/linux/csky/libc_malloc_debug.abilist |   9 +
 .../sysv/linux/hppa/libc_malloc_debug.abilist |   9 +
 sysdeps/unix/sysv/linux/hppa/shlib-versions   |   2 +
 .../sysv/linux/i386/libc_malloc_debug.abilist |   9 +
 .../sysv/linux/ia64/libc_malloc_debug.abilist |   9 +
 sysdeps/unix/sysv/linux/ia64/shlib-versions   |   2 +
 .../m68k/coldfire/libc_malloc_debug.abilist   |   9 +
 .../m68k/m680x0/libc_malloc_debug.abilist     |   9 +
 .../microblaze/be/libc_malloc_debug.abilist   |   9 +
 .../microblaze/le/libc_malloc_debug.abilist   |   9 +
 .../mips/mips32/fpu/libc_malloc_debug.abilist |   9 +
 .../mips32/nofpu/libc_malloc_debug.abilist    |   9 +
 .../mips/mips64/n32/libc_malloc_debug.abilist |   9 +
 .../mips/mips64/n64/libc_malloc_debug.abilist |   9 +
 sysdeps/unix/sysv/linux/mips/shlib-versions   |   2 +
 .../linux/nios2/libc_malloc_debug.abilist     |   9 +
 .../powerpc32/fpu/libc_malloc_debug.abilist   |   9 +
 .../powerpc32/nofpu/libc_malloc_debug.abilist |   9 +
 .../powerpc64/be/libc_malloc_debug.abilist    |   9 +
 .../powerpc64/le/libc_malloc_debug.abilist    |   9 +
 .../riscv/rv32/libc_malloc_debug.abilist      |   9 +
 .../riscv/rv64/libc_malloc_debug.abilist      |   9 +
 .../s390/s390-32/libc_malloc_debug.abilist    |   9 +
 .../s390/s390-64/libc_malloc_debug.abilist    |   9 +
 .../linux/sh/be/libc_malloc_debug.abilist     |   9 +
 .../linux/sh/le/libc_malloc_debug.abilist     |   9 +
 sysdeps/unix/sysv/linux/sh/shlib-versions     |   1 +
 .../sparc/sparc32/libc_malloc_debug.abilist   |   9 +
 .../sparc/sparc64/libc_malloc_debug.abilist   |   9 +
 .../sysv/linux/sparc/sparc64/shlib-versions   |   1 +
 .../linux/x86_64/64/libc_malloc_debug.abilist |   9 +
 .../x86_64/x32/libc_malloc_debug.abilist      |   9 +
 71 files changed, 864 insertions(+), 157 deletions(-)
 delete mode 100644 elf/tst-leaks1-static.c
 create mode 100644 malloc/malloc-debug.c
 create mode 100644 malloc/tst-compathooks-off.c
 create mode 100644 malloc/tst-compathooks-on.c
 delete mode 100644 malloc/tst-malloc-usable-static-tunables.c
 delete mode 100644 malloc/tst-malloc-usable-static.c
 create mode 100644 sysdeps/generic/libc_malloc_debug.abilist
 create mode 100644 sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist

diff --git a/NEWS b/NEWS
index 18d9e65eb2..0297d14f87 100644
--- a/NEWS
+++ b/NEWS
@@ -118,6 +118,12 @@ Deprecated and removed features, and other changes affecting compatibility:
   applications will continue to link against these symbols but the interfaces
   no longer have any effect on malloc.
 
+* Debugging features in malloc such as the MALLOC_CHECK_ environment variable
+  (or the glibc.malloc.check tunable), mtrace() and mcheck() have now been
+  disabled by default in the main C library.  Users looking to use these
+  features now need to preload a new debugging DSO libc_malloc_debug.so to get
+  this functionality back.
+
 Changes to build and runtime requirements:
 
 * On Linux, the shm_open, sem_open, and related functions now expect the
diff --git a/Rules b/Rules
index ba13598df6..b1137afe71 100644
--- a/Rules
+++ b/Rules
@@ -279,10 +279,17 @@ endif
 
 # All malloc-check tests will be run with MALLOC_CHECK_=3
 define malloc-check-ENVS
-$(1)-malloc-check-ENV = MALLOC_CHECK_=3
+$(1)-malloc-check-ENV = MALLOC_CHECK_=3 \
+			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 endef
 $(foreach t,$(tests-malloc-check),$(eval $(call malloc-check-ENVS,$(t))))
 
+# mcheck tests need the debug DSO to support -lmcheck.
+define mcheck-ENVS
+$(1)-mcheck-ENV = LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
+endef
+$(foreach t,$(tests-mcheck),$(eval $(call mcheck-ENVS,$(t))))
+
 ifneq "$(strip $(tests) $(tests-internal) $(xtests) $(test-srcs))" ""
 # These are the implicit rules for making test outputs
 # from the test programs and whatever input files are present.
diff --git a/catgets/Makefile b/catgets/Makefile
index 54da9a985f..215965b352 100644
--- a/catgets/Makefile
+++ b/catgets/Makefile
@@ -56,7 +56,9 @@ generated += tst-catgets.mtrace tst-catgets-mem.out
 
 generated-dirs += de
 
-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace
+tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de \
+		  MALLOC_TRACE=$(objpfx)tst-catgets.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 ifeq ($(run-built-tests),yes)
 # This test just checks whether the program produces any error or not.
diff --git a/elf/Makefile b/elf/Makefile
index 4b320e8b3a..66195ea419 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -156,7 +156,7 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force)
 	$(do-install-program)
 endif
 
-tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
+tests-static-normal := tst-array1-static tst-array5-static \
 	       tst-dl-iter-static \
 	       tst-tlsalign-static tst-tlsalign-extern-static \
 	       tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
@@ -242,7 +242,7 @@ endif
 tests += $(tests-execstack-$(have-z-execstack))
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-leaks1-mem.out \
-		 $(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
+		 $(objpfx)noload-mem.out \
 		 $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
 endif
 tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -895,7 +895,8 @@ $(objpfx)noload.out: $(objpfx)testobj5.so
 $(objpfx)noload-mem.out: $(objpfx)noload.out
 	$(common-objpfx)malloc/mtrace $(objpfx)noload.mtrace > $@; \
 	$(evaluate-test)
-noload-ENV = MALLOC_TRACE=$(objpfx)noload.mtrace
+noload-ENV = MALLOC_TRACE=$(objpfx)noload.mtrace \
+	     LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 LDFLAGS-nodelete = -rdynamic
 LDFLAGS-nodelmod1.so = -Wl,--enable-new-dtags,-z,nodelete
@@ -1273,12 +1274,8 @@ $(objpfx)tst-leaks1-mem.out: $(objpfx)tst-leaks1.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@; \
 	$(evaluate-test)
 
-$(objpfx)tst-leaks1-static-mem.out: $(objpfx)tst-leaks1-static.out
-	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1-static.mtrace > $@; \
-	$(evaluate-test)
-
-tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
-tst-leaks1-static-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1-static.mtrace
+tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace \
+		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)tst-thrlock: $(shared-thread-library)
 $(objpfx)tst-thrlock.out: $(libm)
diff --git a/elf/tst-leaks1-static.c b/elf/tst-leaks1-static.c
deleted file mode 100644
index b956d66905..0000000000
--- a/elf/tst-leaks1-static.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "tst-leaks1.c"
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index bb3f621b49..c216f959df 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -301,7 +301,8 @@ cpp-srcs-left := $(modules) $(generated-modules) $(libJIS-routines) \
 lib := iconvdata
 include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
 
-tst-loading-ENV = MALLOC_TRACE=$(objpfx)tst-loading.mtrace
+tst-loading-ENV = MALLOC_TRACE=$(objpfx)tst-loading.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)mtrace-tst-loading.out: $(objpfx)tst-loading.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-loading.mtrace > $@; \
 	$(evaluate-test)
diff --git a/intl/tst-gettext.sh b/intl/tst-gettext.sh
index 77864de18c..37d9fcb80a 100755
--- a/intl/tst-gettext.sh
+++ b/intl/tst-gettext.sh
@@ -50,6 +50,7 @@ msgfmt -o ${objpfx}domaindir/existing-locale/LC_TIME/existing-time-domain.mo \
 ${test_program_prefix_before_env} \
 ${run_program_env} \
 MALLOC_TRACE=$malloc_trace \
+LD_PRELOAD=${common_objpfx}malloc/libc_malloc_debug.so \
 LOCPATH=${objpfx}localedir:${common_objpfx}localedata \
 ${test_program_prefix_after_env} \
 ${objpfx}tst-gettext > ${objpfx}tst-gettext.out ${objpfx}domaindir
diff --git a/libio/Makefile b/libio/Makefile
index 73f731e064..5336b7d595 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -165,10 +165,14 @@ LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
 
 tst_wprintf2-ARGS = "Some Text"
 
-test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
-tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
-tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
-tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
+test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace \
+		    LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
+tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace \
+		   LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
+tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
+tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 generated += test-fmemopen.mtrace test-fmemopen.check
 generated += tst-fopenloc.mtrace tst-fopenloc.check
diff --git a/localedata/Makefile b/localedata/Makefile
index 14e04cd3c5..f585e0dd41 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -456,7 +456,8 @@ $(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir
 tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
 tst-wctype-ENV = LC_ALL=ja_JP.EUC-JP
 
-tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
+tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
+		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@; \
 	$(evaluate-test)
diff --git a/malloc/Makefile b/malloc/Makefile
index 020f781b59..7ea45d2358 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -46,12 +46,11 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 
 tests-static := \
 	 tst-interpose-static-nothread \
-	 tst-interpose-static-thread \
-	 tst-malloc-usable-static \
+	 tst-interpose-static-thread
 
 # Test for the malloc_set_state symbol removed in glibc 2.25.
 ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)
-tests += tst-mallocstate
+tests += tst-mallocstate tst-compathooks-off tst-compathooks-on
 endif
 
 tests-internal := tst-scratch_buffer
@@ -64,7 +63,6 @@ tests-internal += \
 
 ifneq (no,$(have-tunables))
 tests += tst-malloc-usable-tunables tst-mxfast
-tests-static += tst-malloc-usable-static-tunables
 endif
 
 tests += $(tests-static)
@@ -73,7 +71,8 @@ test-srcs = tst-mtrace
 # These tests either are run with MALLOC_CHECK_=3 by default or do not work
 # with MALLOC_CHECK_=3 because they expect a specific failure.
 tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \
-	tst-mxfast tst-safe-linking
+	tst-mxfast tst-safe-linking \
+	tst-compathooks-off tst-compathooks-on
 
 # Run all tests with MALLOC_CHECK_=3
 tests-malloc-check = $(filter-out $(tests-exclude-malloc-check),$(tests))
@@ -91,15 +90,14 @@ tests-exclude-mcheck = tst-mallocstate \
 	tst-malloc-tcache-leak \
 	tst-malloc-thread-exit \
 	tst-malloc-thread-fail \
-	tst-malloc-usable-static \
-	tst-malloc-usable-static-tunables \
 	tst-malloc-usable-tunables \
 	tst-malloc_info \
 	tst-memalign \
 	tst-posix_memalign \
 	tst-realloc \
 	tst-pvalloc-fortify \
-	tst-reallocarray
+	tst-reallocarray \
+	tst-compathooks-off tst-compathooks-on
 
 tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
 endif
@@ -122,8 +120,8 @@ routines = malloc mcheck mtrace obstack reallocarray \
 install-lib := libmcheck.a
 non-lib.a := libmcheck.a
 
-# Additional library.
-extra-libs = libmemusage
+# Additional libraries.
+extra-libs = libmemusage libc_malloc_debug
 extra-libs-others = $(extra-libs)
 
 # Helper objects for some tests.
@@ -138,6 +136,9 @@ test-extras = \
 libmemusage-routines = memusage
 libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
 
+libc_malloc_debug-routines = malloc-debug
+libc_malloc_debug-inhibit-o = $(filter-out .os,$(object-suffixes))
+
 $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
@@ -243,11 +244,12 @@ endif
 endif
 endif
 
-tst-malloc-check-ENV = MALLOC_CHECK_=3
-tst-malloc-usable-ENV = MALLOC_CHECK_=3
-tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV)
-tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3
-tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV)
+tst-malloc-check-ENV = MALLOC_CHECK_=3 \
+		       LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
+tst-malloc-usable-ENV = MALLOC_CHECK_=3 \
+		       LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
+tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
+				 LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
 
 tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
 
@@ -302,12 +304,14 @@ $(objpfx)tst-interpose-static-thread-mcheck: \
 $(objpfx)tst-interpose-static-thread-malloc-check: \
   $(objpfx)tst-interpose-aux-thread.o $(static-thread-library)
 
-tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace
+tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace \
+		   LD_PRELOAD=$(objpfx)libc_malloc_debug.so
 $(objpfx)tst-dynarray-mem.out: $(objpfx)tst-dynarray.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray.mtrace > $@; \
 	$(evaluate-test)
 
-tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
+tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace \
+			LD_PRELOAD=$(objpfx)libc_malloc_debug.so
 $(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@; \
 	$(evaluate-test)
@@ -321,3 +325,10 @@ $(objpfx)tst-mallocfork2-mcheck: $(shared-thread-library)
 $(objpfx)tst-malloc-tcache-leak-malloc-check: $(shared-thread-library)
 $(objpfx)tst-malloc_info-malloc-check: $(shared-thread-library)
 $(objpfx)tst-mallocfork2-malloc-check: $(shared-thread-library)
+
+tst-compathooks-on-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
+tst-compathooks-on-mcheck-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
+tst-compathooks-on-malloc-check-ENV = \
+	LD_PRELOAD=$(objpfx)libc_malloc_debug.so
+tst-mallocstate-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
+tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
diff --git a/malloc/Versions b/malloc/Versions
index 470a940666..c87f6df8ca 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -98,3 +98,23 @@ libc {
     __libc_alloc_buffer_create_failure;
   }
 }
+
+# Keep in sync with symbols in libc.
+libc_malloc_debug {
+  GLIBC_2.0 {
+    calloc;
+    free;
+    malloc;
+    memalign;
+    pvalloc;
+    realloc;
+    valloc;
+
+  }
+  GLIBC_2.2 {
+    posix_memalign;
+  }
+  GLIBC_2.16 {
+    aligned_alloc;
+  }
+}
diff --git a/malloc/arena.c b/malloc/arena.c
index f1693ed48f..9111b49589 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -404,13 +404,6 @@ ptmalloc_init (void)
   if (s && s[0] != '\0' && s[0] != '0')
     __malloc_check_init ();
 #endif
-
-#if HAVE_MALLOC_INIT_HOOK
-  void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
-  if (hook != NULL)
-    (*hook)();
-#endif
-  __malloc_initialized = 1;
 }
 
 /* Managing heaps and arenas (for concurrent threads) */
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 4aa6dadcff..3cd44eeb84 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -1,4 +1,4 @@
-/* Malloc implementation for multiple threads without lock contention.
+/* Compatibility code for malloc debugging and state management.
    Copyright (C) 2001-2021 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
@@ -17,6 +17,16 @@
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, see <https://www.gnu.org/licenses/>.  */
 
+#ifndef weak_variable
+# define weak_variable weak_function
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_24)
+void (*__malloc_initialize_hook) (void);
+compat_symbol (libc, __malloc_initialize_hook,
+	       __malloc_initialize_hook, GLIBC_2_0);
+#endif
+
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
 void weak_variable (*__after_morecore_hook) (void) = NULL;
 compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
@@ -24,32 +34,64 @@ 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. */
 
-static void *
-malloc_hook_ini (size_t sz, const void *caller)
+/* 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 ();
-  return __libc_malloc (sz);
+
+#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)
 {
-  __malloc_hook = NULL;
-  __realloc_hook = NULL;
-  ptmalloc_init ();
-  return __libc_realloc (ptr, sz);
+  generic_hook_ini ();
+  return realloc (ptr, sz);
 }
 
 static void *
 memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
 {
-  __memalign_hook = NULL;
-  ptmalloc_init ();
-  return __libc_memalign (alignment, sz);
+  generic_hook_ini ();
+  return memalign (alignment, sz);
 }
 
 #include "malloc-check.c"
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
new file mode 100644
index 0000000000..41dfcd3369
--- /dev/null
+++ b/malloc/malloc-debug.c
@@ -0,0 +1,189 @@
+/* Malloc debug DSO.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; see the file COPYING.LIB.  If
+   not, see <https://www.gnu.org/licenses/>.  */
+
+#include <atomic.h>
+#include <libc-symbols.h>
+#include <shlib-compat.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+/* Support only the glibc allocators.  */
+extern void *__libc_malloc (size_t);
+extern void __libc_free (void *);
+extern void *__libc_realloc (void *, size_t);
+extern void *__libc_memalign (size_t, size_t);
+extern void *__libc_valloc (size_t);
+extern void *__libc_pvalloc (size_t);
+extern void *__libc_calloc (size_t, size_t);
+
+#define DEBUG_FN(fn) \
+  static __typeof (__libc_ ## fn) __debug_ ## fn
+
+DEBUG_FN(malloc);
+DEBUG_FN(free);
+DEBUG_FN(realloc);
+DEBUG_FN(memalign);
+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 size_t pagesize;
+
+/* The allocator functions.  */
+
+static void *
+__debug_malloc (size_t bytes)
+{
+  void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
+  if (__builtin_expect (hook != NULL, 0))
+    return (*hook)(bytes, RETURN_ADDRESS (0));
+
+  return __libc_malloc (bytes);
+}
+strong_alias (__debug_malloc, malloc)
+
+static void
+__debug_free (void *mem)
+{
+  void (*hook) (void *, const void *) = atomic_forced_read (__free_hook);
+  if (__builtin_expect (hook != NULL, 0))
+    {
+      (*hook)(mem, RETURN_ADDRESS (0));
+      return;
+    }
+  __libc_free (mem);
+}
+strong_alias (__debug_free, free)
+
+static void *
+__debug_realloc (void *oldmem, size_t bytes)
+{
+  void *(*hook) (void *, size_t, const void *) =
+    atomic_forced_read (__realloc_hook);
+  if (__builtin_expect (hook != NULL, 0))
+    return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
+
+  return __libc_realloc (oldmem, bytes);
+}
+strong_alias (__debug_realloc, realloc)
+
+static void *
+_debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
+{
+  void *(*hook) (size_t, size_t, const void *) =
+    atomic_forced_read (__memalign_hook);
+  if (__builtin_expect (hook != NULL, 0))
+    return (*hook)(alignment, bytes, address);
+
+  return __libc_memalign (alignment, bytes);
+}
+
+static void *
+__debug_memalign (size_t alignment, size_t bytes)
+{
+  return _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
+}
+strong_alias (__debug_memalign, memalign)
+strong_alias (__debug_memalign, aligned_alloc)
+
+static void *
+__debug_pvalloc (size_t bytes)
+{
+  size_t rounded_bytes;
+
+  if (!pagesize)
+    pagesize = sysconf (_SC_PAGESIZE);
+
+  /* ALIGN_UP with overflow check.  */
+  if (__glibc_unlikely (__builtin_add_overflow (bytes,
+						pagesize - 1,
+						&rounded_bytes)))
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+  rounded_bytes = rounded_bytes & -(pagesize - 1);
+
+  return _debug_mid_memalign (pagesize, rounded_bytes, RETURN_ADDRESS (0));
+}
+strong_alias (__debug_pvalloc, pvalloc)
+
+static void *
+__debug_valloc (size_t bytes)
+{
+  if (!pagesize)
+    pagesize = sysconf (_SC_PAGESIZE);
+
+  return _debug_mid_memalign (pagesize, bytes, RETURN_ADDRESS (0));
+}
+strong_alias (__debug_valloc, valloc)
+
+static int
+__debug_posix_memalign (void **memptr, size_t alignment, size_t bytes)
+{
+  /* Test whether the SIZE argument is valid.  It must be a power of
+     two multiple of sizeof (void *).  */
+  if (alignment % sizeof (void *) != 0
+      || !powerof2 (alignment / sizeof (void *))
+      || alignment == 0)
+    return EINVAL;
+
+  *memptr = _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
+
+  if (*memptr == NULL)
+    return ENOMEM;
+
+  return 0;
+}
+strong_alias (__debug_posix_memalign, posix_memalign)
+
+static void *
+__debug_calloc (size_t nmemb, size_t size)
+{
+  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)
+	memset (mem, 0, bytes);
+
+      return mem;
+    }
+
+  return __libc_calloc (nmemb, size);
+}
+strong_alias (__debug_calloc, calloc)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6e8fa9e424..cf71314b2b 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -573,16 +573,6 @@ tag_at (void *ptr)
 #define HAVE_MREMAP 0
 #endif
 
-/* We may need to support __malloc_initialize_hook for backwards
-   compatibility.  */
-
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_24)
-# define HAVE_MALLOC_INIT_HOOK 1
-#else
-# define HAVE_MALLOC_INIT_HOOK 0
-#endif
-
-
 /*
   This version of malloc supports the standard SVID/XPG mallinfo
   routine that returns a struct containing usage properties and
@@ -2008,38 +1998,6 @@ static void     malloc_consolidate (mstate);
 
 /* -------------- Early definitions for debugging hooks ---------------- */
 
-/* Define and initialize the hook variables.  These weak definitions must
-   appear before any use of the variables in a function (arena.c uses one).  */
-#ifndef weak_variable
-/* In GNU libc we want the hook variables to be weak definitions to
-   avoid a problem with Emacs.  */
-# define weak_variable weak_function
-#endif
-
-/* Forward declarations.  */
-static void *malloc_hook_ini (size_t sz,
-                              const void *caller) __THROW;
-static void *realloc_hook_ini (void *ptr, size_t sz,
-                               const void *caller) __THROW;
-static void *memalign_hook_ini (size_t alignment, size_t sz,
-                                const void *caller) __THROW;
-
-#if HAVE_MALLOC_INIT_HOOK
-void (*__malloc_initialize_hook) (void);
-compat_symbol (libc, __malloc_initialize_hook,
-	       __malloc_initialize_hook, GLIBC_2_0);
-#endif
-
-void weak_variable (*__free_hook) (void *__ptr,
-                                   const void *) = NULL;
-void *weak_variable (*__malloc_hook)
-  (size_t __size, const void *) = malloc_hook_ini;
-void *weak_variable (*__realloc_hook)
-  (void *__ptr, size_t __size, const void *)
-  = realloc_hook_ini;
-void *weak_variable (*__memalign_hook)
-  (size_t __alignment, size_t __size, const void *)
-  = memalign_hook_ini;
 /* This function is called from the arena shutdown hook, to free the
    thread cache (if it exists).  */
 static void tcache_thread_shutdown (void);
@@ -3237,10 +3195,8 @@ __libc_malloc (size_t bytes)
   _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
                   "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))
-    return (*hook)(bytes, RETURN_ADDRESS (0));
+  if (__malloc_initialized < 0)
+    ptmalloc_init ();
 #if USE_TCACHE
   /* int_free also calls request2size, be careful to not pad twice.  */
   size_t tbytes;
@@ -3301,14 +3257,6 @@ __libc_free (void *mem)
   mstate ar_ptr;
   mchunkptr p;                          /* chunk corresponding to mem */
 
-  void (*hook) (void *, const void *)
-    = atomic_forced_read (__free_hook);
-  if (__builtin_expect (hook != NULL, 0))
-    {
-      (*hook)(mem, RETURN_ADDRESS (0));
-      return;
-    }
-
   if (mem == 0)                              /* free(0) has no effect */
     return;
 
@@ -3360,10 +3308,8 @@ __libc_realloc (void *oldmem, size_t bytes)
 
   void *newp;             /* chunk to return */
 
-  void *(*hook) (void *, size_t, const void *) =
-    atomic_forced_read (__realloc_hook);
-  if (__builtin_expect (hook != NULL, 0))
-    return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
+  if (__malloc_initialized < 0)
+    ptmalloc_init ();
 
 #if REALLOC_ZERO_BYTES_FREES
   if (bytes == 0 && oldmem != NULL)
@@ -3498,6 +3444,9 @@ libc_hidden_def (__libc_realloc)
 void *
 __libc_memalign (size_t alignment, size_t bytes)
 {
+  if (__malloc_initialized < 0)
+    ptmalloc_init ();
+
   void *address = RETURN_ADDRESS (0);
   return _mid_memalign (alignment, bytes, address);
 }
@@ -3508,11 +3457,6 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
   mstate ar_ptr;
   void *p;
 
-  void *(*hook) (size_t, size_t, const void *) =
-    atomic_forced_read (__memalign_hook);
-  if (__builtin_expect (hook != NULL, 0))
-    return (*hook)(alignment, bytes, address);
-
   /* If we need less alignment than we give anyway, just relay to malloc.  */
   if (alignment <= MALLOC_ALIGNMENT)
     return __libc_malloc (bytes);
@@ -3621,16 +3565,8 @@ __libc_calloc (size_t n, size_t elem_size)
 
   sz = bytes;
 
-  void *(*hook) (size_t, const void *) =
-    atomic_forced_read (__malloc_hook);
-  if (__builtin_expect (hook != NULL, 0))
-    {
-      mem = (*hook)(sz, RETURN_ADDRESS (0));
-      if (mem == 0)
-        return 0;
-
-      return memset (mem, 0, sz);
-    }
+  if (__malloc_initialized < 0)
+    ptmalloc_init ();
 
   MAYBE_INIT_TCACHE ();
 
@@ -5659,6 +5595,9 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
 {
   void *mem;
 
+  if (__malloc_initialized < 0)
+    ptmalloc_init ();
+
   /* Test whether the SIZE argument is valid.  It must be a power of
      two multiple of sizeof (void *).  */
   if (alignment % sizeof (void *) != 0
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index d2efcfb742..1e68cedbf5 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -26,6 +26,7 @@
 # include <stdio.h>
 # include <libintl.h>
 # include <errno.h>
+# include <malloc-internal.h>
 #endif
 
 /* Old hook values.  */
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index 6c2c58b706..fb58413d39 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -22,6 +22,7 @@
 # define _MALLOC_INTERNAL
 # include <malloc.h>
 # include <mcheck.h>
+# include <malloc-internal.h>
 # include <libc-lock.h>
 #endif
 
diff --git a/malloc/tst-compathooks-off.c b/malloc/tst-compathooks-off.c
new file mode 100644
index 0000000000..7b3722d8b3
--- /dev/null
+++ b/malloc/tst-compathooks-off.c
@@ -0,0 +1,145 @@
+/* Minimal tests to verify libc_malloc_debug.so functionality.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <shlib-compat.h>
+#include <libc-diag.h>
+
+#include <support/check.h>
+#include <support/support.h>
+
+extern void (*volatile __free_hook) (void *, const void *);
+extern void *(*volatile __malloc_hook)(size_t, const void *);
+extern void *(*volatile __realloc_hook)(void *, size_t, const void *);
+extern void *(*volatile __memalign_hook)(size_t, size_t, const void *);
+
+int hook_count, call_count;
+
+DIAG_PUSH_NEEDS_COMMENT;
+DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
+
+void
+free_called (void *mem, const void *address)
+{
+  hook_count++;
+  __free_hook = NULL;
+  free (mem);
+  __free_hook = free_called;
+}
+
+void *
+malloc_called (size_t bytes, const void *address)
+{
+  hook_count++;
+  __malloc_hook = NULL;
+  void *mem = malloc (bytes);
+  __malloc_hook = malloc_called;
+  return mem;
+}
+
+void *
+realloc_called (void *oldptr, size_t bytes, const void *address)
+{
+  hook_count++;
+  __realloc_hook = NULL;
+  void *mem = realloc (oldptr, bytes);
+  __realloc_hook = realloc_called;
+  return mem;
+}
+
+void *
+calloc_called (size_t n, size_t size, const void *address)
+{
+  hook_count++;
+  __malloc_hook = NULL;
+  void *mem = calloc (n, size);
+  __malloc_hook = malloc_called;
+  return mem;
+}
+
+void *
+memalign_called (size_t align, size_t size, const void *address)
+{
+  hook_count++;
+  __memalign_hook = NULL;
+  void *mem = memalign (align, size);
+  __memalign_hook = memalign_called;
+  return mem;
+}
+
+static void initialize_hooks (void)
+{
+  __free_hook = free_called;
+  __malloc_hook = malloc_called;
+  __realloc_hook = realloc_called;
+  __memalign_hook = memalign_called;
+}
+void (*__malloc_initialize_hook) (void) = initialize_hooks;
+compat_symbol_reference (libc, __malloc_initialize_hook,
+			 __malloc_initialize_hook, GLIBC_2_0);
+compat_symbol_reference (libc, __free_hook,
+			 __free_hook, GLIBC_2_0);
+compat_symbol_reference (libc, __malloc_hook,
+			 __malloc_hook, GLIBC_2_0);
+compat_symbol_reference (libc, __realloc_hook,
+			 __realloc_hook, GLIBC_2_0);
+compat_symbol_reference (libc, __memalign_hook,
+			 __memalign_hook, GLIBC_2_0);
+
+DIAG_POP_NEEDS_COMMENT;
+
+static int
+do_test (void)
+{
+  void *p;
+  p = malloc (0);
+  TEST_VERIFY_EXIT (p != NULL);
+  call_count++;
+
+  p = realloc (p, 0);
+  TEST_VERIFY_EXIT (p == NULL);
+  call_count++;
+
+  p = calloc (512, 1);
+  TEST_VERIFY_EXIT (p != NULL);
+  call_count++;
+
+  free (p);
+  call_count++;
+
+  p = memalign (0x100, 0x100);
+  TEST_VERIFY_EXIT (p != NULL);
+  call_count++;
+
+  free (p);
+  call_count++;
+
+  printf ("call_count: %d, hook_count: %d\n", call_count, hook_count);
+
+#ifdef HOOKS_ENABLED
+  TEST_VERIFY_EXIT (call_count == hook_count);
+#else
+  TEST_VERIFY_EXIT (hook_count == 0);
+#endif
+
+  exit (0);
+}
+
+#include <support/test-driver.c>
diff --git a/malloc/tst-compathooks-on.c b/malloc/tst-compathooks-on.c
new file mode 100644
index 0000000000..4da183687a
--- /dev/null
+++ b/malloc/tst-compathooks-on.c
@@ -0,0 +1,2 @@
+#define HOOKS_ENABLED 1
+#include "tst-compathooks-off.c"
diff --git a/malloc/tst-malloc-usable-static-tunables.c b/malloc/tst-malloc-usable-static-tunables.c
deleted file mode 100644
index 8907db01a5..0000000000
--- a/malloc/tst-malloc-usable-static-tunables.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <malloc/tst-malloc-usable.c>
diff --git a/malloc/tst-malloc-usable-static.c b/malloc/tst-malloc-usable-static.c
deleted file mode 100644
index 8907db01a5..0000000000
--- a/malloc/tst-malloc-usable-static.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <malloc/tst-malloc-usable.c>
diff --git a/malloc/tst-mtrace.sh b/malloc/tst-mtrace.sh
index 9295683aff..a830204d5e 100755
--- a/malloc/tst-mtrace.sh
+++ b/malloc/tst-mtrace.sh
@@ -30,6 +30,7 @@ trap "rm -f ${common_objpfx}malloc/tst-mtrace.leak; exit 1" 1 2 15
 ${test_program_prefix_before_env} \
 ${run_program_env} \
 MALLOC_TRACE=${common_objpfx}malloc/tst-mtrace.leak \
+LD_PRELOAD=${common_objpfx}malloc/libc_malloc_debug.so \
 ${test_program_prefix_after_env} \
   ${common_objpfx}malloc/tst-mtrace || status=1
 
diff --git a/manual/memory.texi b/manual/memory.texi
index 31ee36be8c..93305f289b 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1256,8 +1256,9 @@ environment variable @env{MALLOC_ARENA_MAX} to the desired value.
 @cindex consistency checking, of heap
 
 You can ask @code{malloc} to check the consistency of dynamic memory by
-using the @code{mcheck} function.  This function is a GNU extension,
-declared in @file{mcheck.h}.
+using the @code{mcheck} function and preloading the malloc debug library
+@file{libc_malloc_debug.so} using the @var{LD_PRELOAD} environment variable.
+This function is a GNU extension, declared in @file{mcheck.h}.
 @pindex mcheck.h
 
 @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
@@ -1368,7 +1369,10 @@ non-zero value less than 4, a special (less efficient) implementation is
 used which is designed to be tolerant against simple errors, such as
 double calls of @code{free} with the same argument, or overruns of a
 single byte (off-by-one bugs).  Not all such errors can be protected
-against, however, and memory leaks can result.
+against, however, and memory leaks can result.  Like in the case of
+@code{mcheck}, one would need to preload the @file{libc_malloc_debug.so}
+library to enable @code{MALLOC_CHECK_} functionality.  Without this
+preloaded library, setting @code{MALLOC_CHECK_} will have no effect.
 
 Any detected heap corruption results in immediate termination of the
 process.
@@ -1747,6 +1751,12 @@ penalties for the program if the debugging mode is not enabled.
 @c  fprintf dup (on newly-created stream) @aculock
 @c  __cxa_atexit (once) dup @asulock @aculock @acsmem
 @c  free dup @ascuheap @acsmem
+The @code{mtrace} function provides a way to trace memory allocation
+events in the program that calls it.  It is disabled by default in the
+library and can be enabled by preloading the debugging library
+@file{libc_malloc_debug.so} using the @code{LD_PRELOAD} environment
+variable.
+
 When the @code{mtrace} function is called it looks for an environment
 variable named @code{MALLOC_TRACE}.  This variable is supposed to
 contain a valid file name.  The user must have write access.  If the
diff --git a/manual/tunables.texi b/manual/tunables.texi
index ebdb562e36..e264e9150c 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -113,7 +113,9 @@ following tunables in the @code{malloc} namespace:
 
 @deftp Tunable glibc.malloc.check
 This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
-identical in features.
+identical in features. This tunable has no effect by default and needs the
+debug library @file{libc_malloc_debug.so} to be preloaded using the
+@code{LD_PRELOAD} environment variable.
 
 Setting this tunable to a non-zero value less than 4 enables a special (less
 efficient) memory allocator for the @code{malloc} family of functions that is
diff --git a/misc/Makefile b/misc/Makefile
index ae03e26f1b..b144a3df6c 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -152,13 +152,15 @@ $(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib)
 
 $(objpfx)tst-tsearch: $(libm)
 
-tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace
+tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace \
+		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 tst-error1-ARGS = $(objpfx)tst-error1.out
 $(objpfx)tst-error1-mem.out: $(objpfx)tst-error1.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-error1.mtrace > $@; \
 	$(evaluate-test)
 
-tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
+tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace \
+			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
 	$(evaluate-test)
diff --git a/nptl/Makefile b/nptl/Makefile
index 9b94bfcd31..ff4d590f11 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -494,7 +494,8 @@ CFLAGS-tst-initializers1-gnu11.c += $(CFLAGS-tst-initializers1-<)
 tst-cancel7-ARGS = --command "exec $(host-test-program-cmd)"
 tst-cancelx7-ARGS = $(tst-cancel7-ARGS)
 
-tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace
+tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace \
+		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-stack3-mem.out: $(objpfx)tst-stack3.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@; \
 	$(evaluate-test)
diff --git a/posix/Makefile b/posix/Makefile
index d82e43eaad..b895638865 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -313,43 +313,50 @@ annexc-CFLAGS = -O
 $(objpfx)annexc: annexc.c
 	$(native-compile)
 
-tst-fnmatch-ENV += MALLOC_TRACE=$(objpfx)tst-fnmatch.mtrace
+tst-fnmatch-ENV += MALLOC_TRACE=$(objpfx)tst-fnmatch.mtrace \
+		   LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)tst-fnmatch-mem.out: $(objpfx)tst-fnmatch.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-fnmatch.mtrace > $@; \
 	$(evaluate-test)
 
-bug-regex2-ENV = MALLOC_TRACE=$(objpfx)bug-regex2.mtrace
+bug-regex2-ENV = MALLOC_TRACE=$(objpfx)bug-regex2.mtrace \
+		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-regex2-mem.out: $(objpfx)bug-regex2.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex2.mtrace > $@; \
 	$(evaluate-test)
 
-bug-regex14-ENV = MALLOC_TRACE=$(objpfx)bug-regex14.mtrace
+bug-regex14-ENV = MALLOC_TRACE=$(objpfx)bug-regex14.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-regex14-mem.out: $(objpfx)bug-regex14.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex14.mtrace > $@; \
 	$(evaluate-test)
 
-bug-regex21-ENV = MALLOC_TRACE=$(objpfx)bug-regex21.mtrace
+bug-regex21-ENV = MALLOC_TRACE=$(objpfx)bug-regex21.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-regex21-mem.out: $(objpfx)bug-regex21.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex21.mtrace > $@; \
 	$(evaluate-test)
 
-bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace
+bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-regex31-mem.out: $(objpfx)bug-regex31.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@; \
 	$(evaluate-test)
 
-bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
+bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
 	$(evaluate-test)
 
-tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
+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 > $@; \
@@ -358,18 +365,22 @@ $(objpfx)tst-vfork3-mem.out: $(objpfx)tst-vfork3.out
 # tst-rxspencer.mtrace is not generated, only
 # tst-rxspencer-no-utf8.mtrace, since otherwise the file has almost
 # 100M and takes very long time to process.
-tst-rxspencer-no-utf8-ENV += MALLOC_TRACE=$(objpfx)tst-rxspencer-no-utf8.mtrace
+tst-rxspencer-no-utf8-ENV += \
+  MALLOC_TRACE=$(objpfx)tst-rxspencer-no-utf8.mtrace \
+  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-rxspencer-no-utf8-mem.out: $(objpfx)tst-rxspencer-no-utf8.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-rxspencer-no-utf8.mtrace \
 				      > $@; \
 	$(evaluate-test)
 
-tst-pcre-ENV = MALLOC_TRACE=$(objpfx)tst-pcre.mtrace
+tst-pcre-ENV = MALLOC_TRACE=$(objpfx)tst-pcre.mtrace \
+	       LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-pcre-mem.out: $(objpfx)tst-pcre.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-pcre.mtrace > $@; \
 	$(evaluate-test)
 
-tst-boost-ENV = MALLOC_TRACE=$(objpfx)tst-boost.mtrace
+tst-boost-ENV = MALLOC_TRACE=$(objpfx)tst-boost.mtrace \
+		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-boost-mem.out: $(objpfx)tst-boost.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-boost.mtrace > $@; \
 	$(evaluate-test)
@@ -384,15 +395,18 @@ $(objpfx)bug-ga2-mem.out: $(objpfx)bug-ga2.out
 	&& $(common-objpfx)malloc/mtrace $(objpfx)bug-ga2.mtrace; } > $@; \
 	$(evaluate-test)
 
-bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace
+bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace \
+	      LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
-bug-glob2-ENV = MALLOC_TRACE=$(objpfx)bug-glob2.mtrace
+bug-glob2-ENV = MALLOC_TRACE=$(objpfx)bug-glob2.mtrace \
+		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)bug-glob2-mem.out: $(objpfx)bug-glob2.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
 	$(evaluate-test)
 
-tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace
+tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace \
+		     LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \
diff --git a/resolv/Makefile b/resolv/Makefile
index 1d3565d478..09b2f129eb 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -156,19 +156,22 @@ $(objpfx)tst-res_hconf_reorder: $(shared-thread-library)
 tst-res_hconf_reorder-ENV = RESOLV_REORDER=on
 
 $(objpfx)tst-leaks: $(objpfx)libresolv.so
-tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
+tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
+		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@; \
 	$(evaluate-test)
 
-tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
+tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace \
+		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
 	{ test -r $(objpfx)tst-leaks2.mtrace \
 	|| ( echo "tst-leaks2.mtrace does not exist"; exit 77; ) \
 	&& $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace; } > $@; \
 	$(evaluate-test)
 
-tst-resolv-res_ninit-ENV = MALLOC_TRACE=$(objpfx)tst-resolv-res_ninit.mtrace
+tst-resolv-res_ninit-ENV = MALLOC_TRACE=$(objpfx)tst-resolv-res_ninit.mtrace \
+			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)mtrace-tst-resolv-res_ninit.out: $(objpfx)tst-resolv-res_ninit.out
 	$(common-objpfx)malloc/mtrace \
 	  $(objpfx)tst-resolv-res_ninit.mtrace > $@; \
diff --git a/shlib-versions b/shlib-versions
index edabba08eb..df6603e699 100644
--- a/shlib-versions
+++ b/shlib-versions
@@ -73,3 +73,6 @@ libgcc_s=1
 
 # The vector math library
 libmvec=1
+
+# The malloc debug library
+libc_malloc_debug=0
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index f87796a8ce..803f16dae0 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -110,15 +110,20 @@ $(objpfx)tst-swprintf.out: $(gen-locales)
 $(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales)
 endif
 
-tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace
+tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \
+			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 tst-vfprintf-width-prec-ENV = \
-  MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace
+  MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace \
+  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 tst-printf-bz25691-ENV = \
-  MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace
+  MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace \
+  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 tst-printf-fp-free-ENV = \
-  MALLOC_TRACE=$(objpfx)tst-printf-fp-free.mtrace
+  MALLOC_TRACE=$(objpfx)tst-printf-fp-free.mtrace \
+  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 tst-printf-fp-leak-ENV = \
-  MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace
+  MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \
+  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 
 $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
 	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
diff --git a/sysdeps/generic/libc_malloc_debug.abilist b/sysdeps/generic/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
index 46bd7b4600..17bb643c18 100644
--- a/sysdeps/mach/hurd/Makefile
+++ b/sysdeps/mach/hurd/Makefile
@@ -222,5 +222,6 @@ CFLAGS-ypclnt.c += -DUSE_BINDINGDIR=1
 endif
 
 LDLIBS-pthread.so += $(objdir)/hurd/libhurduser.so
+LDLIBS-c_malloc_debug.so += $(link-rpcuserlibs)
 
 endif	# in-Makerules
diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..393ef2acd7
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2.6 calloc F
+GLIBC_2.2.6 free F
+GLIBC_2.2.6 malloc F
+GLIBC_2.2.6 memalign F
+GLIBC_2.2.6 posix_memalign F
+GLIBC_2.2.6 pvalloc F
+GLIBC_2.2.6 realloc F
+GLIBC_2.2.6 valloc F
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
index 9b862b93c4..42f9fc5072 100644
--- a/sysdeps/pthread/Makefile
+++ b/sysdeps/pthread/Makefile
@@ -211,7 +211,8 @@ tst-umask1-ARGS = $(objpfx)tst-umask1.temp
 
 $(objpfx)tst-atfork2: $(shared-thread-library)
 LDFLAGS-tst-atfork2 = -rdynamic
-tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
+tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace \
+		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
 $(objpfx)tst-atfork2mod.so: $(shared-thread-library)
 
 ifeq ($(build-shared),yes)
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..2b183c90d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.17 aligned_alloc F
+GLIBC_2.17 calloc F
+GLIBC_2.17 free F
+GLIBC_2.17 malloc F
+GLIBC_2.17 memalign F
+GLIBC_2.17 posix_memalign F
+GLIBC_2.17 pvalloc F
+GLIBC_2.17 realloc F
+GLIBC_2.17 valloc F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..3ec745c9ac
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.32 aligned_alloc F
+GLIBC_2.32 calloc F
+GLIBC_2.32 free F
+GLIBC_2.32 malloc F
+GLIBC_2.32 memalign F
+GLIBC_2.32 posix_memalign F
+GLIBC_2.32 pvalloc F
+GLIBC_2.32 realloc F
+GLIBC_2.32 valloc 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
new file mode 100644
index 0000000000..f7938d075f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 calloc F
+GLIBC_2.4 free F
+GLIBC_2.4 malloc F
+GLIBC_2.4 memalign F
+GLIBC_2.4 posix_memalign F
+GLIBC_2.4 pvalloc F
+GLIBC_2.4 realloc F
+GLIBC_2.4 valloc 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
new file mode 100644
index 0000000000..f7938d075f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 calloc F
+GLIBC_2.4 free F
+GLIBC_2.4 malloc F
+GLIBC_2.4 memalign F
+GLIBC_2.4 posix_memalign F
+GLIBC_2.4 pvalloc F
+GLIBC_2.4 realloc F
+GLIBC_2.4 valloc F
diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..54da2c3e38
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.29 aligned_alloc F
+GLIBC_2.29 calloc F
+GLIBC_2.29 free F
+GLIBC_2.29 malloc F
+GLIBC_2.29 memalign F
+GLIBC_2.29 posix_memalign F
+GLIBC_2.29 pvalloc F
+GLIBC_2.29 realloc F
+GLIBC_2.29 valloc F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc F
diff --git a/sysdeps/unix/sysv/linux/hppa/shlib-versions b/sysdeps/unix/sysv/linux/hppa/shlib-versions
index 3a2d496220..7818a32cc4 100644
--- a/sysdeps/unix/sysv/linux/hppa/shlib-versions
+++ b/sysdeps/unix/sysv/linux/hppa/shlib-versions
@@ -7,3 +7,5 @@ ld=ld.so.1		GLIBC_2.2
 libBrokenLocale=1	GLIBC_2.2
 
 libpthread=0		GLIBC_2.2
+
+libc_malloc_debug=0	GLIBC_2.2
diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc F
diff --git a/sysdeps/unix/sysv/linux/ia64/shlib-versions b/sysdeps/unix/sysv/linux/ia64/shlib-versions
index 37374c0e20..f57e5bae5e 100644
--- a/sysdeps/unix/sysv/linux/ia64/shlib-versions
+++ b/sysdeps/unix/sysv/linux/ia64/shlib-versions
@@ -6,3 +6,5 @@ ld=ld-linux-ia64.so.2	GLIBC_2.2
 libBrokenLocale=1	GLIBC_2.2
 
 libpthread=0		GLIBC_2.2
+
+libc_malloc_debug=0	GLIBC_2.2
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..f7938d075f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.4 calloc F
+GLIBC_2.4 free F
+GLIBC_2.4 malloc F
+GLIBC_2.4 memalign F
+GLIBC_2.4 posix_memalign F
+GLIBC_2.4 pvalloc F
+GLIBC_2.4 realloc F
+GLIBC_2.4 valloc 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..d02da8ef66
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.18 aligned_alloc F
+GLIBC_2.18 calloc F
+GLIBC_2.18 free F
+GLIBC_2.18 malloc F
+GLIBC_2.18 memalign F
+GLIBC_2.18 posix_memalign F
+GLIBC_2.18 pvalloc F
+GLIBC_2.18 realloc F
+GLIBC_2.18 valloc 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
new file mode 100644
index 0000000000..d02da8ef66
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.18 aligned_alloc F
+GLIBC_2.18 calloc F
+GLIBC_2.18 free F
+GLIBC_2.18 malloc F
+GLIBC_2.18 memalign F
+GLIBC_2.18 posix_memalign F
+GLIBC_2.18 pvalloc F
+GLIBC_2.18 realloc F
+GLIBC_2.18 valloc 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 posix_memalign F
diff --git a/sysdeps/unix/sysv/linux/mips/shlib-versions b/sysdeps/unix/sysv/linux/mips/shlib-versions
index ecfe1845f4..c57674deec 100644
--- a/sysdeps/unix/sysv/linux/mips/shlib-versions
+++ b/sysdeps/unix/sysv/linux/mips/shlib-versions
@@ -23,3 +23,5 @@ libnsl=1		GLIBC_2.0 GLIBC_2.2
 librt=1			GLIBC_2.0 GLIBC_2.2
 
 libpthread=0		GLIBC_2.0 GLIBC_2.2
+
+libc_malloc_debug=0	GLIBC_2.0 GLIBC_2.2
diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..658c965b08
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.21 aligned_alloc F
+GLIBC_2.21 calloc F
+GLIBC_2.21 free F
+GLIBC_2.21 malloc F
+GLIBC_2.21 memalign F
+GLIBC_2.21 posix_memalign F
+GLIBC_2.21 pvalloc F
+GLIBC_2.21 realloc F
+GLIBC_2.21 valloc 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..921079580c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.3 calloc F
+GLIBC_2.3 free F
+GLIBC_2.3 malloc F
+GLIBC_2.3 memalign F
+GLIBC_2.3 posix_memalign F
+GLIBC_2.3 pvalloc F
+GLIBC_2.3 realloc F
+GLIBC_2.3 valloc 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
new file mode 100644
index 0000000000..2b183c90d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.17 aligned_alloc F
+GLIBC_2.17 calloc F
+GLIBC_2.17 free F
+GLIBC_2.17 malloc F
+GLIBC_2.17 memalign F
+GLIBC_2.17 posix_memalign F
+GLIBC_2.17 pvalloc F
+GLIBC_2.17 realloc F
+GLIBC_2.17 valloc 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
new file mode 100644
index 0000000000..05c8ba8c9f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.33 aligned_alloc F
+GLIBC_2.33 calloc F
+GLIBC_2.33 free F
+GLIBC_2.33 malloc F
+GLIBC_2.33 memalign F
+GLIBC_2.33 posix_memalign F
+GLIBC_2.33 pvalloc F
+GLIBC_2.33 realloc F
+GLIBC_2.33 valloc 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
new file mode 100644
index 0000000000..20531a7372
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.27 aligned_alloc F
+GLIBC_2.27 calloc F
+GLIBC_2.27 free F
+GLIBC_2.27 malloc F
+GLIBC_2.27 memalign F
+GLIBC_2.27 posix_memalign F
+GLIBC_2.27 pvalloc F
+GLIBC_2.27 realloc F
+GLIBC_2.27 valloc 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
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc 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
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc 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
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc F
diff --git a/sysdeps/unix/sysv/linux/sh/shlib-versions b/sysdeps/unix/sysv/linux/sh/shlib-versions
index 9333bbd7a3..3124264300 100644
--- a/sysdeps/unix/sysv/linux/sh/shlib-versions
+++ b/sysdeps/unix/sysv/linux/sh/shlib-versions
@@ -3,3 +3,4 @@ libc=6			GLIBC_2.2
 ld=ld-linux.so.2	GLIBC_2.2
 libBrokenLocale=1	GLIBC_2.2
 libpthread=0		GLIBC_2.2
+libc_malloc_debug=0	GLIBC_2.2
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
new file mode 100644
index 0000000000..7621d1266e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.0 calloc F
+GLIBC_2.0 free F
+GLIBC_2.0 malloc F
+GLIBC_2.0 memalign 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 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
new file mode 100644
index 0000000000..3ea834d9a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2 calloc F
+GLIBC_2.2 free F
+GLIBC_2.2 malloc F
+GLIBC_2.2 memalign F
+GLIBC_2.2 posix_memalign F
+GLIBC_2.2 pvalloc F
+GLIBC_2.2 realloc F
+GLIBC_2.2 valloc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions b/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
index 9333bbd7a3..3124264300 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
@@ -3,3 +3,4 @@ libc=6			GLIBC_2.2
 ld=ld-linux.so.2	GLIBC_2.2
 libBrokenLocale=1	GLIBC_2.2
 libpthread=0		GLIBC_2.2
+libc_malloc_debug=0	GLIBC_2.2
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
new file mode 100644
index 0000000000..723c5f48f0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.2.5 calloc F
+GLIBC_2.2.5 free F
+GLIBC_2.2.5 malloc F
+GLIBC_2.2.5 memalign F
+GLIBC_2.2.5 posix_memalign F
+GLIBC_2.2.5 pvalloc F
+GLIBC_2.2.5 realloc F
+GLIBC_2.2.5 valloc 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
new file mode 100644
index 0000000000..c506f45101
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
@@ -0,0 +1,9 @@
+GLIBC_2.16 aligned_alloc F
+GLIBC_2.16 calloc F
+GLIBC_2.16 free F
+GLIBC_2.16 malloc F
+GLIBC_2.16 memalign F
+GLIBC_2.16 posix_memalign F
+GLIBC_2.16 pvalloc F
+GLIBC_2.16 realloc F
+GLIBC_2.16 valloc F
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 05/10] mcheck: Wean away from malloc hooks
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (3 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 04/10] Move malloc hooks into a compat DSO Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-13 15:47   ` H.J. Lu via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 06/10] Simplify __malloc_initialized Siddhesh Poyarekar via Libc-alpha
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Split the mcheck implementation into the debugging hooks and API so
that the API can be replicated in libc and libc_malloc_debug.so.  The
libc APIs always result in failure.

The mcheck implementation has also been moved entirely into
libc_malloc_debug.so and with it, all of the hook initialization code
can now be moved into the debug library.  Now the initialization can
be done independently of libc internals.

With this patch, libc_malloc_debug.so can no longer be used with older
libcs, which is not its goal anyway.  tst-vfork3 breaks due to this
since it spawns shell scripts, which in turn execute using the system
glibc.  Move the test to tests-container so that only the built glibc
is used.

This move also fixes bugs in the mcheck version of memalign and
realloc, thus allowing removal of the tests from tests-mcheck
exclusion list.
---
 include/mcheck.h                              |   4 -
 malloc/Makefile                               |   3 -
 malloc/Versions                               |   9 +
 malloc/hooks.c                                |  61 +--
 malloc/malloc-debug.c                         | 173 +++++++-
 malloc/mcheck-impl.c                          | 406 ++++++++++++++++++
 malloc/mcheck.c                               | 398 +----------------
 posix/Makefile                                |   8 +-
 .../mach/hurd/i386/libc_malloc_debug.abilist  |   8 +
 .../linux/aarch64/libc_malloc_debug.abilist   |   8 +
 .../linux/alpha/libc_malloc_debug.abilist     |   8 +
 .../sysv/linux/arc/libc_malloc_debug.abilist  |   8 +
 .../linux/arm/be/libc_malloc_debug.abilist    |   8 +
 .../linux/arm/le/libc_malloc_debug.abilist    |   8 +
 .../sysv/linux/csky/libc_malloc_debug.abilist |   8 +
 .../sysv/linux/hppa/libc_malloc_debug.abilist |   8 +
 .../sysv/linux/i386/libc_malloc_debug.abilist |   8 +
 .../sysv/linux/ia64/libc_malloc_debug.abilist |   8 +
 .../m68k/coldfire/libc_malloc_debug.abilist   |   8 +
 .../m68k/m680x0/libc_malloc_debug.abilist     |   8 +
 .../microblaze/be/libc_malloc_debug.abilist   |   8 +
 .../microblaze/le/libc_malloc_debug.abilist   |   8 +
 .../mips/mips32/fpu/libc_malloc_debug.abilist |   8 +
 .../mips32/nofpu/libc_malloc_debug.abilist    |   8 +
 .../mips/mips64/n32/libc_malloc_debug.abilist |   8 +
 .../mips/mips64/n64/libc_malloc_debug.abilist |   8 +
 .../linux/nios2/libc_malloc_debug.abilist     |   8 +
 .../powerpc32/fpu/libc_malloc_debug.abilist   |   8 +
 .../powerpc32/nofpu/libc_malloc_debug.abilist |   8 +
 .../powerpc64/be/libc_malloc_debug.abilist    |   8 +
 .../powerpc64/le/libc_malloc_debug.abilist    |   8 +
 .../riscv/rv32/libc_malloc_debug.abilist      |   8 +
 .../riscv/rv64/libc_malloc_debug.abilist      |   8 +
 .../s390/s390-32/libc_malloc_debug.abilist    |   8 +
 .../s390/s390-64/libc_malloc_debug.abilist    |   8 +
 .../linux/sh/be/libc_malloc_debug.abilist     |   8 +
 .../linux/sh/le/libc_malloc_debug.abilist     |   8 +
 .../sparc/sparc32/libc_malloc_debug.abilist   |   8 +
 .../sparc/sparc64/libc_malloc_debug.abilist   |   8 +
 .../linux/x86_64/64/libc_malloc_debug.abilist |   8 +
 .../x86_64/x32/libc_malloc_debug.abilist      |   8 +
 41 files changed, 861 insertions(+), 465 deletions(-)
 create mode 100644 malloc/mcheck-impl.c

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 7ea45d2358..c0dbe04b57 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
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 06/10] Simplify __malloc_initialized
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (4 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 05/10] mcheck: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 07/10] mtrace: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Now that mcheck no longer needs to check __malloc_initialized (and no
other third party hook can since the symbol is not exported), make the
variable boolean and static so that it is used strictly within malloc.
---
 include/malloc.h |  6 ------
 malloc/arena.c   | 12 ++++++------
 malloc/malloc.c  | 24 ++++++++++++------------
 3 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/include/malloc.h b/include/malloc.h
index b77761f74d..f9c9610548 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -5,12 +5,6 @@
 # ifndef _ISOMAC
 #  include <rtld-malloc.h>
 
-/* In the GNU libc we rename the global variable
-   `__malloc_initialized' to `__libc_malloc_initialized'.  */
-#define __malloc_initialized __libc_malloc_initialized
-/* Nonzero if the malloc is already initialized.  */
-extern int __malloc_initialized attribute_hidden;
-
 struct malloc_state;
 typedef struct malloc_state *mstate;
 
diff --git a/malloc/arena.c b/malloc/arena.c
index 9111b49589..840426f9fb 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -97,7 +97,7 @@ static mstate free_list;
 __libc_lock_define_initialized (static, list_lock);
 
 /* Already initialized? */
-int __malloc_initialized = -1;
+static bool __malloc_initialized = false;
 
 /**************************************************************************/
 
@@ -143,7 +143,7 @@ int __malloc_initialized = -1;
 void
 __malloc_fork_lock_parent (void)
 {
-  if (__malloc_initialized < 1)
+  if (!__malloc_initialized)
     return;
 
   /* We do not acquire free_list_lock here because we completely
@@ -163,7 +163,7 @@ __malloc_fork_lock_parent (void)
 void
 __malloc_fork_unlock_parent (void)
 {
-  if (__malloc_initialized < 1)
+  if (!__malloc_initialized)
     return;
 
   for (mstate ar_ptr = &main_arena;; )
@@ -179,7 +179,7 @@ __malloc_fork_unlock_parent (void)
 void
 __malloc_fork_unlock_child (void)
 {
-  if (__malloc_initialized < 1)
+  if (!__malloc_initialized)
     return;
 
   /* Push all arenas to the free list, except thread_arena, which is
@@ -286,10 +286,10 @@ static void tcache_key_initialize (void);
 static void
 ptmalloc_init (void)
 {
-  if (__malloc_initialized >= 0)
+  if (__malloc_initialized)
     return;
 
-  __malloc_initialized = 0;
+  __malloc_initialized = true;
 
 #if USE_TCACHE
   tcache_key_initialize ();
diff --git a/malloc/malloc.c b/malloc/malloc.c
index cf71314b2b..ed0316e690 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3195,7 +3195,7 @@ __libc_malloc (size_t bytes)
   _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
                   "PTRDIFF_MAX is not more than half of SIZE_MAX");
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 #if USE_TCACHE
   /* int_free also calls request2size, be careful to not pad twice.  */
@@ -3308,7 +3308,7 @@ __libc_realloc (void *oldmem, size_t bytes)
 
   void *newp;             /* chunk to return */
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
 #if REALLOC_ZERO_BYTES_FREES
@@ -3444,7 +3444,7 @@ libc_hidden_def (__libc_realloc)
 void *
 __libc_memalign (size_t alignment, size_t bytes)
 {
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   void *address = RETURN_ADDRESS (0);
@@ -3515,7 +3515,7 @@ libc_hidden_def (__libc_memalign)
 void *
 __libc_valloc (size_t bytes)
 {
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   void *address = RETURN_ADDRESS (0);
@@ -3526,7 +3526,7 @@ __libc_valloc (size_t bytes)
 void *
 __libc_pvalloc (size_t bytes)
 {
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   void *address = RETURN_ADDRESS (0);
@@ -3565,7 +3565,7 @@ __libc_calloc (size_t n, size_t elem_size)
 
   sz = bytes;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   MAYBE_INIT_TCACHE ();
@@ -5022,7 +5022,7 @@ __malloc_trim (size_t s)
 {
   int result = 0;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   mstate ar_ptr = &main_arena;
@@ -5157,7 +5157,7 @@ __libc_mallinfo2 (void)
   struct mallinfo2 m;
   mstate ar_ptr;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   memset (&m, 0, sizeof (m));
@@ -5208,7 +5208,7 @@ __malloc_stats (void)
   mstate ar_ptr;
   unsigned int in_use_b = mp_.mmapped_mem, system_b = in_use_b;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
   _IO_flockfile (stderr);
   int old_flags2 = stderr->_flags2;
@@ -5377,7 +5377,7 @@ __libc_mallopt (int param_number, int value)
   mstate av = &main_arena;
   int res = 1;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
   __libc_lock_lock (av->mutex);
 
@@ -5595,7 +5595,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
 {
   void *mem;
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   /* Test whether the SIZE argument is valid.  It must be a power of
@@ -5639,7 +5639,7 @@ __malloc_info (int options, FILE *fp)
 
 
 
-  if (__malloc_initialized < 0)
+  if (!__malloc_initialized)
     ptmalloc_init ();
 
   fputs ("<malloc version=\"1\">\n", fp);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 07/10] mtrace: Wean away from malloc hooks
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (5 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 06/10] Simplify __malloc_initialized Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 08/10] glibc.malloc.check: " Siddhesh Poyarekar via Libc-alpha
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Wean mtrace away from the malloc hooks and move them into the debug
DSO.  Split the API away from the implementation so that we can add
the API to libc.so as well as libc_malloc_debug.so, with the libc
implementations being empty.

Update localplt data since memalign no longer has any callers after
this change.
---
 malloc/Versions                               |   2 +
 malloc/malloc-debug.c                         |  13 +
 malloc/mtrace-impl.c                          | 226 +++++++++++++
 malloc/mtrace.c                               | 314 +-----------------
 sysdeps/generic/localplt.data                 |   1 -
 .../mach/hurd/i386/libc_malloc_debug.abilist  |   2 +
 sysdeps/mach/hurd/i386/localplt.data          |   1 -
 .../linux/aarch64/libc_malloc_debug.abilist   |   2 +
 sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
 .../linux/alpha/libc_malloc_debug.abilist     |   2 +
 sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
 .../sysv/linux/arc/libc_malloc_debug.abilist  |   2 +
 sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
 .../linux/arm/be/libc_malloc_debug.abilist    |   2 +
 .../linux/arm/le/libc_malloc_debug.abilist    |   2 +
 sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
 .../sysv/linux/csky/libc_malloc_debug.abilist |   2 +
 sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
 .../sysv/linux/hppa/libc_malloc_debug.abilist |   2 +
 sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
 .../sysv/linux/i386/libc_malloc_debug.abilist |   2 +
 sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
 .../sysv/linux/ia64/libc_malloc_debug.abilist |   2 +
 sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
 .../m68k/coldfire/libc_malloc_debug.abilist   |   2 +
 .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
 .../m68k/m680x0/libc_malloc_debug.abilist     |   2 +
 .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
 .../microblaze/be/libc_malloc_debug.abilist   |   2 +
 .../microblaze/le/libc_malloc_debug.abilist   |   2 +
 .../unix/sysv/linux/microblaze/localplt.data  |   1 -
 .../mips/mips32/fpu/libc_malloc_debug.abilist |   2 +
 .../mips32/nofpu/libc_malloc_debug.abilist    |   2 +
 .../mips/mips64/n32/libc_malloc_debug.abilist |   2 +
 .../mips/mips64/n64/libc_malloc_debug.abilist |   2 +
 .../linux/nios2/libc_malloc_debug.abilist     |   2 +
 sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
 .../powerpc32/fpu/libc_malloc_debug.abilist   |   2 +
 .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
 .../powerpc32/nofpu/libc_malloc_debug.abilist |   2 +
 .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
 .../powerpc64/be/libc_malloc_debug.abilist    |   2 +
 .../powerpc64/le/libc_malloc_debug.abilist    |   2 +
 .../linux/powerpc/powerpc64/localplt.data     |   1 -
 sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
 .../riscv/rv32/libc_malloc_debug.abilist      |   2 +
 .../riscv/rv64/libc_malloc_debug.abilist      |   2 +
 sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
 .../s390/s390-32/libc_malloc_debug.abilist    |   2 +
 .../s390/s390-64/libc_malloc_debug.abilist    |   2 +
 .../linux/sh/be/libc_malloc_debug.abilist     |   2 +
 .../linux/sh/le/libc_malloc_debug.abilist     |   2 +
 sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
 .../sparc/sparc32/libc_malloc_debug.abilist   |   2 +
 .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
 .../sparc/sparc64/libc_malloc_debug.abilist   |   2 +
 .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
 .../linux/x86_64/64/libc_malloc_debug.abilist |   2 +
 .../x86_64/x32/libc_malloc_debug.abilist      |   2 +
 sysdeps/x86_64/localplt.data                  |   1 -
 60 files changed, 319 insertions(+), 325 deletions(-)
 create mode 100644 malloc/mtrace-impl.c

diff --git a/malloc/Versions b/malloc/Versions
index 6548970419..71d933de19 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -117,6 +117,8 @@ libc_malloc_debug {
 
     mcheck;
     mprobe;
+    mtrace;
+    muntrace;
   }
   GLIBC_2.2 {
     mcheck_check_all;
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
index 7c3a1e26b5..9942124e02 100644
--- a/malloc/malloc-debug.c
+++ b/malloc/malloc-debug.c
@@ -49,6 +49,7 @@ enum malloc_debug_hooks
 {
   MALLOC_NONE_HOOK = 0,
   MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck()  */
+  MALLOC_MTRACE_HOOK = 1 << 1, /* mtrace()  */
 };
 static unsigned __malloc_debugging_hooks;
 
@@ -71,6 +72,7 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
 }
 
 #include "mcheck.c"
+#include "mtrace.c"
 
 extern void (*__malloc_initialize_hook) (void);
 compat_symbol_reference (libc, __malloc_initialize_hook,
@@ -154,6 +156,8 @@ __debug_malloc (size_t bytes)
     }
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = malloc_mcheck_after (victim, orig_bytes);
+  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+    malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
 
   return victim;
 }
@@ -171,6 +175,8 @@ __debug_free (void *mem)
 
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
     mem = free_mcheck (mem);
+  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+    free_mtrace (mem, RETURN_ADDRESS (0));
 
   __libc_free (mem);
 }
@@ -195,6 +201,8 @@ __debug_realloc (void *oldmem, size_t bytes)
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
 				   oldsize);
+  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+    realloc_mtrace_after (victim, oldmem, orig_bytes, RETURN_ADDRESS (0));
 
   return victim;
 }
@@ -218,6 +226,8 @@ _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
     }
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = memalign_mcheck_after (victim, alignment, orig_bytes);
+  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+    memalign_mtrace_after (victim, orig_bytes, address);
 
   return victim;
 }
@@ -317,6 +327,9 @@ __debug_calloc (size_t nmemb, size_t size)
 	victim = malloc_mcheck_after (victim, orig_bytes);
       memset (victim, 0, orig_bytes);
     }
+  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+    malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
+
   return victim;
 }
 strong_alias (__debug_calloc, calloc)
diff --git a/malloc/mtrace-impl.c b/malloc/mtrace-impl.c
new file mode 100644
index 0000000000..0e10ab7f60
--- /dev/null
+++ b/malloc/mtrace-impl.c
@@ -0,0 +1,226 @@
+/* mtrace implementation for `malloc'.
+   Copyright (C) 1991-2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+                 Written April 2, 1991 by John Gilmore of Cygnus Support.
+                 Based on mcheck.c 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.h>
+#include <mcheck.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <libc-internal.h>
+#include <dso_handle.h>
+
+#include <kernel-features.h>
+
+#define TRACE_BUFFER_SIZE 512
+
+static FILE *mallstream;
+static const char mallenv[] = "MALLOC_TRACE";
+static char *malloc_trace_buffer;
+
+static void
+tr_where (const void *caller, Dl_info *info)
+{
+  if (caller != NULL)
+    {
+      if (info != NULL)
+        {
+          char *buf = (char *) "";
+          if (info->dli_sname != NULL)
+            {
+              size_t len = strlen (info->dli_sname);
+              buf = alloca (len + 6 + 2 * sizeof (void *));
+	      char sign;
+	      ptrdiff_t offset =
+		(ptrdiff_t) info->dli_saddr - (ptrdiff_t) caller;
+
+	      if (caller >= (const void *) info->dli_saddr)
+		{
+		  sign = '+';
+		  offset = -offset;
+		}
+	      else
+		  sign = '-';
+
+	      sprintf (buf, "(%s%c%" PRIxPTR ")", info->dli_sname, sign,
+		       offset);
+            }
+
+	  fprintf (mallstream, "@ %s%s%s[%p] ", info->dli_fname ? : "",
+		   info->dli_fname ? ":" : "",
+                   buf, caller);
+        }
+      else
+        fprintf (mallstream, "@ [%p] ", caller);
+    }
+}
+
+static Dl_info *
+lock_and_info (const void *caller, Dl_info *mem)
+{
+  if (caller == NULL)
+    return NULL;
+
+  Dl_info *res = dladdr (caller, mem) ? mem : NULL;
+
+  flockfile (mallstream);
+
+  return res;
+}
+
+static void
+free_mtrace (void *ptr, const void *caller)
+{
+  if (ptr == NULL)
+    return;
+
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+  tr_where (caller, info);
+  /* Be sure to print it first.  */
+  fprintf (mallstream, "- %p\n", ptr);
+  funlockfile (mallstream);
+}
+
+static void
+malloc_mtrace_after (void *block, size_t size, const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  /* We could be printing a NULL here; that's OK.  */
+  fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
+
+  funlockfile (mallstream);
+}
+
+static void
+realloc_mtrace_after (void *block, const void *oldptr, size_t size,
+		      const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  if (block == NULL)
+    {
+      if (size != 0)
+        /* Failed realloc.  */
+	fprintf (mallstream, "! %p %#lx\n", oldptr, (unsigned long int) size);
+      else
+        fprintf (mallstream, "- %p\n", oldptr);
+    }
+  else if (oldptr == NULL)
+    fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
+  else
+    {
+      fprintf (mallstream, "< %p\n", oldptr);
+      tr_where (caller, info);
+      fprintf (mallstream, "> %p %#lx\n", block, (unsigned long int) size);
+    }
+
+  funlockfile (mallstream);
+}
+
+static void
+memalign_mtrace_after (void *block, size_t size, const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  /* We could be printing a NULL here; that's OK.  */
+  fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
+
+  funlockfile (mallstream);
+}
+
+/* This function gets called to make sure all memory the library
+   allocates get freed and so does not irritate the user when studying
+   the mtrace output.  */
+static void
+release_libc_mem (void)
+{
+  /* Only call the free function if we still are running in mtrace mode.  */
+  if (mallstream != NULL)
+    __libc_freeres ();
+}
+
+/* We enable tracing if the environment variable MALLOC_TRACE is set.  */
+
+static void
+do_mtrace (void)
+{
+  static int added_atexit_handler;
+  char *mallfile;
+
+  /* Don't panic if we're called more than once.  */
+  if (mallstream != NULL)
+    return;
+
+  mallfile = secure_getenv (mallenv);
+  if (mallfile != NULL)
+    {
+      char *mtb = malloc (TRACE_BUFFER_SIZE);
+      if (mtb == NULL)
+        return;
+
+      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
+      if (mallstream != NULL)
+        {
+          /* Be sure it doesn't malloc its buffer!  */
+          malloc_trace_buffer = mtb;
+          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
+          fprintf (mallstream, "= Start\n");
+          if (!added_atexit_handler)
+            {
+              added_atexit_handler = 1;
+              __cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
+			    __dso_handle);
+            }
+	  __malloc_debug_enable (MALLOC_MTRACE_HOOK);
+        }
+      else
+        free (mtb);
+    }
+}
+
+static void
+do_muntrace (void)
+{
+  __malloc_debug_disable (MALLOC_MTRACE_HOOK);
+  if (mallstream == NULL)
+    return;
+
+  /* Do the reverse of what done in mtrace: first reset the hooks and
+     MALLSTREAM, and only after that write the trailer and close the
+     file.  */
+  FILE *f = mallstream;
+  mallstream = NULL;
+
+  fprintf (f, "= End\n");
+  fclose (f);
+}
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index fb58413d39..c1c836a740 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -1,4 +1,4 @@
-/* More debugging hooks for `malloc'.
+/* mtrace API for `malloc'.
    Copyright (C) 1991-2021 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
                  Written April 2, 1991 by John Gilmore of Cygnus Support.
@@ -18,40 +18,14 @@
    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 <mcheck.h>
-# include <malloc-internal.h>
-# include <libc-lock.h>
+#if !IS_IN (libc)
+# include "mtrace-impl.c"
+#else
+# include <shlib-compat.h>
+# include <libc-symbols.h>
 #endif
 
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <_itoa.h>
-
-#include <libc-internal.h>
-#include <dso_handle.h>
-
-#include <libio/iolibio.h>
-#define setvbuf(s, b, f, l) _IO_setvbuf (s, b, f, l)
-#define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp)
-
-#include <kernel-features.h>
-
-#define TRACE_BUFFER_SIZE 512
-
-static FILE *mallstream;
-static const char mallenv[] = "MALLOC_TRACE";
-static char *malloc_trace_buffer;
-
-__libc_lock_define_initialized (static, lock);
-
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
+#if IS_IN (libc) && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
 /* Compatibility symbols that were introduced to help break at allocation sites
    for specific memory allocations.  This is unusable with ASLR, although gdb
    may allow predictable allocation addresses.  Even then, gdb has watchpoint
@@ -71,282 +45,18 @@ compat_symbol (libc, tr_break, tr_break, GLIBC_2_0);
 #endif
 
 
-/* Old hook values.  */
-static void (*tr_old_free_hook) (void *ptr, const void *);
-static void *(*tr_old_malloc_hook) (size_t size, const void *);
-static void *(*tr_old_realloc_hook) (void *ptr, size_t size,
-				     const void *);
-static void *(*tr_old_memalign_hook) (size_t __alignment, size_t __size,
-				      const void *);
-
-static void
-tr_where (const void *caller, Dl_info *info)
-{
-  if (caller != NULL)
-    {
-      if (info != NULL)
-        {
-          char *buf = (char *) "";
-          if (info->dli_sname != NULL)
-            {
-              size_t len = strlen (info->dli_sname);
-              buf = alloca (len + 6 + 2 * sizeof (void *));
-
-              buf[0] = '(';
-              __stpcpy (_fitoa (caller >= (const void *) info->dli_saddr
-                                ? caller - (const void *) info->dli_saddr
-                                : (const void *) info->dli_saddr - caller,
-                                __stpcpy (__mempcpy (buf + 1, info->dli_sname,
-                                                     len),
-                                          caller >= (void *) info->dli_saddr
-                                          ? "+0x" : "-0x"),
-                                16, 0),
-                        ")");
-            }
-
-          fprintf (mallstream, "@ %s%s%s[%p] ",
-                   info->dli_fname ? : "", info->dli_fname ? ":" : "",
-                   buf, caller);
-        }
-      else
-        fprintf (mallstream, "@ [%p] ", caller);
-    }
-}
-
-static Dl_info *
-lock_and_info (const void *caller, Dl_info *mem)
-{
-  if (caller == NULL)
-    return NULL;
-
-  Dl_info *res = _dl_addr (caller, mem, NULL, NULL) ? mem : NULL;
-
-  __libc_lock_lock (lock);
-
-  return res;
-}
-
-static void tr_freehook (void *, const void *);
-static void * tr_mallochook (size_t, const void *);
-static void * tr_reallochook (void *, size_t, const void *);
-static void * tr_memalignhook (size_t, size_t, const void *);
-
-/* Set all the default non-trace hooks.  */
-static __always_inline void
-set_default_hooks (void)
-{
-  __free_hook = tr_old_free_hook;
-  __malloc_hook = tr_old_malloc_hook;
-  __realloc_hook = tr_old_realloc_hook;
-  __memalign_hook = tr_old_memalign_hook;
-}
-
-/* Set all of the tracing hooks used for mtrace.  */
-static __always_inline void
-set_trace_hooks (void)
-{
-  __free_hook = tr_freehook;
-  __malloc_hook = tr_mallochook;
-  __realloc_hook = tr_reallochook;
-  __memalign_hook = tr_memalignhook;
-}
-
-/* Save the current set of hooks as the default hooks.  */
-static __always_inline void
-save_default_hooks (void)
-{
-  tr_old_free_hook = __free_hook;
-  tr_old_malloc_hook = __malloc_hook;
-  tr_old_realloc_hook = __realloc_hook;
-  tr_old_memalign_hook = __memalign_hook;
-}
-
-static void
-tr_freehook (void *ptr, const void *caller)
-{
-  if (ptr == NULL)
-    return;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-  tr_where (caller, info);
-  /* Be sure to print it first.  */
-  fprintf (mallstream, "- %p\n", ptr);
-  set_default_hooks ();
-  if (tr_old_free_hook != NULL)
-    (*tr_old_free_hook)(ptr, caller);
-  else
-    free (ptr);
-  set_trace_hooks ();
-  __libc_lock_unlock (lock);
-}
-
-static void *
-tr_mallochook (size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_malloc_hook != NULL)
-    hdr = (void *) (*tr_old_malloc_hook)(size, caller);
-  else
-    hdr = (void *) malloc (size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  /* We could be printing a NULL here; that's OK.  */
-  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-static void *
-tr_reallochook (void *ptr, size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_realloc_hook != NULL)
-    hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
-  else
-    hdr = (void *) realloc (ptr, size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  if (hdr == NULL)
-    {
-      if (size != 0)
-        /* Failed realloc.  */
-        fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
-      else
-        fprintf (mallstream, "- %p\n", ptr);
-    }
-  else if (ptr == NULL)
-    fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-  else
-    {
-      fprintf (mallstream, "< %p\n", ptr);
-      tr_where (caller, info);
-      fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
-    }
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-static void *
-tr_memalignhook (size_t alignment, size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_memalign_hook != NULL)
-    hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
-  else
-    hdr = (void *) memalign (alignment, size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  /* We could be printing a NULL here; that's OK.  */
-  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-
-#ifdef _LIBC
-
-/* This function gets called to make sure all memory the library
-   allocates get freed and so does not irritate the user when studying
-   the mtrace output.  */
-static void __libc_freeres_fn_section
-release_libc_mem (void)
-{
-  /* Only call the free function if we still are running in mtrace mode.  */
-  if (mallstream != NULL)
-    __libc_freeres ();
-}
-#endif
-
-
-/* We enable tracing if the environment variable MALLOC_TRACE is set.  */
-
 void
 mtrace (void)
 {
-#ifdef _LIBC
-  static int added_atexit_handler;
+#if !IS_IN (libc)
+  do_mtrace ();
 #endif
-  char *mallfile;
-
-  /* Don't panic if we're called more than once.  */
-  if (mallstream != NULL)
-    return;
-
-#ifdef _LIBC
-  /* When compiling the GNU libc we use the secure getenv function
-     which prevents the misuse in case of SUID or SGID enabled
-     programs.  */
-  mallfile = __libc_secure_getenv (mallenv);
-#else
-  mallfile = getenv (mallenv);
-#endif
-  if (mallfile != NULL)
-    {
-      char *mtb = malloc (TRACE_BUFFER_SIZE);
-      if (mtb == NULL)
-        return;
-
-      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
-      if (mallstream != NULL)
-        {
-          /* Be sure it doesn't malloc its buffer!  */
-          malloc_trace_buffer = mtb;
-          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
-          fprintf (mallstream, "= Start\n");
-	  save_default_hooks ();
-	  set_trace_hooks ();
-#ifdef _LIBC
-          if (!added_atexit_handler)
-            {
-              added_atexit_handler = 1;
-              __cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
-			    __dso_handle);
-            }
-#endif
-        }
-      else
-        free (mtb);
-    }
 }
 
 void
 muntrace (void)
 {
-  if (mallstream == NULL)
-    return;
-
-  /* Do the reverse of what done in mtrace: first reset the hooks and
-     MALLSTREAM, and only after that write the trailer and close the
-     file.  */
-  FILE *f = mallstream;
-  mallstream = NULL;
-  set_default_hooks ();
-
-  fprintf (f, "= End\n");
-  fclose (f);
+#if !IS_IN (libc)
+  do_muntrace ();
+#endif
 }
diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data
index e2083c0ce6..9b4f35786a 100644
--- a/sysdeps/generic/localplt.data
+++ b/sysdeps/generic/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
index c5e1192b27..798d3ae8a3 100644
--- a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
+++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2.6 muntrace F
 GLIBC_2.2.6 posix_memalign F
 GLIBC_2.2.6 pvalloc F
 GLIBC_2.2.6 realloc F
diff --git a/sysdeps/mach/hurd/i386/localplt.data b/sysdeps/mach/hurd/i386/localplt.data
index 94064ecbc5..47fbe1e2a7 100644
--- a/sysdeps/mach/hurd/i386/localplt.data
+++ b/sysdeps/mach/hurd/i386/localplt.data
@@ -6,7 +6,6 @@
 libc.so: calloc + REL R_386_GLOB_DAT
 libc.so: free + REL R_386_GLOB_DAT
 libc.so: malloc + REL R_386_GLOB_DAT
-libc.so: memalign + REL R_386_GLOB_DAT
 libc.so: realloc + REL R_386_GLOB_DAT
 libm.so: matherr + REL R_386_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
index cc6531b017..bf543ed1e0 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.17 muntrace F
 GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data
index 2c14b652ef..348b3f3793 100644
--- a/sysdeps/unix/sysv/linux/aarch64/localplt.data
+++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # If outline atomics are used, libgcc (built outside of glibc) may
diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
index 5fe020dca6..fa8beb5e83 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data
index 43f6fdaea1..44bf36f4f1 100644
--- a/sysdeps/unix/sysv/linux/alpha/localplt.data
+++ b/sysdeps/unix/sysv/linux/alpha/localplt.data
@@ -18,7 +18,6 @@ libc.so: _Unwind_Find_FDE
 libc.so: calloc + RELA R_ALPHA_GLOB_DAT
 libc.so: free + RELA R_ALPHA_GLOB_DAT
 libc.so: malloc + RELA R_ALPHA_GLOB_DAT
-libc.so: memalign + RELA R_ALPHA_GLOB_DAT
 libc.so: realloc + RELA R_ALPHA_GLOB_DAT
 libm.so: matherr + RELA R_ALPHA_GLOB_DAT
 # We used to offer inline functions that used this, so it must be exported.
diff --git a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
index b5e9d10b9f..14bad4f83a 100644
--- a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.32 muntrace F
 GLIBC_2.32 posix_memalign F
 GLIBC_2.32 pvalloc F
 GLIBC_2.32 realloc F
diff --git a/sysdeps/unix/sysv/linux/arc/localplt.data b/sysdeps/unix/sysv/linux/arc/localplt.data
index 4479e8ee8a..ac5332caf7 100644
--- a/sysdeps/unix/sysv/linux/arc/localplt.data
+++ b/sysdeps/unix/sysv/linux/arc/localplt.data
@@ -1,6 +1,5 @@
 libc.so: realloc
 libc.so: malloc
-libc.so: memalign
 libc.so: calloc
 libc.so: free
 # At -Os, a struct assignment in libgcc-static pulls this in
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 c90d894b22..97b470a989 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.4 muntrace 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 c90d894b22..97b470a989 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.4 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data
index eb315da2f1..78896444c6 100644
--- a/sysdeps/unix/sysv/linux/arm/localplt.data
+++ b/sysdeps/unix/sysv/linux/arm/localplt.data
@@ -1,7 +1,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: raise
 libc.so: realloc
 libm.so: matherr
diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
index 932cbbd382..eac818b681 100644
--- a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.29 muntrace F
 GLIBC_2.29 posix_memalign F
 GLIBC_2.29 pvalloc F
 GLIBC_2.29 realloc F
diff --git a/sysdeps/unix/sysv/linux/csky/localplt.data b/sysdeps/unix/sysv/linux/csky/localplt.data
index 0ed8650b65..817ab2659a 100644
--- a/sysdeps/unix/sysv/linux/csky/localplt.data
+++ b/sysdeps/unix/sysv/linux/csky/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 # The TLS-enabled version of these functions is interposed from libc.so.
 ld.so: _dl_signal_error
diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
index 88ed3c09c8..88cdf04cbe 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data
index 09893d4dcf..baf857a750 100644
--- a/sysdeps/unix/sysv/linux/hppa/localplt.data
+++ b/sysdeps/unix/sysv/linux/hppa/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libc.so: __sigsetjmp
 libc.so: _IO_funlockfile
diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
index c847b1ee49..96955644d5 100644
--- a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
index 5334875b4b..f9bf7fb410 100644
--- a/sysdeps/unix/sysv/linux/i386/localplt.data
+++ b/sysdeps/unix/sysv/linux/i386/localplt.data
@@ -4,7 +4,6 @@ libc.so: _Unwind_Find_FDE + REL R_386_GLOB_DAT
 libc.so: calloc + REL R_386_GLOB_DAT
 libc.so: free + REL R_386_GLOB_DAT
 libc.so: malloc + REL R_386_GLOB_DAT
-libc.so: memalign + REL R_386_GLOB_DAT
 libc.so: realloc + REL R_386_GLOB_DAT
 libm.so: matherr + REL R_386_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
index bc8a2be276..ee940be29a 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace F
 GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data
index 1c566a503e..174fb88128 100644
--- a/sysdeps/unix/sysv/linux/ia64/localplt.data
+++ b/sysdeps/unix/sysv/linux/ia64/localplt.data
@@ -1,7 +1,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 libm.so: matherrf
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 c90d894b22..97b470a989 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.4 muntrace 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/coldfire/localplt.data b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
index 3c5efb7204..42fa90508c 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
@@ -2,7 +2,6 @@ libc.so: __m68k_read_tp
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 c847b1ee49..96955644d5 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
index 843f4e25f2..34bd4c1aca 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
@@ -3,7 +3,6 @@ libc.so: __m68k_read_tp
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 0502f3001e..48db59ebb1 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.18 muntrace 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 0502f3001e..48db59ebb1 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.18 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data
index 0e98d5251e..c3801314c9 100644
--- a/sysdeps/unix/sysv/linux/microblaze/localplt.data
+++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data
@@ -2,7 +2,6 @@ libc.so: __errno_location
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The dynamic loader needs __tls_get_addr for TLS.
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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc 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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc 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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc 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 5fe020dca6..fa8beb5e83 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
index 3a4599773d..3a3f0a2861 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.21 muntrace F
 GLIBC_2.21 posix_memalign F
 GLIBC_2.21 pvalloc F
 GLIBC_2.21 realloc F
diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data
index b37987c7c0..17fcfdd4db 100644
--- a/sysdeps/unix/sysv/linux/nios2/localplt.data
+++ b/sysdeps/unix/sysv/linux/nios2/localplt.data
@@ -6,7 +6,6 @@ libc.so: __gedf2
 libc.so: malloc
 libc.so: __gtsf2 ?
 libc.so: __nesf2
-libc.so: memalign
 libc.so: __mulsf3
 libc.so: __floatunsisf
 libc.so: __addsf3
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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
index a02dd5cc24..c0af84eef7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
@@ -2,7 +2,6 @@ libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
index d8072597b7..581e54b95c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
@@ -30,7 +30,6 @@ libc.so: abort ?
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: memset ?
 libc.so: realloc
 libm.so: copysignl ?
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 0696d526d4..9e0c7a48c0 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
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.3 muntrace 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 cc6531b017..bf543ed1e0 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
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.17 muntrace F
 GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
index bb498fbe3a..d69b7ae646 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
@@ -1,7 +1,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/riscv/localplt.data b/sysdeps/unix/sysv/linux/riscv/localplt.data
index 0a235592c3..e6d5330d5b 100644
--- a/sysdeps/unix/sysv/linux/riscv/localplt.data
+++ b/sysdeps/unix/sysv/linux/riscv/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: memset ?
 libc.so: realloc
 # The TLS-enabled version of these functions is interposed from libc.so.
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 4ded2f9640..e2448d7b83 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.33 muntrace 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 f878912895..622ee2e67a 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.27 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data
index a02dd5cc24..c0af84eef7 100644
--- a/sysdeps/unix/sysv/linux/s390/localplt.data
+++ b/sysdeps/unix/sysv/linux/s390/localplt.data
@@ -2,7 +2,6 @@ libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 c847b1ee49..96955644d5 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
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc 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 bc8a2be276..ee940be29a 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
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace 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 88ed3c09c8..88cdf04cbe 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace 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 88ed3c09c8..88cdf04cbe 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data
index 3225177c50..6491b9e37b 100644
--- a/sysdeps/unix/sysv/linux/sh/localplt.data
+++ b/sysdeps/unix/sysv/linux/sh/localplt.data
@@ -4,7 +4,6 @@
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libc.so: _Unwind_Find_FDE
 libc.so: _exit
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 c847b1ee49..96955644d5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
@@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
+GLIBC_2.0 mtrace F
+GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
index be51efd566..38309a1393 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
@@ -16,7 +16,6 @@ libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 bc8a2be276..ee940be29a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2 muntrace 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/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
index 809062d46c..6a216f3a5a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
@@ -15,7 +15,6 @@ libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
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 3fa0aa3cc3..e734b8f088 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
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.2.5 muntrace 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 4c213fcbef..14efc6602f 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
@@ -11,6 +11,8 @@ 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 mtrace F
+GLIBC_2.16 muntrace F
 GLIBC_2.16 posix_memalign F
 GLIBC_2.16 pvalloc F
 GLIBC_2.16 realloc F
diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data
index 8f41e92870..d1f2e26612 100644
--- a/sysdeps/x86_64/localplt.data
+++ b/sysdeps/x86_64/localplt.data
@@ -6,7 +6,6 @@
 libc.so: calloc + RELA R_X86_64_GLOB_DAT
 libc.so: free + RELA R_X86_64_GLOB_DAT
 libc.so: malloc + RELA R_X86_64_GLOB_DAT
-libc.so: memalign + RELA R_X86_64_GLOB_DAT
 libc.so: realloc + RELA R_X86_64_GLOB_DAT
 libm.so: matherr + RELA R_X86_64_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 08/10] glibc.malloc.check: Wean away from malloc hooks
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (6 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 07/10] mtrace: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 09/10] Remove " Siddhesh Poyarekar via Libc-alpha
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

The malloc-check debugging feature is tightly integrated into glibc
malloc, so thanks to an idea from Florian Weimer, much of the malloc
implementation has been moved into libc_malloc_debug.so to support
malloc-check.  Due to this, glibc malloc and malloc-check can no
longer work together; they use altogether different (but identical)
structures for heap management.  This should not make a difference
though since the malloc check hook is not disabled anywhere.
malloc_set_state does, but it does so early enough and that behaviour
has been ported to the debug DSO.

The only changes to malloc.c in this change is to add #if IS_IN (libc)
to not compile some functions into the debug DSO, especially the
allocator function entry points.

The malloc check tunable is now in the debug DSO and has no effect
when the DSO is not preloaded.
---
 malloc/Makefile                               |   3 +-
 malloc/Versions                               |  13 ++
 malloc/arena.c                                |  17 +-
 malloc/hooks.c                                |  17 +-
 malloc/malloc-check.c                         |  63 +++---
 malloc/malloc-debug.c                         | 181 ++++++++++++++++--
 malloc/malloc.c                               |  35 ++--
 sysdeps/aarch64/Makefile                      |   3 +
 .../mach/hurd/i386/libc_malloc_debug.abilist  |   7 +
 .../linux/aarch64/libc_malloc_debug.abilist   |   7 +
 .../linux/alpha/libc_malloc_debug.abilist     |   7 +
 .../sysv/linux/arc/libc_malloc_debug.abilist  |   7 +
 .../linux/arm/be/libc_malloc_debug.abilist    |   7 +
 .../linux/arm/le/libc_malloc_debug.abilist    |   7 +
 .../sysv/linux/csky/libc_malloc_debug.abilist |   7 +
 .../sysv/linux/hppa/libc_malloc_debug.abilist |   7 +
 .../sysv/linux/i386/libc_malloc_debug.abilist |   7 +
 .../sysv/linux/ia64/libc_malloc_debug.abilist |   7 +
 .../m68k/coldfire/libc_malloc_debug.abilist   |   7 +
 .../m68k/m680x0/libc_malloc_debug.abilist     |   7 +
 .../microblaze/be/libc_malloc_debug.abilist   |   7 +
 .../microblaze/le/libc_malloc_debug.abilist   |   7 +
 .../mips/mips32/fpu/libc_malloc_debug.abilist |   7 +
 .../mips32/nofpu/libc_malloc_debug.abilist    |   7 +
 .../mips/mips64/n32/libc_malloc_debug.abilist |   7 +
 .../mips/mips64/n64/libc_malloc_debug.abilist |   7 +
 .../linux/nios2/libc_malloc_debug.abilist     |   7 +
 .../powerpc32/fpu/libc_malloc_debug.abilist   |   7 +
 .../powerpc32/nofpu/libc_malloc_debug.abilist |   7 +
 .../powerpc64/be/libc_malloc_debug.abilist    |   7 +
 .../powerpc64/le/libc_malloc_debug.abilist    |   7 +
 .../riscv/rv32/libc_malloc_debug.abilist      |   7 +
 .../riscv/rv64/libc_malloc_debug.abilist      |   7 +
 .../s390/s390-32/libc_malloc_debug.abilist    |   7 +
 .../s390/s390-64/libc_malloc_debug.abilist    |   7 +
 .../linux/sh/be/libc_malloc_debug.abilist     |   7 +
 .../linux/sh/le/libc_malloc_debug.abilist     |   7 +
 .../sparc/sparc32/libc_malloc_debug.abilist   |   7 +
 .../sparc/sparc64/libc_malloc_debug.abilist   |   7 +
 .../linux/x86_64/64/libc_malloc_debug.abilist |   7 +
 .../x86_64/x32/libc_malloc_debug.abilist      |   7 +
 41 files changed, 482 insertions(+), 81 deletions(-)

diff --git a/malloc/Makefile b/malloc/Makefile
index c0dbe04b57..c9504d0916 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -133,7 +133,7 @@ test-extras = \
 libmemusage-routines = memusage
 libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
 
-libc_malloc_debug-routines = malloc-debug
+libc_malloc_debug-routines = malloc-debug $(sysdep_malloc_debug_routines)
 libc_malloc_debug-inhibit-o = $(filter-out .os,$(object-suffixes))
 
 $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
@@ -250,6 +250,7 @@ tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
 
 tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
 
+CPPFLAGS-malloc-debug.c += -DUSE_TCACHE=0
 ifeq ($(experimental-malloc),yes)
 CPPFLAGS-malloc.c += -DUSE_TCACHE=1
 else
diff --git a/malloc/Versions b/malloc/Versions
index 71d933de19..2961d0796d 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -119,13 +119,26 @@ libc_malloc_debug {
     mprobe;
     mtrace;
     muntrace;
+
+    mallinfo;
+    malloc_set_state;
+    malloc_stats;
+    malloc_trim;
+    malloc_usable_size;
+    mallopt;
   }
   GLIBC_2.2 {
     mcheck_check_all;
     mcheck_pedantic;
     posix_memalign;
   }
+  GLIBC_2.10 {
+    malloc_info;
+  }
   GLIBC_2.16 {
     aligned_alloc;
   }
+  GLIBC_2.33 {
+    mallinfo2;
+  }
 }
diff --git a/malloc/arena.c b/malloc/arena.c
index 840426f9fb..edcaa8816d 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -79,7 +79,9 @@ static __thread mstate thread_arena attribute_tls_model_ie;
    acquired after free_list_lock has been acquired.  */
 
 __libc_lock_define_initialized (static, free_list_lock);
+#if IS_IN (libc)
 static size_t narenas = 1;
+#endif
 static mstate free_list;
 
 /* list_lock prevents concurrent writes to the next member of struct
@@ -207,14 +209,6 @@ __malloc_fork_unlock_child (void)
 }
 
 #if HAVE_TUNABLES
-static void
-TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
-{
-  int32_t value = (int32_t) valp->numval;
-  if (value != 0)
-    __malloc_check_init ();
-}
-
 # define TUNABLE_CALLBACK_FNDECL(__name, __type) \
 static inline int do_ ## __name (__type value);				      \
 static void									      \
@@ -309,7 +303,7 @@ ptmalloc_init (void)
     }
 #endif
 
-#ifdef SHARED
+#if defined SHARED && IS_IN (libc)
   /* In case this libc copy is in a non-default namespace, never use
      brk.  Likewise if dlopened from statically linked program.  The
      generic sbrk implementation also enforces this, but it is not
@@ -323,7 +317,6 @@ ptmalloc_init (void)
   malloc_init_state (&main_arena);
 
 #if HAVE_TUNABLES
-  TUNABLE_GET (check, int32_t, TUNABLE_CALLBACK (set_mallopt_check));
   TUNABLE_GET (top_pad, size_t, TUNABLE_CALLBACK (set_top_pad));
   TUNABLE_GET (perturb, int32_t, TUNABLE_CALLBACK (set_perturb_byte));
   TUNABLE_GET (mmap_threshold, size_t, TUNABLE_CALLBACK (set_mmap_threshold));
@@ -401,8 +394,6 @@ ptmalloc_init (void)
             }
         }
     }
-  if (s && s[0] != '\0' && s[0] != '0')
-    __malloc_check_init ();
 #endif
 }
 
@@ -672,6 +663,7 @@ heap_trim (heap_info *heap, size_t pad)
 
 /* Create a new arena with initial size "size".  */
 
+#if IS_IN (libc)
 /* If REPLACED_ARENA is not NULL, detach it from this thread.  Must be
    called while free_list_lock is held.  */
 static void
@@ -947,6 +939,7 @@ arena_get_retry (mstate ar_ptr, size_t bytes)
 
   return ar_ptr;
 }
+#endif
 
 void
 __malloc_arena_thread_freeres (void)
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 8e9fefe6c3..af72b622c5 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -39,10 +39,10 @@ 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"
-
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
 
+static void ptmalloc_init (void);
+
 /* Support for restoring dumped heaps contained in historic Emacs
    executables.  The heap saving feature (malloc_get_state) is no
    longer implemented in this version of glibc, but we have a heap
@@ -106,14 +106,11 @@ malloc_set_state (void *msptr)
      must be called before the first call into the malloc subsytem
      (usually via __malloc_initialize_hook).  pthread_create always
      calls calloc and thus must be called only afterwards, so there
-     cannot be more than one thread when we reach this point.  */
-
-  /* Disable the malloc hooks (and malloc checking).  */
-  __malloc_hook = NULL;
-  __realloc_hook = NULL;
-  __free_hook = NULL;
-  __memalign_hook = NULL;
-  using_malloc_checking = 0;
+     cannot be more than one thread when we reach this point.  Since the
+     initialization hook is now in libc_malloc_debug.so, we may need to
+     initialize malloc.  */
+  if (!__malloc_initialized)
+    ptmalloc_init ();
 
   /* Patch the dumped heap.  We no longer try to integrate into the
      existing heap.  Instead, we mark the existing chunks as mmapped.
diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
index dcab880510..a444c7478e 100644
--- a/malloc/malloc-check.c
+++ b/malloc/malloc-check.c
@@ -17,20 +17,8 @@
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, see <https://www.gnu.org/licenses/>.  */
 
-
-/* Whether we are using malloc checking.  */
-static int using_malloc_checking;
-
-/* Activate a standard set of debugging hooks. */
-void
-__malloc_check_init (void)
-{
-  using_malloc_checking = 1;
-  __malloc_hook = malloc_check;
-  __free_hook = free_check;
-  __realloc_hook = realloc_check;
-  __memalign_hook = memalign_check;
-}
+#define __mremap mremap
+#include "malloc.c"
 
 /* When memory is tagged, the checking data is stored in the user part
    of the chunk.  We can't rely on the user not having modified the
@@ -63,14 +51,13 @@ magicbyte (const void *p)
    must reach it with this iteration, otherwise we have witnessed a memory
    corruption.  */
 static size_t
-malloc_check_get_size (mchunkptr p)
+malloc_check_get_size (void *mem)
 {
   size_t size;
   unsigned char c;
+  mchunkptr p = mem2chunk (mem);
   unsigned char magic = magicbyte (p);
 
-  assert (using_malloc_checking == 1);
-
   for (size = CHUNK_HDR_SZ + memsize (p) - 1;
        (c = *SAFE_CHAR_OFFSET (p, size)) != magic;
        size -= c)
@@ -203,7 +190,7 @@ top_check (void)
 }
 
 static void *
-malloc_check (size_t sz, const void *caller)
+malloc_check (size_t sz)
 {
   void *victim;
   size_t nb;
@@ -222,7 +209,7 @@ malloc_check (size_t sz, const void *caller)
 }
 
 static void
-free_check (void *mem, const void *caller)
+free_check (void *mem)
 {
   mchunkptr p;
 
@@ -256,7 +243,7 @@ free_check (void *mem, const void *caller)
 }
 
 static void *
-realloc_check (void *oldmem, size_t bytes, const void *caller)
+realloc_check (void *oldmem, size_t bytes)
 {
   INTERNAL_SIZE_T chnb;
   void *newmem = 0;
@@ -269,11 +256,11 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
       return NULL;
     }
   if (oldmem == 0)
-    return malloc_check (bytes, NULL);
+    return malloc_check (bytes);
 
   if (bytes == 0)
     {
-      free_check (oldmem, NULL);
+      free_check (oldmem);
       return NULL;
     }
 
@@ -348,12 +335,12 @@ invert:
 }
 
 static void *
-memalign_check (size_t alignment, size_t bytes, const void *caller)
+memalign_check (size_t alignment, size_t bytes)
 {
   void *mem;
 
   if (alignment <= MALLOC_ALIGNMENT)
-    return malloc_check (bytes, NULL);
+    return malloc_check (bytes);
 
   if (alignment < MINSIZE)
     alignment = MINSIZE;
@@ -363,14 +350,14 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
   if (alignment > SIZE_MAX / 2 + 1)
     {
       __set_errno (EINVAL);
-      return 0;
+      return NULL;
     }
 
   /* Check for overflow.  */
   if (bytes > SIZE_MAX - alignment - MINSIZE)
     {
       __set_errno (ENOMEM);
-      return 0;
+      return NULL;
     }
 
   /* Make sure alignment is power of 2.  */
@@ -388,3 +375,27 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
   __libc_lock_unlock (main_arena.mutex);
   return mem2mem_check (tag_new_usable (mem), bytes);
 }
+
+static void
+TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
+{
+  int32_t value = (int32_t) valp->numval;
+  if (value != 0)
+    __malloc_debug_enable (MALLOC_CHECK_HOOK);
+}
+
+static bool
+initialize_malloc_check (void)
+{
+  /* This is the copy of the malloc initializer that we pulled in along with
+     malloc-check.  This does not affect any of the libc malloc structures.  */
+  ptmalloc_init ();
+#if HAVE_TUNABLES
+  TUNABLE_GET (check, int32_t, TUNABLE_CALLBACK (set_mallopt_check));
+#else
+  const char *s = secure_getenv ("MALLOC_CHECK_");
+  if (s && s[0] != '\0' && s[0] != '0')
+    __malloc_debug_enable (MALLOC_CHECK_HOOK);
+#endif
+  return __is_malloc_debug_enabled (MALLOC_CHECK_HOOK);
+}
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
index 9942124e02..6e5402f20c 100644
--- a/malloc/malloc-debug.c
+++ b/malloc/malloc-debug.c
@@ -50,6 +50,7 @@ enum malloc_debug_hooks
   MALLOC_NONE_HOOK = 0,
   MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck()  */
   MALLOC_MTRACE_HOOK = 1 << 1, /* mtrace()  */
+  MALLOC_CHECK_HOOK = 1 << 2,  /* MALLOC_CHECK_ or glibc.malloc.check.  */
 };
 static unsigned __malloc_debugging_hooks;
 
@@ -73,6 +74,7 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
 
 #include "mcheck.c"
 #include "mtrace.c"
+#include "malloc-check.c"
 
 extern void (*__malloc_initialize_hook) (void);
 compat_symbol_reference (libc, __malloc_initialize_hook,
@@ -105,13 +107,18 @@ generic_hook_ini (void)
   __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));
+
+  /* malloc check does not quite co-exist with libc malloc, so initialize
+     either on or the other.  */
+  if (!initialize_malloc_check ())
+    /* 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;
 }
 
@@ -149,10 +156,11 @@ __debug_malloc (size_t bytes)
 
   void *victim = NULL;
   size_t orig_bytes = bytes;
-  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
-      || !malloc_mcheck_before (&bytes, &victim))
+  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+       || !malloc_mcheck_before (&bytes, &victim)))
     {
-      victim = __libc_malloc (bytes);
+      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
+		? malloc_check (bytes) : __libc_malloc (bytes));
     }
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = malloc_mcheck_after (victim, orig_bytes);
@@ -175,10 +183,12 @@ __debug_free (void *mem)
 
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
     mem = free_mcheck (mem);
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    free_check (mem);
+  else
+    __libc_free (mem);
   if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
     free_mtrace (mem, RETURN_ADDRESS (0));
-
-  __libc_free (mem);
 }
 strong_alias (__debug_free, free)
 
@@ -193,10 +203,12 @@ __debug_realloc (void *oldmem, size_t 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))
+  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+       || !realloc_mcheck_before (&oldmem, &bytes, &oldsize, &victim)))
     {
-      victim = __libc_realloc (oldmem, bytes);
+      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
+		? realloc_check (oldmem, bytes)
+		: __libc_realloc (oldmem, bytes));
     }
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
@@ -219,10 +231,12 @@ _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
   void *victim = NULL;
   size_t orig_bytes = bytes;
 
-  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
-      || !memalign_mcheck_before (alignment, &bytes, &victim))
+  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+       || !memalign_mcheck_before (alignment, &bytes, &victim)))
     {
-      victim = __libc_memalign (alignment, bytes);
+      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
+		? memalign_check (alignment, bytes)
+		: __libc_memalign (alignment, bytes));
     }
   if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
     victim = memalign_mcheck_after (victim, alignment, orig_bytes);
@@ -316,10 +330,11 @@ __debug_calloc (size_t nmemb, size_t size)
   size_t orig_bytes = bytes;
   void *victim = NULL;
 
-  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
-      || !malloc_mcheck_before (&bytes, &victim))
+  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
+       || !malloc_mcheck_before (&bytes, &victim)))
     {
-      victim = __libc_malloc (bytes);
+      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
+		? malloc_check (bytes) : __libc_malloc (bytes));
     }
   if (victim != NULL)
     {
@@ -333,3 +348,135 @@ __debug_calloc (size_t nmemb, size_t size)
   return victim;
 }
 strong_alias (__debug_calloc, calloc)
+
+size_t
+malloc_usable_size (void *mem)
+{
+  return (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
+	  ? malloc_check_get_size (mem) : musable (mem));
+}
+
+#define LIBC_SYMBOL(sym) libc_ ## sym
+#define SYMHANDLE(sym) sym ## _handle
+
+#define LOAD_SYM(sym) ({ \
+  static void *SYMHANDLE (sym);						      \
+  if (SYMHANDLE (sym) == NULL)						      \
+    SYMHANDLE (sym) = dlsym (RTLD_NEXT, #sym);				      \
+  SYMHANDLE (sym);							      \
+})
+
+int
+malloc_info (int options, FILE *fp)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __malloc_info (options, fp);
+
+  int (*LIBC_SYMBOL (malloc_info)) (int, FILE *) = LOAD_SYM (malloc_info);
+  if (LIBC_SYMBOL (malloc_info) == NULL)
+    return -1;
+
+  return LIBC_SYMBOL (malloc_info) (options, fp);
+}
+
+int
+mallopt (int param_number, int value)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __libc_mallopt (param_number, value);
+
+  int (*LIBC_SYMBOL (mallopt)) (int, int) = LOAD_SYM (mallopt);
+  if (LIBC_SYMBOL (mallopt) == NULL)
+    return 0;
+
+  return LIBC_SYMBOL (mallopt) (param_number, value);
+}
+
+void
+malloc_stats (void)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __malloc_stats ();
+
+  void (*LIBC_SYMBOL (malloc_stats)) (void) = LOAD_SYM (malloc_stats);
+  if (LIBC_SYMBOL (malloc_stats) == NULL)
+    return;
+
+  LIBC_SYMBOL (malloc_stats) ();
+}
+
+struct mallinfo2
+mallinfo2 (void)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __libc_mallinfo2 ();
+
+  struct mallinfo2 (*LIBC_SYMBOL (mallinfo2)) (void) = LOAD_SYM (mallinfo2);
+  if (LIBC_SYMBOL (mallinfo2) == NULL)
+    {
+      struct mallinfo2 ret = {0};
+      return ret;
+    }
+
+  return LIBC_SYMBOL (mallinfo2) ();
+}
+
+struct mallinfo
+mallinfo (void)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __libc_mallinfo ();
+
+  struct mallinfo (*LIBC_SYMBOL (mallinfo)) (void) = LOAD_SYM (mallinfo);
+  if (LIBC_SYMBOL (mallinfo) == NULL)
+    {
+      struct mallinfo ret = {0};
+      return ret;
+    }
+
+  return LIBC_SYMBOL (mallinfo) ();
+}
+
+int
+malloc_trim (size_t s)
+{
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return __malloc_trim (s);
+
+  int (*LIBC_SYMBOL (malloc_trim)) (size_t) = LOAD_SYM (malloc_trim);
+  if (LIBC_SYMBOL (malloc_trim) == NULL)
+    return 0;
+
+  return LIBC_SYMBOL (malloc_trim) (s);
+}
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
+int
+malloc_set_state (void *msptr)
+{
+  if (ms->magic != MALLOC_STATE_MAGIC)
+    return -1;
+
+  /* Must fail if the major version is too high. */
+  if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
+    return -2;
+
+  if (debug_initialized && __is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return -1;
+
+  /* It's not too late, so disable MALLOC_CHECK_ and hand off to the libc
+     malloc_set_state.  */
+  __malloc_debug_disable (MALLOC_CHECK_HOOK);
+  __malloc_hook = NULL;
+  __realloc_hook = NULL;
+  __free_hook = NULL;
+  __memalign_hook = NULL;
+
+  int (*LIBC_SYMBOL (malloc_set_state)) (void *) = LOAD_SYM (malloc_set_state);
+  if (LIBC_SYMBOL (malloc_set_state) == NULL)
+    return -1;
+
+  return LIBC_SYMBOL (malloc_set_state) (msptr);
+}
+compat_symbol (libc, malloc_set_state, malloc_set_state, GLIBC_2_0);
+#endif
diff --git a/malloc/malloc.c b/malloc/malloc.c
index ed0316e690..b8fcb2f2d3 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -288,6 +288,7 @@
 #define MALLOC_DEBUG 0
 #endif
 
+#if IS_IN (libc)
 #ifndef NDEBUG
 # define __assert_fail(assertion, file, line, function)			\
 	 __malloc_assert(assertion, file, line, function)
@@ -307,6 +308,7 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
   abort ();
 }
 #endif
+#endif
 
 #if USE_TCACHE
 /* We want 64 entries.  This is an arbitrary limit, which tunables can reduce.  */
@@ -592,6 +594,7 @@ tag_at (void *ptr)
 
 /* ---------- description of public routines ------------ */
 
+#if IS_IN (libc)
 /*
   malloc(size_t n)
   Returns a pointer to a newly allocated chunk of at least n bytes, or null
@@ -815,6 +818,7 @@ void     __malloc_stats(void);
   POSIX wrapper like memalign(), checking for validity of size.
 */
 int      __posix_memalign(void **, size_t, size_t);
+#endif /* IS_IN (libc) */
 
 /* mallopt tuning options */
 
@@ -1106,24 +1110,17 @@ static void     _int_free(mstate, mchunkptr, int);
 static void*  _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
 			   INTERNAL_SIZE_T);
 static void*  _int_memalign(mstate, size_t, size_t);
+#if IS_IN (libc)
 static void*  _mid_memalign(size_t, size_t, void *);
+#endif
 
 static void malloc_printerr(const char *str) __attribute__ ((noreturn));
 
-static void* mem2mem_check(void *p, size_t sz);
-static void top_check(void);
 static void munmap_chunk(mchunkptr p);
 #if HAVE_MREMAP
 static mchunkptr mremap_chunk(mchunkptr p, size_t new_size);
 #endif
 
-static void*   malloc_check(size_t sz, const void *caller);
-static void      free_check(void* mem, const void *caller);
-static void*   realloc_check(void* oldmem, size_t bytes,
-			       const void *caller);
-static void*   memalign_check(size_t alignment, size_t bytes,
-				const void *caller);
-
 /* ------------------ MMAP support ------------------  */
 
 
@@ -2385,7 +2382,9 @@ do_check_malloc_state (mstate av)
 
 
 /* ----------------- Support for debugging hooks -------------------- */
+#if IS_IN (libc)
 #include "hooks.c"
+#endif
 
 
 /* ----------- Routines dealing with system allocation -------------- */
@@ -3186,6 +3185,7 @@ tcache_thread_shutdown (void)
 
 #endif /* !USE_TCACHE  */
 
+#if IS_IN (libc)
 void *
 __libc_malloc (size_t bytes)
 {
@@ -3686,6 +3686,7 @@ __libc_calloc (size_t n, size_t elem_size)
 
   return mem;
 }
+#endif /* IS_IN (libc) */
 
 /*
    ------------------------------ malloc ------------------------------
@@ -5054,9 +5055,6 @@ musable (void *mem)
 
       p = mem2chunk (mem);
 
-      if (__builtin_expect (using_malloc_checking == 1, 0))
-	return malloc_check_get_size (p);
-
       if (chunk_is_mmapped (p))
 	{
 	  if (DUMPED_MAIN_ARENA_CHUNK (p))
@@ -5072,7 +5070,7 @@ musable (void *mem)
   return 0;
 }
 
-
+#if IS_IN (libc)
 size_t
 __malloc_usable_size (void *m)
 {
@@ -5081,12 +5079,12 @@ __malloc_usable_size (void *m)
   result = musable (m);
   return result;
 }
+#endif
 
 /*
    ------------------------------ mallinfo ------------------------------
    Accumulate malloc statistics for arena AV into M.
  */
-
 static void
 int_mallinfo (mstate av, struct mallinfo2 *m)
 {
@@ -5585,10 +5583,15 @@ extern char **__libc_argv attribute_hidden;
 static void
 malloc_printerr (const char *str)
 {
+#if IS_IN (libc)
   __libc_message (do_abort, "%s\n", str);
+#else
+  __libc_fatal (str);
+#endif
   __builtin_unreachable ();
 }
 
+#if IS_IN (libc)
 /* We need a wrapper function for one of the additions of POSIX.  */
 int
 __posix_memalign (void **memptr, size_t alignment, size_t size)
@@ -5618,6 +5621,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
   return ENOMEM;
 }
 weak_alias (__posix_memalign, posix_memalign)
+#endif
 
 
 int
@@ -5821,9 +5825,9 @@ __malloc_info (int options, FILE *fp)
 
   return 0;
 }
+#if IS_IN (libc)
 weak_alias (__malloc_info, malloc_info)
 
-
 strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
 strong_alias (__libc_free, __free) strong_alias (__libc_free, free)
 strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc)
@@ -5841,6 +5845,7 @@ strong_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
 weak_alias (__malloc_stats, malloc_stats)
 weak_alias (__malloc_usable_size, malloc_usable_size)
 weak_alias (__malloc_trim, malloc_trim)
+#endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
 compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 1099f1d657..7c66fb97aa 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -42,5 +42,8 @@ ifeq ($(subdir),misc)
 sysdep_headers += sys/ifunc.h
 sysdep_routines += __mtag_tag_zero_region \
 		   __mtag_tag_region
+endif
 
+ifeq ($(subdir),malloc)
+sysdep_malloc_debug_routines = __mtag_tag_zero_region __mtag_tag_region
 endif
diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
index 798d3ae8a3..c1ff86dfbd 100644
--- a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
+++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2.6 __free_hook D 0x4
 GLIBC_2.2.6 __malloc_hook D 0x4
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2.6 malloc F
+GLIBC_2.2.6 malloc_stats F
+GLIBC_2.2.6 malloc_trim F
+GLIBC_2.2.6 malloc_usable_size F
+GLIBC_2.2.6 mallopt F
 GLIBC_2.2.6 mcheck F
 GLIBC_2.2.6 mcheck_check_all F
 GLIBC_2.2.6 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2.6 posix_memalign F
 GLIBC_2.2.6 pvalloc F
 GLIBC_2.2.6 realloc F
 GLIBC_2.2.6 valloc F
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
index bf543ed1e0..65fb5036bd 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.17 malloc F
+GLIBC_2.17 malloc_info F
+GLIBC_2.17 malloc_stats F
+GLIBC_2.17 malloc_trim F
+GLIBC_2.17 malloc_usable_size F
+GLIBC_2.17 mallopt F
 GLIBC_2.17 mcheck F
 GLIBC_2.17 mcheck_check_all F
 GLIBC_2.17 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
 GLIBC_2.17 valloc F
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
index fa8beb5e83..bdf3541c24 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
index 14bad4f83a..cf9f611403 100644
--- a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.32 malloc F
+GLIBC_2.32 malloc_info F
+GLIBC_2.32 malloc_stats F
+GLIBC_2.32 malloc_trim F
+GLIBC_2.32 malloc_usable_size F
+GLIBC_2.32 mallopt F
 GLIBC_2.32 mcheck F
 GLIBC_2.32 mcheck_check_all F
 GLIBC_2.32 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.32 posix_memalign F
 GLIBC_2.32 pvalloc F
 GLIBC_2.32 realloc F
 GLIBC_2.32 valloc F
+GLIBC_2.33 mallinfo2 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 97b470a989..81be491d53 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
@@ -1,11 +1,18 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.33 mallinfo2 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 mallinfo F
 GLIBC_2.4 malloc F
+GLIBC_2.4 malloc_stats F
+GLIBC_2.4 malloc_trim F
+GLIBC_2.4 malloc_usable_size F
+GLIBC_2.4 mallopt F
 GLIBC_2.4 mcheck F
 GLIBC_2.4 mcheck_check_all F
 GLIBC_2.4 mcheck_pedantic 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 97b470a989..81be491d53 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
@@ -1,11 +1,18 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.33 mallinfo2 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 mallinfo F
 GLIBC_2.4 malloc F
+GLIBC_2.4 malloc_stats F
+GLIBC_2.4 malloc_trim F
+GLIBC_2.4 malloc_usable_size F
+GLIBC_2.4 mallopt F
 GLIBC_2.4 mcheck F
 GLIBC_2.4 mcheck_check_all F
 GLIBC_2.4 mcheck_pedantic F
diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
index eac818b681..4cd866430b 100644
--- a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.29 malloc F
+GLIBC_2.29 malloc_info F
+GLIBC_2.29 malloc_stats F
+GLIBC_2.29 malloc_trim F
+GLIBC_2.29 malloc_usable_size F
+GLIBC_2.29 mallopt F
 GLIBC_2.29 mcheck F
 GLIBC_2.29 mcheck_check_all F
 GLIBC_2.29 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.29 posix_memalign F
 GLIBC_2.29 pvalloc F
 GLIBC_2.29 realloc F
 GLIBC_2.29 valloc F
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
index 88cdf04cbe..22d0bf2d8a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x4
 GLIBC_2.2 __malloc_hook D 0x4
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
index 96955644d5..6b3c5bfd0b 100644
--- a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
index ee940be29a..6d5574a760 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x8
 GLIBC_2.2 __malloc_hook D 0x8
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 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 97b470a989..81be491d53 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
@@ -1,11 +1,18 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
+GLIBC_2.33 mallinfo2 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 mallinfo F
 GLIBC_2.4 malloc F
+GLIBC_2.4 malloc_stats F
+GLIBC_2.4 malloc_trim F
+GLIBC_2.4 malloc_usable_size F
+GLIBC_2.4 mallopt F
 GLIBC_2.4 mcheck F
 GLIBC_2.4 mcheck_check_all F
 GLIBC_2.4 mcheck_pedantic 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 96955644d5..6b3c5bfd0b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 48db59ebb1..daa80c4772 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.18 malloc F
+GLIBC_2.18 malloc_info F
+GLIBC_2.18 malloc_stats F
+GLIBC_2.18 malloc_trim F
+GLIBC_2.18 malloc_usable_size F
+GLIBC_2.18 mallopt F
 GLIBC_2.18 mcheck F
 GLIBC_2.18 mcheck_check_all F
 GLIBC_2.18 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.18 posix_memalign F
 GLIBC_2.18 pvalloc F
 GLIBC_2.18 realloc F
 GLIBC_2.18 valloc F
+GLIBC_2.33 mallinfo2 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 48db59ebb1..daa80c4772 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.18 malloc F
+GLIBC_2.18 malloc_info F
+GLIBC_2.18 malloc_stats F
+GLIBC_2.18 malloc_trim F
+GLIBC_2.18 malloc_usable_size F
+GLIBC_2.18 mallopt F
 GLIBC_2.18 mcheck F
 GLIBC_2.18 mcheck_check_all F
 GLIBC_2.18 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.18 posix_memalign F
 GLIBC_2.18 pvalloc F
 GLIBC_2.18 realloc F
 GLIBC_2.18 valloc F
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 fa8beb5e83..bdf3541c24 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
index 3a3f0a2861..ce6c5f7631 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.21 malloc F
+GLIBC_2.21 malloc_info F
+GLIBC_2.21 malloc_stats F
+GLIBC_2.21 malloc_trim F
+GLIBC_2.21 malloc_usable_size F
+GLIBC_2.21 mallopt F
 GLIBC_2.21 mcheck F
 GLIBC_2.21 mcheck_check_all F
 GLIBC_2.21 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.21 posix_memalign F
 GLIBC_2.21 pvalloc F
 GLIBC_2.21 realloc F
 GLIBC_2.21 valloc F
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 9e0c7a48c0..7f134f9b48 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,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.3 __free_hook D 0x8
 GLIBC_2.3 __malloc_hook D 0x8
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.3 malloc F
+GLIBC_2.3 malloc_stats F
+GLIBC_2.3 malloc_trim F
+GLIBC_2.3 malloc_usable_size F
+GLIBC_2.3 mallopt F
 GLIBC_2.3 mcheck F
 GLIBC_2.3 mcheck_check_all F
 GLIBC_2.3 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.3 posix_memalign F
 GLIBC_2.3 pvalloc F
 GLIBC_2.3 realloc F
 GLIBC_2.3 valloc F
+GLIBC_2.33 mallinfo2 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 bf543ed1e0..65fb5036bd 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
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.17 malloc F
+GLIBC_2.17 malloc_info F
+GLIBC_2.17 malloc_stats F
+GLIBC_2.17 malloc_trim F
+GLIBC_2.17 malloc_usable_size F
+GLIBC_2.17 mallopt F
 GLIBC_2.17 mcheck F
 GLIBC_2.17 mcheck_check_all F
 GLIBC_2.17 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.17 posix_memalign F
 GLIBC_2.17 pvalloc F
 GLIBC_2.17 realloc F
 GLIBC_2.17 valloc F
+GLIBC_2.33 mallinfo2 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 e2448d7b83..ff6713a479 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
@@ -5,7 +5,14 @@ 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 mallinfo F
+GLIBC_2.33 mallinfo2 F
 GLIBC_2.33 malloc F
+GLIBC_2.33 malloc_info F
+GLIBC_2.33 malloc_stats F
+GLIBC_2.33 malloc_trim F
+GLIBC_2.33 malloc_usable_size F
+GLIBC_2.33 mallopt F
 GLIBC_2.33 mcheck F
 GLIBC_2.33 mcheck_check_all F
 GLIBC_2.33 mcheck_pedantic 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 622ee2e67a..65425a03ee 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.27 malloc F
+GLIBC_2.27 malloc_info F
+GLIBC_2.27 malloc_stats F
+GLIBC_2.27 malloc_trim F
+GLIBC_2.27 malloc_usable_size F
+GLIBC_2.27 mallopt F
 GLIBC_2.27 mcheck F
 GLIBC_2.27 mcheck_check_all F
 GLIBC_2.27 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.27 posix_memalign F
 GLIBC_2.27 pvalloc F
 GLIBC_2.27 realloc F
 GLIBC_2.27 valloc F
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 ee940be29a..6d5574a760 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,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x8
 GLIBC_2.2 __malloc_hook D 0x8
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 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 88cdf04cbe..22d0bf2d8a 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x4
 GLIBC_2.2 __malloc_hook D 0x4
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 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 88cdf04cbe..22d0bf2d8a 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x4
 GLIBC_2.2 __malloc_hook D 0x4
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
@@ -4,7 +4,12 @@ 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 mallinfo F
 GLIBC_2.0 malloc F
+GLIBC_2.0 malloc_stats F
+GLIBC_2.0 malloc_trim F
+GLIBC_2.0 malloc_usable_size F
+GLIBC_2.0 mallopt F
 GLIBC_2.0 mcheck F
 GLIBC_2.0 memalign F
 GLIBC_2.0 mprobe F
@@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
 GLIBC_2.0 pvalloc F
 GLIBC_2.0 realloc F
 GLIBC_2.0 valloc F
+GLIBC_2.10 malloc_info 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
+GLIBC_2.33 mallinfo2 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 ee940be29a..6d5574a760 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2 __free_hook D 0x8
 GLIBC_2.2 __malloc_hook D 0x8
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2 malloc F
+GLIBC_2.2 malloc_stats F
+GLIBC_2.2 malloc_trim F
+GLIBC_2.2 malloc_usable_size F
+GLIBC_2.2 mallopt F
 GLIBC_2.2 mcheck F
 GLIBC_2.2 mcheck_check_all F
 GLIBC_2.2 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
 GLIBC_2.2 pvalloc F
 GLIBC_2.2 realloc F
 GLIBC_2.2 valloc F
+GLIBC_2.33 mallinfo2 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 e734b8f088..3b7b729d64 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,3 +1,4 @@
+GLIBC_2.10 malloc_info F
 GLIBC_2.16 aligned_alloc F
 GLIBC_2.2.5 __free_hook D 0x8
 GLIBC_2.2.5 __malloc_hook D 0x8
@@ -5,7 +6,12 @@ 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 mallinfo F
 GLIBC_2.2.5 malloc F
+GLIBC_2.2.5 malloc_stats F
+GLIBC_2.2.5 malloc_trim F
+GLIBC_2.2.5 malloc_usable_size F
+GLIBC_2.2.5 mallopt F
 GLIBC_2.2.5 mcheck F
 GLIBC_2.2.5 mcheck_check_all F
 GLIBC_2.2.5 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.2.5 posix_memalign F
 GLIBC_2.2.5 pvalloc F
 GLIBC_2.2.5 realloc F
 GLIBC_2.2.5 valloc F
+GLIBC_2.33 mallinfo2 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 14efc6602f..91d737a7f8 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
@@ -5,7 +5,13 @@ 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 mallinfo F
 GLIBC_2.16 malloc F
+GLIBC_2.16 malloc_info F
+GLIBC_2.16 malloc_stats F
+GLIBC_2.16 malloc_trim F
+GLIBC_2.16 malloc_usable_size F
+GLIBC_2.16 mallopt F
 GLIBC_2.16 mcheck F
 GLIBC_2.16 mcheck_check_all F
 GLIBC_2.16 mcheck_pedantic F
@@ -17,3 +23,4 @@ GLIBC_2.16 posix_memalign F
 GLIBC_2.16 pvalloc F
 GLIBC_2.16 realloc F
 GLIBC_2.16 valloc F
+GLIBC_2.33 mallinfo2 F
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 09/10] Remove malloc hooks
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (7 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 08/10] glibc.malloc.check: " Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13  7:38 ` [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057] Siddhesh Poyarekar via Libc-alpha
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Make malloc hooks symbols compat-only so that new applications cannot
link against them and remove the declarations from the API.  Also
remove the unused malloc-hooks.h.

Finally, mark all symbols in libc_malloc_debug.so as compat so that
the library cannot be linked against.

Add a note about the deprecation in NEWS.
---
 NEWS                  |  10 +++
 malloc/hooks.c        |   6 +-
 malloc/malloc-debug.c |  36 ++++++++
 malloc/malloc-hooks.h |  24 ------
 malloc/malloc.h       |  16 ----
 manual/memory.texi    | 191 ++----------------------------------------
 6 files changed, 57 insertions(+), 226 deletions(-)
 delete mode 100644 malloc/malloc-hooks.h

diff --git a/NEWS b/NEWS
index 0297d14f87..f1685e7d40 100644
--- a/NEWS
+++ b/NEWS
@@ -124,6 +124,16 @@ Deprecated and removed features, and other changes affecting compatibility:
   features now need to preload a new debugging DSO libc_malloc_debug.so to get
   this functionality back.
 
+* The deprecated memory allocation hooks __malloc_hook, __realloc_hook,
+  __memalign_hook and __free_hook are now removed from the API.  Compatibility
+  symbols are present to support legacy programs but new applications can no
+  longer link to these symbols.  These hooks no longer have any effect on glibc
+  functionality.  The malloc debugging DSO libc_malloc_debug.so currently
+  supports hooks and can be preloaded to get this functionality back for older
+  programs.  However this is a transitional measure and may be removed in a
+  future release of the GNU C Library.  Users may port away from these hooks by
+  writing and preloading their own malloc interposition library.
+
 Changes to build and runtime requirements:
 
 * On Linux, the shm_open, sem_open, and related functions now expect the
diff --git a/malloc/hooks.c b/malloc/hooks.c
index af72b622c5..fff6fe76db 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -32,12 +32,16 @@ void weak_variable (*__after_morecore_hook) (void) = NULL;
 compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
 void *(*__morecore)(ptrdiff_t);
 compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);
-#endif
 
 void weak_variable (*__free_hook) (void *, const void *) = NULL;
 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;
+compat_symbol (libc, __free_hook, __free_hook, GLIBC_2_0);
+compat_symbol (libc, __malloc_hook, __malloc_hook, GLIBC_2_0);
+compat_symbol (libc, __realloc_hook, __realloc_hook, GLIBC_2_0);
+compat_symbol (libc, __memalign_hook, __memalign_hook, GLIBC_2_0);
+#endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
 
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
index 6e5402f20c..ef44546a4e 100644
--- a/malloc/malloc-debug.c
+++ b/malloc/malloc-debug.c
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <sys/param.h>
 
+#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_34)
 /* Support only the glibc allocators.  */
 extern void *__libc_malloc (size_t);
 extern void __libc_free (void *);
@@ -76,9 +77,11 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
 #include "mtrace.c"
 #include "malloc-check.c"
 
+#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
 extern void (*__malloc_initialize_hook) (void);
 compat_symbol_reference (libc, __malloc_initialize_hook,
 			 __malloc_initialize_hook, 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;
@@ -115,9 +118,11 @@ generic_hook_ini (void)
        will not try to optimize it away.  */
     __libc_free (__libc_malloc (0));
 
+#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
   void (*hook) (void) = __malloc_initialize_hook;
   if (hook != NULL)
     (*hook)();
+#endif
 
   debug_initialized = 1;
 }
@@ -480,3 +485,34 @@ malloc_set_state (void *msptr)
 }
 compat_symbol (libc, malloc_set_state, malloc_set_state, GLIBC_2_0);
 #endif
+
+/* Do not allow linking against the library.  */
+compat_symbol (libc_malloc_debug, aligned_alloc, aligned_alloc, GLIBC_2_16);
+compat_symbol (libc_malloc_debug, calloc, calloc, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, free, free, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mallinfo2, mallinfo2, GLIBC_2_33);
+compat_symbol (libc_malloc_debug, mallinfo, mallinfo, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, malloc_info, malloc_info, GLIBC_2_10);
+compat_symbol (libc_malloc_debug, malloc, malloc, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, malloc_stats, malloc_stats, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, malloc_trim, malloc_trim, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, malloc_usable_size, malloc_usable_size,
+	       GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mallopt, mallopt, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mcheck_check_all, mcheck_check_all,
+	       GLIBC_2_2);
+compat_symbol (libc_malloc_debug, mcheck, mcheck, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mcheck_pedantic, mcheck_pedantic, GLIBC_2_2);
+compat_symbol (libc_malloc_debug, memalign, memalign, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mprobe, mprobe, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, mtrace, mtrace, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, muntrace, muntrace, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, posix_memalign, posix_memalign, GLIBC_2_2);
+compat_symbol (libc_malloc_debug, pvalloc, pvalloc, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, realloc, realloc, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, valloc, valloc, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, __free_hook, __free_hook, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, __malloc_hook, __malloc_hook, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, __realloc_hook, __realloc_hook, GLIBC_2_0);
+compat_symbol (libc_malloc_debug, __memalign_hook, __memalign_hook, GLIBC_2_0);
+#endif
diff --git a/malloc/malloc-hooks.h b/malloc/malloc-hooks.h
deleted file mode 100644
index 0133331b83..0000000000
--- a/malloc/malloc-hooks.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Internal declarations of malloc hooks no longer in the public API.
-   Copyright (C) 2016-2021 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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; see the file COPYING.LIB.  If
-   not, see <https://www.gnu.org/licenses/>.  */
-
-#ifndef _MALLOC_HOOKS_H
-#define _MALLOC_HOOKS_H
-
-void (*__malloc_initialize_hook) (void);
-
-#endif  /* _MALLOC_HOOKS_H */
diff --git a/malloc/malloc.h b/malloc/malloc.h
index 17ab9ee345..2df0b38050 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -156,21 +156,5 @@ extern void malloc_stats (void) __THROW;
 /* Output information about state of allocator to stream FP.  */
 extern int malloc_info (int __options, FILE *__fp) __THROW;
 
-/* Hooks for debugging and user-defined versions. */
-extern void (*__MALLOC_HOOK_VOLATILE __free_hook) (void *__ptr,
-                                                   const void *)
-__MALLOC_DEPRECATED;
-extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook)(size_t __size,
-                                                     const void *)
-__MALLOC_DEPRECATED;
-extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook)(void *__ptr,
-                                                      size_t __size,
-                                                      const void *)
-__MALLOC_DEPRECATED;
-extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
-                                                       size_t __size,
-                                                       const void *)
-__MALLOC_DEPRECATED;
-
 __END_DECLS
 #endif /* malloc.h */
diff --git a/manual/memory.texi b/manual/memory.texi
index 93305f289b..69c8894602 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -328,8 +328,6 @@ any time (or never).
 * Malloc Tunable Parameters::   Use @code{mallopt} to adjust allocation
                                  parameters.
 * Heap Consistency Checking::   Automatic checking for errors.
-* Hooks for Malloc::            You can use these hooks for debugging
-				 programs that use @code{malloc}.
 * Statistics of Malloc::        Getting information about how much
 				 memory your program is using.
 * Summary of Malloc::           Summary of @code{malloc} and related functions.
@@ -1392,170 +1390,6 @@ compatibility.  Both @code{MALLOC_CHECK_} and @samp{-lmcheck} should
 uncover the same bugs - but using @code{MALLOC_CHECK_} you don't need to
 recompile your application.
 
-@node Hooks for Malloc
-@subsubsection Memory Allocation Hooks
-@cindex allocation hooks, for @code{malloc}
-
-@Theglibc{} lets you modify the behavior of @code{malloc},
-@code{realloc}, and @code{free} by specifying appropriate hook
-functions.  You can use these hooks to help you debug programs that use
-dynamic memory allocation, for example.
-
-The hook variables are declared in @file{malloc.h}.
-@pindex malloc.h
-
-@defvar __malloc_hook
-@standards{GNU, malloc.h}
-The value of this variable is a pointer to the function that
-@code{malloc} uses whenever it is called.  You should define this
-function to look like @code{malloc}; that is, like:
-
-@smallexample
-void *@var{function} (size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{malloc} function was called.  This value allows you to trace
-the memory consumption of the program.
-@end defvar
-
-@defvar __realloc_hook
-@standards{GNU, malloc.h}
-The value of this variable is a pointer to function that @code{realloc}
-uses whenever it is called.  You should define this function to look
-like @code{realloc}; that is, like:
-
-@smallexample
-void *@var{function} (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{realloc} function was called.  This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-@defvar __free_hook
-@standards{GNU, malloc.h}
-The value of this variable is a pointer to function that @code{free}
-uses whenever it is called.  You should define this function to look
-like @code{free}; that is, like:
-
-@smallexample
-void @var{function} (void *@var{ptr}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{free} function was called.  This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-@defvar __memalign_hook
-@standards{GNU, malloc.h}
-The value of this variable is a pointer to function that @code{aligned_alloc},
-@code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they
-are called.  You should define this function to look like @code{aligned_alloc};
-that is, like:
-
-@smallexample
-void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or
-@code{valloc} functions are called.  This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-You must make sure that the function you install as a hook for one of
-these functions does not call that function recursively without restoring
-the old value of the hook first!  Otherwise, your program will get stuck
-in an infinite recursion.  Before calling the function recursively, one
-should make sure to restore all the hooks to their previous value.  When
-coming back from the recursive call, all the hooks should be resaved
-since a hook might modify itself.
-
-An issue to look out for is the time at which the hook functions
-can be safely installed.  If the hook functions call the @code{malloc}-related
-functions recursively, it is necessary that @code{malloc} has already properly
-initialized itself at the time when @code{__malloc_hook} etc. is
-assigned to.  On the other hand, if the hook functions provide a
-complete @code{malloc} implementation of their own, it is vital that the hooks
-are assigned to @emph{before} the very first @code{malloc} call has
-completed, because otherwise a chunk obtained from the ordinary,
-un-hooked @code{malloc} may later be handed to @code{__free_hook}, for example.
-
-Here is an example showing how to use @code{__malloc_hook} and
-@code{__free_hook} properly.  It installs a function that prints out
-information every time @code{malloc} or @code{free} is called.  We just
-assume here that @code{realloc} and @code{memalign} are not used in our
-program.
-
-@smallexample
-/* Prototypes for __malloc_hook, __free_hook */
-#include <malloc.h>
-
-/* Prototypes for our hooks.  */
-static void my_init_hook (void);
-static void *my_malloc_hook (size_t, const void *);
-static void my_free_hook (void*, const void *);
-
-static void
-my_init (void)
-@{
-  old_malloc_hook = __malloc_hook;
-  old_free_hook = __free_hook;
-  __malloc_hook = my_malloc_hook;
-  __free_hook = my_free_hook;
-@}
-
-static void *
-my_malloc_hook (size_t size, const void *caller)
-@{
-  void *result;
-  /* Restore all old hooks */
-  __malloc_hook = old_malloc_hook;
-  __free_hook = old_free_hook;
-  /* Call recursively */
-  result = malloc (size);
-  /* Save underlying hooks */
-  old_malloc_hook = __malloc_hook;
-  old_free_hook = __free_hook;
-  /* @r{@code{printf} might call @code{malloc}, so protect it too.} */
-  printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
-  /* Restore our own hooks */
-  __malloc_hook = my_malloc_hook;
-  __free_hook = my_free_hook;
-  return result;
-@}
-
-static void
-my_free_hook (void *ptr, const void *caller)
-@{
-  /* Restore all old hooks */
-  __malloc_hook = old_malloc_hook;
-  __free_hook = old_free_hook;
-  /* Call recursively */
-  free (ptr);
-  /* Save underlying hooks */
-  old_malloc_hook = __malloc_hook;
-  old_free_hook = __free_hook;
-  /* @r{@code{printf} might call @code{free}, so protect it too.} */
-  printf ("freed pointer %p\n", ptr);
-  /* Restore our own hooks */
-  __malloc_hook = my_malloc_hook;
-  __free_hook = my_free_hook;
-@}
-
-main ()
-@{
-  my_init ();
-  @dots{}
-@}
-@end smallexample
-
-The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by
-installing such hooks.
-
 @c __morecore, __after_morecore_hook are undocumented
 @c It's not clear whether to document them.
 
@@ -1690,19 +1524,6 @@ Tell @code{malloc} to perform occasional consistency checks on
 dynamically allocated memory, and to call @var{abortfn} when an
 inconsistency is found.  @xref{Heap Consistency Checking}.
 
-@item void *(*__malloc_hook) (size_t @var{size}, const void *@var{caller})
-A pointer to a function that @code{malloc} uses whenever it is called.
-
-@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
-A pointer to a function that @code{realloc} uses whenever it is called.
-
-@item void (*__free_hook) (void *@var{ptr}, const void *@var{caller})
-A pointer to a function that @code{free} uses whenever it is called.
-
-@item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller})
-A pointer to a function that @code{aligned_alloc}, @code{memalign},
-@code{posix_memalign} and @code{valloc} use whenever they are called.
-
 @item struct mallinfo2 mallinfo2 (void)
 Return information about the current dynamic memory usage.
 @xref{Statistics of Malloc}.
@@ -1737,7 +1558,7 @@ penalties for the program if the debugging mode is not enabled.
 
 @deftypefun void mtrace (void)
 @standards{GNU, mcheck.h}
-@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Like the mcheck hooks, these are not designed with thread safety in
 @c mind, because the hook pointers are temporarily modified without
 @c regard to other threads, signals or cancellation.
@@ -1768,10 +1589,10 @@ with the SUID or SGID bit set.
 
 If the named file is successfully opened, @code{mtrace} installs special
 handlers for the functions @code{malloc}, @code{realloc}, and
-@code{free} (@pxref{Hooks for Malloc}).  From then on, all uses of these
-functions are traced and protocolled into the file.  There is now of
-course a speed penalty for all calls to the traced functions so tracing
-should not be enabled during normal use.
+@code{free}.  From then on, all uses of these functions are traced and
+protocolled into the file.  There is now of course a speed penalty for all
+calls to the traced functions so tracing should not be enabled during normal
+use.
 
 This function is a GNU extension and generally not available on other
 systems.  The prototype can be found in @file{mcheck.h}.
@@ -1779,7 +1600,7 @@ systems.  The prototype can be found in @file{mcheck.h}.
 
 @deftypefun void muntrace (void)
 @standards{GNU, mcheck.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
 
 @c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
 @c  fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057]
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (8 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 09/10] Remove " Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13  7:38 ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  2021-07-13 14:48 ` [PATCH v8 00/10] malloc hooks removal H.J. Lu via Libc-alpha
  2021-07-17 22:03 ` Carlos O'Donell via Libc-alpha
  11 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13  7:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer

Interpose malloc_usable_size to return the correct mcheck value for
malloc_usable_size.
---
 malloc/Makefile       | 4 +---
 malloc/malloc-debug.c | 8 ++++++--
 malloc/mcheck-impl.c  | 6 ++++++
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/malloc/Makefile b/malloc/Makefile
index c9504d0916..04c6b09949 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -83,7 +83,7 @@ ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)
 # the tests expect specific internal behavior that is changed due to linking to
 # libmcheck.a.
 tests-exclude-mcheck = tst-mallocstate \
-	tst-safe-linking tst-malloc-usable \
+	tst-safe-linking \
 	tst-malloc-backtrace \
 	tst-malloc-fork-deadlock \
 	tst-malloc-stats-cancellation \
@@ -92,8 +92,6 @@ tests-exclude-mcheck = tst-mallocstate \
 	tst-malloc-thread-fail \
 	tst-malloc-usable-tunables \
 	tst-malloc_info \
-	tst-pvalloc-fortify \
-	tst-reallocarray \
 	tst-compathooks-off tst-compathooks-on
 
 tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
index ef44546a4e..7968787ad6 100644
--- a/malloc/malloc-debug.c
+++ b/malloc/malloc-debug.c
@@ -357,8 +357,12 @@ strong_alias (__debug_calloc, calloc)
 size_t
 malloc_usable_size (void *mem)
 {
-  return (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
-	  ? malloc_check_get_size (mem) : musable (mem));
+  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
+    return mcheck_usable_size (mem);
+  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
+    return malloc_check_get_size (mem);
+
+  return musable (mem);
 }
 
 #define LIBC_SYMBOL(sym) libc_ ## sym
diff --git a/malloc/mcheck-impl.c b/malloc/mcheck-impl.c
index 8857e6b179..6597a290a6 100644
--- a/malloc/mcheck-impl.c
+++ b/malloc/mcheck-impl.c
@@ -404,3 +404,9 @@ __mcheck_initialize (void (*func) (enum mcheck_status), bool in_pedantic)
   pedantic = in_pedantic;
   return 0;
 }
+
+static int
+mcheck_usable_size (struct hdr *h)
+{
+  return (h - 1)->size;
+}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 00/10] malloc hooks removal
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (9 preceding siblings ...)
  2021-07-13  7:38 ` [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057] Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13 14:48 ` H.J. Lu via Libc-alpha
  2021-07-13 15:41   ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:03 ` Carlos O'Donell via Libc-alpha
  11 siblings, 1 reply; 39+ messages in thread
From: H.J. Lu via Libc-alpha @ 2021-07-13 14:48 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: Florian Weimer, GNU C Library

On Tue, Jul 13, 2021 at 12:39 AM Siddhesh Poyarekar via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> This patchset removes the malloc hooks __malloc_hook, __free_hook,
> __realloc_hook and __memalign_hook from the API and leaves compatibility
> symbols so that existing applications can continue to link to them.  The
> reading and execution of the hooks has been moved to a DSO
> libc_malloc_debug.so, which can be preloaded for applications that need
> it.  By default these hooks no longer have any effect in the library.
>
> Further, debugging features such as MALLOC_CHECK_, mcheck() and mtrace
> have been weaned away from these hooks and also moved to
> libc_malloc_debug.so.  With this change, these features are only enabled
> when libc_malloc_debug.so is preloaded using LD_PRELOAD.
>
> Finally, the __morecore, __morecore_after_hook and __default_morecore
> hooks have also been moved to compat symbols and removed from the API.
> Existing applications will continue to link to them but they won't have
> any effect on malloc behaviour.
>
> Testing:
>
> The patchset has gone through a full build and test on x86_64, i686,
> s390x, ppc64le, armv7l and aarch64 through a scratch build on Fedora
> rawhide.  I also installed a test package on x86_64 and rebooted to make
> sure the system boots to shell.  I did a build-many-glibcs run with
> the patchset and it ran clean on all targets.

Does this series fix posix_memalign:

https://sourceware.org/bugzilla/show_bug.cgi?id=23489

> Changes from v7:
> - Made mcheck tests conditional on GLIBC_2.24
> - Added SHLIB_COMPAT guard around __malloc_initialize_hook usage in
>   libc_malloc_debug.so
> - Fixed hurd build failure.
> - Add another patch to fix malloc_usable_size to mcheck
>
> Changes from v6:
> - Moved malloc-check into libc_malloc_debug.so. Tweaked malloc.c to
>   allow building twice, once inside libc.so and next in
>   libc_malloc_debug.so
> - Included morecore.c into malloc.c
> - Moved hook initialization too into libc_malloc_debug.so.
> - Interposed more functions in libc_malloc_debug.so
> - Versioned all symbols exported from libc_malloc_debug.so and finalized
>   them so that the library cannot be linked against
>
> Changes from v5:
> - Rebased on latest master
> - Fixed realloc-mcheck
> - Removed residual mention of libmalloc_compathooks
> - Removed LD_PRELOAD from elf/tst-setuid
>
> Changes from v4:
> - Patchset has a different approach, starting with moving out hooks
>   first to restrict all major malloc.c changes to the first patch
> - Renamed libmalloc_compathooks.so to libc_malloc_debug.so
> - Moved all debugging features into libc_malloc_debug.so
> - Made more documentation updates
> - Simplified __malloc_initialized variable use
> - Removed debugging tests on static variables since that is no longer
>   supported
>
> Changes from v3:
> - Remove source file dependencies
> - Commit mcheck tests
>
> Changes from v2:
> - Move hooks dependencies to malloc.o{,sS}
>
> Changes from v1:
>
> - Added makefile dependencies for the new hooks files
> - Fixed memset call in calloc debugging hooks
> - Added the tr_break deprecation patch and mcheck test patch to this
>   series
>
>
> Siddhesh Poyarekar (10):
>   Make mcheck tests conditional on GLIBC_2.24 or earlier
>   Remove __after_morecore_hook
>   Remove __morecore and __default_morecore
>   Move malloc hooks into a compat DSO
>   mcheck: Wean away from malloc hooks
>   Simplify __malloc_initialized
>   mtrace: Wean away from malloc hooks
>   glibc.malloc.check: Wean away from malloc hooks
>   Remove malloc hooks
>   mcheck Fix malloc_usable_size [BZ #22057]
>
>  NEWS                                          |  21 +
>  Rules                                         |   9 +-
>  catgets/Makefile                              |   4 +-
>  elf/Makefile                                  |  15 +-
>  elf/tst-leaks1-static.c                       |   1 -
>  iconvdata/Makefile                            |   3 +-
>  include/malloc.h                              |   6 -
>  include/mcheck.h                              |   4 -
>  include/stdlib.h                              |   3 -
>  intl/tst-gettext.sh                           |   1 +
>  libio/Makefile                                |  12 +-
>  localedata/Makefile                           |   3 +-
>  malloc/Makefile                               |  56 +-
>  malloc/Versions                               |  44 ++
>  malloc/arena.c                                |  48 +-
>  malloc/hooks.c                                |  71 ++-
>  malloc/malloc-check.c                         |  63 ++-
>  malloc/malloc-debug.c                         | 522 ++++++++++++++++++
>  malloc/malloc-hooks.h                         |  24 -
>  malloc/malloc.c                               | 163 ++----
>  malloc/malloc.h                               |  27 -
>  malloc/mcheck-impl.c                          | 412 ++++++++++++++
>  malloc/mcheck.c                               | 397 +------------
>  malloc/morecore.c                             |  34 +-
>  malloc/mtrace-impl.c                          | 226 ++++++++
>  malloc/mtrace.c                               | 313 +----------
>  malloc/tst-compathooks-off.c                  | 145 +++++
>  malloc/tst-compathooks-on.c                   |   2 +
>  malloc/tst-malloc-usable-static-tunables.c    |   1 -
>  malloc/tst-malloc-usable-static.c             |   1 -
>  malloc/tst-mtrace.sh                          |   1 +
>  manual/memory.texi                            | 207 +------
>  manual/tunables.texi                          |   4 +-
>  misc/Makefile                                 |   6 +-
>  nptl/Makefile                                 |   3 +-
>  posix/Makefile                                |  48 +-
>  resolv/Makefile                               |   9 +-
>  shlib-versions                                |   3 +
>  stdio-common/Makefile                         |  15 +-
>  sysdeps/aarch64/Makefile                      |   3 +
>  sysdeps/generic/libc_malloc_debug.abilist     |   0
>  sysdeps/generic/localplt.data                 |   1 -
>  sysdeps/mach/hurd/Makefile                    |   1 +
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |  26 +
>  sysdeps/mach/hurd/i386/localplt.data          |   1 -
>  sysdeps/pthread/Makefile                      |   3 +-
>  .../linux/aarch64/libc_malloc_debug.abilist   |  26 +
>  sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
>  .../linux/alpha/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |  26 +
>  sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
>  .../linux/arm/be/libc_malloc_debug.abilist    |  26 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |  26 +
>  sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
>  .../sysv/linux/csky/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
>  sysdeps/unix/sysv/linux/hppa/shlib-versions   |   2 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
>  sysdeps/unix/sysv/linux/ia64/shlib-versions   |   2 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
>  .../m68k/m680x0/libc_malloc_debug.abilist     |  26 +
>  .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
>  .../microblaze/be/libc_malloc_debug.abilist   |  26 +
>  .../microblaze/le/libc_malloc_debug.abilist   |  26 +
>  .../unix/sysv/linux/microblaze/localplt.data  |   1 -
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |  26 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |  26 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |  26 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/mips/shlib-versions   |   2 +
>  .../linux/nios2/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |  26 +
>  .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |  26 +
>  .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
>  .../powerpc64/be/libc_malloc_debug.abilist    |  26 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |  26 +
>  .../linux/powerpc/powerpc64/localplt.data     |   1 -
>  sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
>  .../riscv/rv32/libc_malloc_debug.abilist      |  26 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |  26 +
>  sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
>  .../s390/s390-32/libc_malloc_debug.abilist    |  26 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |  26 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |  26 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
>  sysdeps/unix/sysv/linux/sh/shlib-versions     |   1 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
>  .../sparc/sparc64/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
>  .../sysv/linux/sparc/sparc64/shlib-versions   |   1 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |  26 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |  26 +
>  sysdeps/x86_64/localplt.data                  |   1 -
>  104 files changed, 2557 insertions(+), 1266 deletions(-)
>  delete mode 100644 elf/tst-leaks1-static.c
>  create mode 100644 malloc/malloc-debug.c
>  delete mode 100644 malloc/malloc-hooks.h
>  create mode 100644 malloc/mcheck-impl.c
>  create mode 100644 malloc/mtrace-impl.c
>  create mode 100644 malloc/tst-compathooks-off.c
>  create mode 100644 malloc/tst-compathooks-on.c
>  delete mode 100644 malloc/tst-malloc-usable-static-tunables.c
>  delete mode 100644 malloc/tst-malloc-usable-static.c
>  create mode 100644 sysdeps/generic/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
>
> --
> 2.31.1
>


-- 
H.J.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 00/10] malloc hooks removal
  2021-07-13 14:48 ` [PATCH v8 00/10] malloc hooks removal H.J. Lu via Libc-alpha
@ 2021-07-13 15:41   ` Siddhesh Poyarekar via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-13 15:41 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, GNU C Library

On 7/13/21 8:18 PM, H.J. Lu wrote:
> Does this series fix posix_memalign:
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=23489
> 

The series does fix a memalign+posix_memalign bug for less than 
MALLOC_ALIGNMENT alignment (patch 5/10), so I think it should.  If it 
doesn't, I'll track it down and fix it after the series is pushed.

Thanks,
Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 05/10] mcheck: Wean away from malloc hooks
  2021-07-13  7:38 ` [PATCH v8 05/10] mcheck: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
@ 2021-07-13 15:47   ` H.J. Lu via Libc-alpha
  2021-07-14  2:44     ` Siddhesh Poyarekar via Libc-alpha
  2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  1 sibling, 1 reply; 39+ messages in thread
From: H.J. Lu via Libc-alpha @ 2021-07-13 15:47 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: Florian Weimer, GNU C Library

On Tue, Jul 13, 2021 at 12:44 AM Siddhesh Poyarekar via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Split the mcheck implementation into the debugging hooks and API so
> that the API can be replicated in libc and libc_malloc_debug.so.  The
> libc APIs always result in failure.
>
> The mcheck implementation has also been moved entirely into
> libc_malloc_debug.so and with it, all of the hook initialization code
> can now be moved into the debug library.  Now the initialization can
> be done independently of libc internals.
>
> With this patch, libc_malloc_debug.so can no longer be used with older
> libcs, which is not its goal anyway.  tst-vfork3 breaks due to this
> since it spawns shell scripts, which in turn execute using the system
> glibc.  Move the test to tests-container so that only the built glibc
> is used.
>
> This move also fixes bugs in the mcheck version of memalign and
> realloc, thus allowing removal of the tests from tests-mcheck
> exclusion list.
> ---
>  include/mcheck.h                              |   4 -
>  malloc/Makefile                               |   3 -
>  malloc/Versions                               |   9 +
>  malloc/hooks.c                                |  61 +--
>  malloc/malloc-debug.c                         | 173 +++++++-
>  malloc/mcheck-impl.c                          | 406 ++++++++++++++++++
>  malloc/mcheck.c                               | 398 +----------------
>  posix/Makefile                                |   8 +-
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |   8 +
>  .../linux/aarch64/libc_malloc_debug.abilist   |   8 +
>  .../linux/alpha/libc_malloc_debug.abilist     |   8 +
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |   8 +
>  .../linux/arm/be/libc_malloc_debug.abilist    |   8 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |   8 +
>  .../sysv/linux/csky/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |   8 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |   8 +
>  .../m68k/m680x0/libc_malloc_debug.abilist     |   8 +
>  .../microblaze/be/libc_malloc_debug.abilist   |   8 +
>  .../microblaze/le/libc_malloc_debug.abilist   |   8 +
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |   8 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |   8 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |   8 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |   8 +
>  .../linux/nios2/libc_malloc_debug.abilist     |   8 +
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |   8 +
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |   8 +
>  .../powerpc64/be/libc_malloc_debug.abilist    |   8 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |   8 +
>  .../riscv/rv32/libc_malloc_debug.abilist      |   8 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |   8 +
>  .../s390/s390-32/libc_malloc_debug.abilist    |   8 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |   8 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |   8 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |   8 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |   8 +
>  .../sparc/sparc64/libc_malloc_debug.abilist   |   8 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |   8 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |   8 +
>  41 files changed, 861 insertions(+), 465 deletions(-)
>  create mode 100644 malloc/mcheck-impl.c
>
> 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 7ea45d2358..c0dbe04b57 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 \

Since this fixes:

https://sourceware.org/bugzilla/show_bug.cgi?id=23489

please mention it.

Thanks.

>         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
> --
> 2.31.1
>


-- 
H.J.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 05/10] mcheck: Wean away from malloc hooks
  2021-07-13 15:47   ` H.J. Lu via Libc-alpha
@ 2021-07-14  2:44     ` Siddhesh Poyarekar via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-07-14  2:44 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, GNU C Library

On 7/13/21 9:17 PM, H.J. Lu via Libc-alpha wrote:
> Since this fixes:
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=23489
> 
> please mention it.

Fixed locally.  I also added #23328 to the subject line of 9/10.

Thanks,
Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-13  7:38 ` [PATCH v8 03/10] Remove __morecore and __default_morecore Siddhesh Poyarekar via Libc-alpha
@ 2021-07-14  7:01   ` Siddhesh Poyarekar
  2021-07-14 12:54     ` Guillaume Morin
  2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  1 sibling, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar @ 2021-07-14  7:01 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer, guillaume

FYI, there's at least one use case[1] that is adversely affected by 
__morecore removal.  I have closed it as WONTFIX citing that malloc does 
not always do the right thing with arbitrary morecore (and we don't even 
test it) anyway and it's a net win to remove them, but I mention it here 
too in the interest of a wider discussion.

Guillaume, would you like to elaborate on the use case a bit more so 
that we know exactly what we're dealing with?

Siddhesh

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=20646

On 7/13/21 1:08 PM, Siddhesh Poyarekar via Libc-alpha wrote:
> Make the __morecore and __default_morecore symbols compat-only and
> remove their declarations from the API.  Also, include morecore.c
> directly into malloc.c; this should ideally get merged into malloc in
> a future cleanup.
> ---
>   NEWS              |  5 +++++
>   include/stdlib.h  |  3 ---
>   malloc/Makefile   |  2 +-
>   malloc/arena.c    | 12 ++----------
>   malloc/hooks.c    |  2 ++
>   malloc/malloc.c   |  7 +++----
>   malloc/malloc.h   |  8 --------
>   malloc/morecore.c | 34 +++++++++++-----------------------
>   8 files changed, 24 insertions(+), 49 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index 13ffe627da..18d9e65eb2 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -113,6 +113,11 @@ Deprecated and removed features, and other changes affecting compatibility:
>     mtrace.  Similar functionality can be achieved by using conditional
>     breakpoints within mtrace functions from within gdb.
>   
> +* The __morecore and __after_morecore_hook malloc hooks and the default
> +  implementation __default_morecore have been removed from the API.  Existing
> +  applications will continue to link against these symbols but the interfaces
> +  no longer have any effect on malloc.
> +
>   Changes to build and runtime requirements:
>   
>   * On Linux, the shm_open, sem_open, and related functions now expect the
> diff --git a/include/stdlib.h b/include/stdlib.h
> index 1f6e1508e4..1c6f70b082 100644
> --- a/include/stdlib.h
> +++ b/include/stdlib.h
> @@ -306,9 +306,6 @@ libc_hidden_proto (__qfcvt_r)
>   #  define MB_CUR_MAX (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX))
>   # endif
>   
> -extern void *__default_morecore (ptrdiff_t) __THROW;
> -libc_hidden_proto (__default_morecore)
> -
>   struct abort_msg_s
>   {
>     unsigned int size;
> diff --git a/malloc/Makefile b/malloc/Makefile
> index d15729569b..020f781b59 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -104,7 +104,7 @@ tests-exclude-mcheck = tst-mallocstate \
>   tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
>   endif
>   
> -routines = malloc morecore mcheck mtrace obstack reallocarray \
> +routines = malloc mcheck mtrace obstack reallocarray \
>     scratch_buffer_dupfree \
>     scratch_buffer_grow scratch_buffer_grow_preserve \
>     scratch_buffer_set_array_size \
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 991fc21a7e..f1693ed48f 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -274,14 +274,6 @@ next_env_entry (char ***position)
>   #endif
>   
>   
> -#if defined(SHARED) || defined(USE_MTAG)
> -static void *
> -__failing_morecore (ptrdiff_t d)
> -{
> -  return (void *) MORECORE_FAILURE;
> -}
> -#endif
> -
>   #ifdef SHARED
>   extern struct dl_open_hook *_dl_open_hook;
>   libc_hidden_proto (_dl_open_hook);
> @@ -310,7 +302,7 @@ ptmalloc_init (void)
>   	 and that morecore does not support tagged regions, then
>   	 disable it.  */
>         if (__MTAG_SBRK_UNTAGGED)
> -	__morecore = __failing_morecore;
> +	__always_fail_morecore = true;
>   
>         mtag_enabled = true;
>         mtag_mmap_flags = __MTAG_MMAP_FLAGS;
> @@ -323,7 +315,7 @@ ptmalloc_init (void)
>        generic sbrk implementation also enforces this, but it is not
>        used on Hurd.  */
>     if (!__libc_initial)
> -    __morecore = __failing_morecore;
> +    __always_fail_morecore = true;
>   #endif
>   
>     thread_arena = &main_arena;
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index 45c91d6502..4aa6dadcff 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -20,6 +20,8 @@
>   #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
>   void weak_variable (*__after_morecore_hook) (void) = NULL;
>   compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
> +void *(*__morecore)(ptrdiff_t);
> +compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);
>   #endif
>   
>   /* Hooks for debugging versions.  The initial hooks just call the
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 24e7854a0e..6e8fa9e424 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -384,12 +384,11 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
>   #define TRIM_FASTBINS  0
>   #endif
>   
> -
>   /* Definition for getting more memory from the OS.  */
> -#define MORECORE         (*__morecore)
> +#include "morecore.c"
> +
> +#define MORECORE         (*__glibc_morecore)
>   #define MORECORE_FAILURE 0
> -void * __default_morecore (ptrdiff_t);
> -void *(*__morecore)(ptrdiff_t) = __default_morecore;
>   
>   /* Memory tagging.  */
>   
> diff --git a/malloc/malloc.h b/malloc/malloc.h
> index 634b7db868..17ab9ee345 100644
> --- a/malloc/malloc.h
> +++ b/malloc/malloc.h
> @@ -76,14 +76,6 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__
>   extern void *pvalloc (size_t __size) __THROW __attribute_malloc__
>     __wur __attr_dealloc_free;
>   
> -/* Underlying allocation function; successive calls should return
> -   contiguous pieces of memory.  */
> -extern void *(*__morecore) (ptrdiff_t __size) __MALLOC_DEPRECATED;
> -
> -/* Default value of `__morecore'.  */
> -extern void *__default_morecore (ptrdiff_t __size)
> -__THROW __attribute_malloc__  __MALLOC_DEPRECATED;
> -
>   /* SVID2/XPG mallinfo structure */
>   
>   struct mallinfo
> diff --git a/malloc/morecore.c b/malloc/morecore.c
> index 047228779b..8168ef158c 100644
> --- a/malloc/morecore.c
> +++ b/malloc/morecore.c
> @@ -15,39 +15,27 @@
>      License along with the GNU C Library; if not, see
>      <https://www.gnu.org/licenses/>.  */
>   
> -#ifndef _MALLOC_INTERNAL
> -# define _MALLOC_INTERNAL
> -# include <malloc.h>
> -#endif
> -
> -#ifndef __GNU_LIBRARY__
> -# define __sbrk  sbrk
> -#endif
> -
> -#ifdef __GNU_LIBRARY__
> -/* It is best not to declare this and cast its result on foreign operating
> -   systems with potentially hostile include files.  */
> -
> -# include <stddef.h>
> -# include <stdlib.h>
> -extern void *__sbrk (ptrdiff_t increment) __THROW;
> -libc_hidden_proto (__sbrk)
> -#endif
> -
> -#ifndef NULL
> -# define NULL 0
> +#if defined(SHARED) || defined(USE_MTAG)
> +static bool __always_fail_morecore = false;
>   #endif
>   
>   /* Allocate INCREMENT more bytes of data space,
>      and return the start of data space, or NULL on errors.
>      If INCREMENT is negative, shrink data space.  */
>   void *
> -__default_morecore (ptrdiff_t increment)
> +__glibc_morecore (ptrdiff_t increment)
>   {
> +#if defined(SHARED) || defined(USE_MTAG)
> +  if (__always_fail_morecore)
> +    return NULL;
> +#endif
> +
>     void *result = (void *) __sbrk (increment);
>     if (result == (void *) -1)
>       return NULL;
>   
>     return result;
>   }
> -libc_hidden_def (__default_morecore)
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
> +compat_symbol (libc, __glibc_morecore, __default_morecore, GLIBC_2_0);
> +#endif
> 


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14  7:01   ` Siddhesh Poyarekar
@ 2021-07-14 12:54     ` Guillaume Morin
  2021-07-14 14:13       ` Siddhesh Poyarekar
  0 siblings, 1 reply; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 12:54 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: fweimer, Siddhesh Poyarekar, libc-alpha, guillaume

On 14 Jul 12:31, Siddhesh Poyarekar wrote:
> FYI, there's at least one use case[1] that is adversely affected by
> __morecore removal.  I have closed it as WONTFIX citing that malloc does not
> always do the right thing with arbitrary morecore (and we don't even test
> it) anyway and it's a net win to remove them, but I mention it here too in
> the interest of a wider discussion.
> 
> Guillaume, would you like to elaborate on the use case a bit more so that we
> know exactly what we're dealing with?
> 
> Siddhesh
> 
> [1] https://sourceware.org/bugzilla/show_bug.cgi?id=20646

Hello Siddesh,

I replied on the bug report becuase I had not seen this message.

But basically, this breaks https://github.com/libhugetlbfs/libhugetlbfs/
which is old (started in 2006) and commonly used library.  The library
is plugging its own morecore() implementation to use hugetlb pages to
back the malloc heap.

This is definitely not a win for all libhugetlbfs users. We have no
equivalent solution. You're asking to find us an entire new malloc
implementation if there is one (or write one?). We have no way of keep
using glibc's malloc and hugetlb. I am not even sure there exists
an equivalent replacement.

I understand there is some security concern about malloc hooks but then
why not allow morecore() substitution with a properly
documented/supported interface? Most users already LD_PRELOAD
libhugetlbfs so that would be an easy fix.

You're claiming that it's subtly broken. I'd like to understand how and
why this can't be fixed. Afaik people have been using libhugetlbfs's
morecore() in production for 15+ years without any issue.

The only issue I am aware of is the one I reported about 5 years ago
(along with a reproducer and a patch). This problem can only be reached
if trimming is enabled in the morecore implementation (it's disabled in
libhugetlbfs for this very reason).

-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 12:54     ` Guillaume Morin
@ 2021-07-14 14:13       ` Siddhesh Poyarekar
  2021-07-14 16:42         ` Guillaume Morin
  0 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar @ 2021-07-14 14:13 UTC (permalink / raw)
  To: Guillaume Morin; +Cc: fweimer, Siddhesh Poyarekar, libc-alpha

On 7/14/21 6:24 PM, Guillaume Morin wrote:
> On 14 Jul 12:31, Siddhesh Poyarekar wrote:
> I replied on the bug report becuase I had not seen this message.
> 
> But basically, this breaks https://github.com/libhugetlbfs/libhugetlbfs/
> which is old (started in 2006) and commonly used library.  The library
> is plugging its own morecore() implementation to use hugetlb pages to
> back the malloc heap.

Thanks, AFAICT, libhugetlbfs only uses __morecore and not the rest of 
the interfaces.  The thing is, __morecore and friends have been 
deprecated for a year and building anything with __morecore ought to 
give the deprecation warning.

> This is definitely not a win for all libhugetlbfs users. We have no
> equivalent solution. You're asking to find us an entire new malloc
> implementation if there is one (or write one?). We have no way of keep
> using glibc's malloc and hugetlb. I am not even sure there exists
> an equivalent replacement.
> 
> I understand there is some security concern about malloc hooks but then
> why not allow morecore() substitution with a properly
> documented/supported interface? Most users already LD_PRELOAD
> libhugetlbfs so that would be an easy fix.

I don't think we would like to export a different interface to do the 
same thing because it still doesn't allow us to clamp down further on 
the system malloc implementation.  Besides, the morecore hooking 
interface is severely limited because it only affects the main arena. 
Non-main arenas have their own allocation techniques and it doesn't 
really make sense to have an interface to control just the main arena.

> You're claiming that it's subtly broken. I'd like to understand how and
> why this can't be fixed. Afaik people have been using libhugetlbfs's
> morecore() in production for 15+ years without any issue.
> 
> The only issue I am aware of is the one I reported about 5 years ago
> (along with a reproducer and a patch). This problem can only be reached
> if trimming is enabled in the morecore implementation (it's disabled in
> libhugetlbfs for this very reason).

There is only the one known issue that you reported but that may well be 
because the interface isn't well tested.  There have been many changes 
to malloc over the years and I cannot say for certain that the idea that 
morecore could be anything other than brk has been consistently 
considered.  We don't have tests to verify that either.  Further, 
morecore limits its influence to the main arena and it is possible that 
future changes could break this in ways that we cannot anticipate today.

Basically this is technical debt we've accumulated from the days when 
malloc assumed single threaded programs and was incrementally hacked to 
add in multi-threaded support.  We'd like to clean this up.

The malloc code in glibc is quite general purpose and has little 
dependency on libc internals.  It may well be possible for you to copy 
the source files over into libhugetlbfs to implement the interposer 
within libhugetlbfs that does exactly what you need.  In fact, that may 
even allow you to extend hugetlbfs support to non-main arenas.

Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 14:13       ` Siddhesh Poyarekar
@ 2021-07-14 16:42         ` Guillaume Morin
  2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
  2021-07-14 17:32           ` Siddhesh Poyarekar
  0 siblings, 2 replies; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 16:42 UTC (permalink / raw)
  To: Siddhesh Poyarekar
  Cc: fweimer, Siddhesh Poyarekar, Guillaume Morin, libc-alpha

On 14 Jul 19:43, Siddhesh Poyarekar wrote:
> > But basically, this breaks https://github.com/libhugetlbfs/libhugetlbfs/
> > which is old (started in 2006) and commonly used library.  The library
> > is plugging its own morecore() implementation to use hugetlb pages to
> > back the malloc heap.
> Thanks, AFAICT, libhugetlbfs only uses __morecore and not the rest of the
> interfaces.  The thing is, __morecore and friends have been deprecated for a
> year and building anything with __morecore ought to give the deprecation
> warning.

Probably. But you surely know that most people get glibc from their
distributions and do not build their own glibc. My main box is running
Debian stable for example. The next release (bullseye) seems like it'll
be shipping 2.31 (where it's not deprecated yet, I believe). RHEL8 ships
with a libhugetlbfs rpm (so users do not need to build it at all unlike
Debian), which will become useless with this change! Most users will
never have seen the deprecation warning before they see the actual
removal.

That said, I was personally aware since it was pointed out on a
libhugetlbfs github issue that it was deprecated in 2.32. I think the
hope was it would be replaced by something usable, and users would not
be left with *no* solution (I was also quietly hoping Eric Munson, the
libhugetlbfs maintainer would be reaching out). But if you remove it, I
am not quite sure what you expect libhugetlbfs users to do, really.

> I don't think we would like to export a different interface to do the same
> thing because it still doesn't allow us to clamp down further on the system
> malloc implementation.  Besides, the morecore hooking interface is severely
> limited because it only affects the main arena. Non-main arenas have their
> own allocation techniques and it doesn't really make sense to have an
> interface to control just the main arena.

Well, I do not see why morecore() does not make sense as a plugin. I am
not seeing any technical argument supporting that it will prevent
clamping down the implementation provided you document the currently
acceptable semantics for this interface.

libhugetlbfs users are aware this only works in the main arena. I
certainly agree this is not ideal and this is definitely something that
could be fixed as well. But again, keep in mind people have been using
this for 15+ years.

Obviously, if you're arguing to extend the glibc hookability so it works
for all arenas, I am all ears, certainly would help out and would be a
day one user :-)

> There is only the one known issue that you reported but that may well be
> because the interface isn't well tested.  There have been many changes to
> malloc over the years and I cannot say for certain that the idea that
> morecore could be anything other than brk has been consistently considered.
> We don't have tests to verify that either. 

I guess you mean sbrk() above and not brk().

Again, you seem to be ignoring the 15 years of people using
libhugetblfs. It's been tested extensively by users. I certainly agree
it should get testing in the glibc testsuite, but it's actually trivial
afaict:

- morecore() in effect has very simple semantics. It takes a size and
  returns a pointer to the beginning of the new area. The only thing
  that differs here from sbrk() is the fact that a new area might not be
  contiguous with the previous segment.  But that's supported in the
  malloc code, otherwise libhugetlbfs morecore() would never have worked
  (that's the MORECORE_CONTIGUOUS handling in the malloc code). That's
  really _all_ you need to test. And I would presume non contiguous
  heaps are implemented not just for morecore() sake (not sure though).
  If that's case, no actual specific testing needs to be done.

- If you _only_ allow morecore interposition through a DSO (as I was
  suggesting), you do _not_ even need to support non contiguous heaps
  (at least for morecore()) since at that point it becomes guaranteed
  that morecore() will always point to the same implementation. Then
  there is _nothing_ to test at that point. Proper morecore()
  implementations can semantically behave exactly like sbrk!

- A morecore2() hook that takes the old top of the heap as well as the
  size would also allow libhugetlbfs() to implement a perfectly
  continuous heap and so would semantically behave like sbrk().  But it
  does not look like it's being considered here :-)

> Further, morecore limits its influence to the main arena and it is
> possible that future changes could break this in ways that we cannot
> anticipate today.
 
As I said, we're aware and it not ideal :-). But if you're using single
threaded software, that covers all allocations under the mmap threshold
(which is tunable). So it's _very_ easy to make this hook usable for a lot
of software. The limitations are not such a big deal (but again, I'd prefer
if they were not there).

> Basically this is technical debt we've accumulated from the days when malloc
> assumed single threaded programs and was incrementally hacked to add in
> multi-threaded support.  We'd like to clean this up.

Honestly from my PoV, some usual feature was added a while ago. The rest
of the code was changed without paying attention to the feature (bug
report ignored for 5 years as well). And you're using this as an
argument to remove it.... I don't think this is tech debt at all, the
feature is simply paying the price of being ignored. It does _seem_ to
me that little effort have been made to see if it was workable at all.
 
> The malloc code in glibc is quite general purpose and has little dependency
> on libc internals.  It may well be possible for you to copy the source files
> over into libhugetlbfs to implement the interposer within libhugetlbfs that
> does exactly what you need.  In fact, that may even allow you to extend
> hugetlbfs support to non-main arenas.

To be clear, I am not the libhugetblfs maintainer, just a user (that
investigated the trimming issue). I think everybody is aware they can
fork the glibc malloc implementation.  Surely you realize that it's not
ideal but even feasible for most users.

Guillaume.

-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 16:42         ` Guillaume Morin
@ 2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
  2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
  2021-07-14 18:31             ` Guillaume Morin
  2021-07-14 17:32           ` Siddhesh Poyarekar
  1 sibling, 2 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-14 17:15 UTC (permalink / raw)
  To: Guillaume Morin, Siddhesh Poyarekar
  Cc: fweimer, Siddhesh Poyarekar, libc-alpha

On 7/14/21 12:42 PM, Guillaume Morin wrote:
> That said, I was personally aware since it was pointed out on a
> libhugetlbfs github issue that it was deprecated in 2.32. I think the
> hope was it would be replaced by something usable, and users would not
> be left with *no* solution (I was also quietly hoping Eric Munson, the
> libhugetlbfs maintainer would be reaching out). But if you remove it, I
> am not quite sure what you expect libhugetlbfs users to do, really.

Please work with upstream libhugetlbfs to prioritize issue #52.

Deprecation of morecore in glibc #52 (2020-08-27):
https://github.com/libhugetlbfs/libhugetlbfs/issues/52

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 16:42         ` Guillaume Morin
  2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
@ 2021-07-14 17:32           ` Siddhesh Poyarekar
  2021-07-14 18:25             ` Guillaume Morin
  1 sibling, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar @ 2021-07-14 17:32 UTC (permalink / raw)
  To: Guillaume Morin; +Cc: fweimer, Siddhesh Poyarekar, libc-alpha

On 7/14/21 10:12 PM, Guillaume Morin wrote:
> On 14 Jul 19:43, Siddhesh Poyarekar wrote:
> Probably. But you surely know that most people get glibc from their
> distributions and do not build their own glibc. My main box is running
> Debian stable for example. The next release (bullseye) seems like it'll
> be shipping 2.31 (where it's not deprecated yet, I believe). RHEL8 ships
> with a libhugetlbfs rpm (so users do not need to build it at all unlike
> Debian), which will become useless with this change! Most users will
> never have seen the deprecation warning before they see the actual
> removal.

But that means it won't be useless in RHEL8 or current stable 
Debian/Ubuntu, so there's still time for libhugetlbfs to adapt to the 
change.

> That said, I was personally aware since it was pointed out on a
> libhugetlbfs github issue that it was deprecated in 2.32. I think the
> hope was it would be replaced by something usable, and users would not
> be left with *no* solution (I was also quietly hoping Eric Munson, the
> libhugetlbfs maintainer would be reaching out). But if you remove it, I
> am not quite sure what you expect libhugetlbfs users to do, really.

As is evident, I personally haven't followed libhugetlbfs development 
and have been carrying forward work to remove __morecore that started at 
least a year ago, if not more.  That said though, the deprecation 
warning (especially the fact that the release notes specifically 
mentioned malloc interpositioning as the alternative) ought to have made 
it clear that we weren't thinking of an alternative.

> Well, I do not see why morecore() does not make sense as a plugin. I am
> not seeing any technical argument supporting that it will prevent
> clamping down the implementation provided you document the currently
> acceptable semantics for this interface.

Right now the debug DSO that this patch pulls out only supports the 
debugging features (malloc_check, mcheck, mtrace, old hooks) and they're 
not intended to be linked against, only used as compatibility for 
existing programs.  If __morecore is to move there, we'd have to allow 
linking with the debug DSO, which we don't want to do because it 
multiplies the interfaces we need to support.  We'd basically have two 
malloc interfaces to support then.

> libhugetlbfs users are aware this only works in the main arena. I
> certainly agree this is not ideal and this is definitely something that
> could be fixed as well. But again, keep in mind people have been using
> this for 15+ years.
> 
> Obviously, if you're arguing to extend the glibc hookability so it works
> for all arenas, I am all ears, certainly would help out and would be a
> day one user :-)

Unfortunately not, I'd like the system malloc to be as less hookable as 
possible because the hookability is a security nightmare and it prevents 
a lot of optimizations and hardening.

> Again, you seem to be ignoring the 15 years of people using
> libhugetblfs. It's been tested extensively by users. I certainly agree
> it should get testing in the glibc testsuite, but it's actually trivial
> afaict:
> 
> - morecore() in effect has very simple semantics. It takes a size and
>    returns a pointer to the beginning of the new area. The only thing
>    that differs here from sbrk() is the fact that a new area might not be
>    contiguous with the previous segment.  But that's supported in the
>    malloc code, otherwise libhugetlbfs morecore() would never have worked
>    (that's the MORECORE_CONTIGUOUS handling in the malloc code). That's
>    really _all_ you need to test. And I would presume non contiguous
>    heaps are implemented not just for morecore() sake (not sure though).
>    If that's case, no actual specific testing needs to be done.
> 
> - If you _only_ allow morecore interposition through a DSO (as I was
>    suggesting), you do _not_ even need to support non contiguous heaps
>    (at least for morecore()) since at that point it becomes guaranteed
>    that morecore() will always point to the same implementation. Then
>    there is _nothing_ to test at that point. Proper morecore()
>    implementations can semantically behave exactly like sbrk!
> 
> - A morecore2() hook that takes the old top of the heap as well as the
>    size would also allow libhugetlbfs() to implement a perfectly
>    continuous heap and so would semantically behave like sbrk().  But it
>    does not look like it's being considered here :-)

The direction we want to take is to not have to support all this in the 
interest of simplifying the implementation and make it easier to reason, 
audit and debug.

> Honestly from my PoV, some usual feature was added a while ago. The rest
> of the code was changed without paying attention to the feature (bug
> report ignored for 5 years as well). And you're using this as an
> argument to remove it.... I don't think this is tech debt at all, the
> feature is simply paying the price of being ignored. It does _seem_ to
> me that little effort have been made to see if it was workable at all.

Different developers have been involved in this and I suppose the 
developers who wrote the original implementation may even agree with 
you.  However, technology has changed a lot over the years and many of 
the things that were thought to be useful are now either redundant, 
unwieldy or downright dangerous.  The hooks fall somewhere between the 
last two because in the general case they're quite hard to reason and in 
the simplest case, they're unprotected indirections that have 
historically been used as vulnerability primitives for years.

> To be clear, I am not the libhugetblfs maintainer, just a user (that
> investigated the trimming issue). I think everybody is aware they can
> fork the glibc malloc implementation.  Surely you realize that it's not
> ideal but even feasible for most users.

I understand, I'm sorry it has come to this.  I hope libhugetlbfs 
maintainers can find a way out sooner.

Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
@ 2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
  2021-07-14 18:37               ` Guillaume Morin
  2021-07-14 18:48               ` Siddhesh Poyarekar
  2021-07-14 18:31             ` Guillaume Morin
  1 sibling, 2 replies; 39+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2021-07-14 17:42 UTC (permalink / raw)
  To: Carlos O'Donell, Guillaume Morin, Siddhesh Poyarekar
  Cc: fweimer, Siddhesh Poyarekar, libc-alpha



On 14/07/2021 14:15, Carlos O'Donell via Libc-alpha wrote:
> On 7/14/21 12:42 PM, Guillaume Morin wrote:
>> That said, I was personally aware since it was pointed out on a
>> libhugetlbfs github issue that it was deprecated in 2.32. I think the
>> hope was it would be replaced by something usable, and users would not
>> be left with *no* solution (I was also quietly hoping Eric Munson, the
>> libhugetlbfs maintainer would be reaching out). But if you remove it, I
>> am not quite sure what you expect libhugetlbfs users to do, really.
> 
> Please work with upstream libhugetlbfs to prioritize issue #52.
> 
> Deprecation of morecore in glibc #52 (2020-08-27):
> https://github.com/libhugetlbfs/libhugetlbfs/issues/52
> 

I agree with Carlos and Siddhesh rationale that a dangling function
pointer in an essential code as malloc is a security liability and it 
is about time to get removed (as there is PoC out there that does it to 
exploit glibc malloc). However I think we can work towards a solution to
enable within glibc instead of pushing the support on libhugetlfs, which 
does *not* aim to be a malloc replacement but rather a way to explicit
provide and manage large pages.

There is some discussion last year about providing large pages support
directly on glibc without resorting to THP [1].  The idea is to hook
up the mmap/madvise with the required flags, which seems similar of
what is required by libhugetls morecore() implementation [2]. So I think
it should be feasible to add support for the required bits on glibc
and provide a tunable to actually use it. 

The proposed patchset does require some additional work, such as providing
is through a tunable, allowing different sizes depending of the architecture,
and maybe just dump the sbrk change in favor of just using mmap() for the 
case of large pages.

Guillaume, would this be suffice for your use cases.  The libhugetlsfs
projects does provide more functionality than glibc scope, for instance
a linker script to for bss/data and exe section to large parges, so I
glibc support would be a complement to what libhugetls provides.

[1] https://sourceware.org/pipermail/libc-alpha/2020-May/113539.html
[2] https://github.com/libhugetlbfs/libhugetlbfs/blob/master/morecore.c

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 17:32           ` Siddhesh Poyarekar
@ 2021-07-14 18:25             ` Guillaume Morin
  2021-07-14 18:43               ` Siddhesh Poyarekar
  0 siblings, 1 reply; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 18:25 UTC (permalink / raw)
  To: Siddhesh Poyarekar
  Cc: fweimer, Siddhesh Poyarekar, Guillaume Morin, libc-alpha

On 14 Jul 23:02, Siddhesh Poyarekar wrote:
> But that means it won't be useless in RHEL8 or current stable Debian/Ubuntu,
> so there's still time for libhugetlbfs to adapt to the change.

As I said though, there is no other way besides forking glibc's malloc.
the morecore.c implementation in libhugetlbfs is like 100 lines of code.
We're not talking apples to apples. Far from it.

> As is evident, I personally haven't followed libhugetlbfs development and
> have been carrying forward work to remove __morecore that started at least a
> year ago, if not more.  That said though, the deprecation warning
> (especially the fact that the release notes specifically mentioned malloc
> interpositioning as the alternative) ought to have made it clear that we
> weren't thinking of an alternative.

Well, I will certainly grant that someone should have reached out
sooner, though I would probably have done it if my bug report had not
been ignore for 5 years ;-)

> > Well, I do not see why morecore() does not make sense as a plugin. I am
> > not seeing any technical argument supporting that it will prevent
> > clamping down the implementation provided you document the currently
> > acceptable semantics for this interface.
> 
> Right now the debug DSO that this patch pulls out only supports the
> debugging features (malloc_check, mcheck, mtrace, old hooks) and they're not
> intended to be linked against, only used as compatibility for existing
> programs.  If __morecore is to move there, we'd have to allow linking with
> the debug DSO, which we don't want to do because it multiplies the
> interfaces we need to support.  We'd basically have two malloc interfaces to
> support then.

I did not mean to say it should be moved to the debug DSO.

What I am saying is having explicit glibc support so I can LD_PRELOAD  a
version of libhugetlbfs that would export a __morecore() that will then be
used by glibc. No function pointers that needs explicitly set.

I am suggesting morecore interposition instead of the malloc
interposition you initially suggested. That should make no security
difference at all. It just requires to agree on some semantics though
for the interface which are basically these are sbrk.

> The direction we want to take is to not have to support all this in the
> interest of simplifying the implementation and make it easier to reason,
> audit and debug.

I think I have made decent technical points that it's not complicated at
all. There are no complications or security implications that I see,
just agreeing on the semantics on one function ...
I keep hearing theoretical concerns but nobody seems to want to detail:
why morecore interposition is complicated or insecure. I'll grant you
guys are the experts here, so please humor me, I am all ears.

> The hooks fall somewhere between the last two because in the
> general case they're quite hard to reason and in the simplest case, they're
> unprotected indirections that have historically been used as vulnerability
> primitives for years.

I have not argued for you to keep the hooks as is because i understand
your concerns. I am trying to find a solution that alleviates your
understandable concerns without breaking every single libhugetlbfs
user.

Guillaume.

-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
  2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
@ 2021-07-14 18:31             ` Guillaume Morin
  1 sibling, 0 replies; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 18:31 UTC (permalink / raw)
  To: Carlos O'Donell
  Cc: fweimer, Guillaume Morin, libc-alpha, Siddhesh Poyarekar

On 14 Jul 13:15, Carlos O'Donell wrote:
>
> On 7/14/21 12:42 PM, Guillaume Morin wrote:
> > That said, I was personally aware since it was pointed out on a
> > libhugetlbfs github issue that it was deprecated in 2.32. I think the
> > hope was it would be replaced by something usable, and users would not
> > be left with *no* solution (I was also quietly hoping Eric Munson, the
> > libhugetlbfs maintainer would be reaching out). But if you remove it, I
> > am not quite sure what you expect libhugetlbfs users to do, really.
> 
> Please work with upstream libhugetlbfs to prioritize issue #52.
> 
> Deprecation of morecore in glibc #52 (2020-08-27):
> https://github.com/libhugetlbfs/libhugetlbfs/issues/52

I wrote quite a few extensive emails in this thread about how there are
no good, maintainbable solution for libhugetlbfs that I can see. If
there was, I would have written a patch already instead of arguing over
email :-) 

I do get your frustation here and libhugetlbfs users/debs should have
reached out earlier. But I cannot do much about that now. I am trying to
find a workable compromise here, that's all.
 
-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
@ 2021-07-14 18:37               ` Guillaume Morin
  2021-07-14 18:48               ` Siddhesh Poyarekar
  1 sibling, 0 replies; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 18:37 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: fweimer, libc-alpha, Siddhesh Poyarekar, Guillaume Morin

On 14 Jul 14:42, Adhemerval Zanella wrote:
> I agree with Carlos and Siddhesh rationale that a dangling function
> pointer in an essential code as malloc is a security liability and it 
> is about time to get removed (as there is PoC out there that does it to 
> exploit glibc malloc).

To reiterate, I have not argued to keep the hook as is. I do understand
the valid concerns about potential exploitation with the current scheme.

> However I think we can work towards a solution to enable within glibc
> instead of pushing the support on libhugetlfs, which does *not* aim to
> be a malloc replacement but rather a way to explicit provide and
> manage large pages.
> There is some discussion last year about providing large pages support
> directly on glibc without resorting to THP [1].  The idea is to hook
> up the mmap/madvise with the required flags, which seems similar of
> what is required by libhugetls morecore() implementation [2]. So I think
> it should be feasible to add support for the required bits on glibc
> and provide a tunable to actually use it. 

That would be ideal.

> Guillaume, would this be suffice for your use cases.  The libhugetlsfs
> projects does provide more functionality than glibc scope, for instance
> a linker script to for bss/data and exe section to large parges, so I
> glibc support would be a complement to what libhugetls provides.

Yes, it would be perfect for my use case.

Guillaume.

-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 18:25             ` Guillaume Morin
@ 2021-07-14 18:43               ` Siddhesh Poyarekar
  2021-07-14 18:51                 ` Guillaume Morin
  0 siblings, 1 reply; 39+ messages in thread
From: Siddhesh Poyarekar @ 2021-07-14 18:43 UTC (permalink / raw)
  To: Guillaume Morin; +Cc: fweimer, Siddhesh Poyarekar, libc-alpha

On 7/14/21 11:55 PM, Guillaume Morin wrote:
> I did not mean to say it should be moved to the debug DSO.
> 
> What I am saying is having explicit glibc support so I can LD_PRELOAD  a
> version of libhugetlbfs that would export a __morecore() that will then be
> used by glibc. No function pointers that needs explicitly set.
> 
> I am suggesting morecore interposition instead of the malloc
> interposition you initially suggested. That should make no security
> difference at all. It just requires to agree on some semantics though
> for the interface which are basically these are sbrk.

This seems to be the central the point of difference.  A contract for an 
interface like that is not limited to hugetlbfs.

That said, Adhemerval's suggestion is perhaps a good compromise.  I'm 
far more comfortable with a tunable chosen hugetlbfs morecore 
implementation within glibc since it does not have any arbitrary 
interface contracts that we may be obliged to maintain indefinitely.

Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
  2021-07-14 18:37               ` Guillaume Morin
@ 2021-07-14 18:48               ` Siddhesh Poyarekar
  1 sibling, 0 replies; 39+ messages in thread
From: Siddhesh Poyarekar @ 2021-07-14 18:48 UTC (permalink / raw)
  To: Adhemerval Zanella, Carlos O'Donell, Guillaume Morin
  Cc: fweimer, libc-alpha

On 7/14/21 11:12 PM, Adhemerval Zanella wrote:
> There is some discussion last year about providing large pages support
> directly on glibc without resorting to THP [1].  The idea is to hook
> up the mmap/madvise with the required flags, which seems similar of
> what is required by libhugetls morecore() implementation [2]. So I think
> it should be feasible to add support for the required bits on glibc
> and provide a tunable to actually use it.

Sure, having hugetlb support within glibc is far more maintainable IMO 
than exposing a generic interface.

> The proposed patchset does require some additional work, such as providing
> is through a tunable, allowing different sizes depending of the architecture,
> and maybe just dump the sbrk change in favor of just using mmap() for the
> case of large pages.

I think we should keep it distinct from this patchset.  Since adding 
hugetlb support isn't likely to have an ABI impact (only tunables, which 
is not ABI), it could be done after 2.34.

What do you think?

Siddhesh

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-14 18:43               ` Siddhesh Poyarekar
@ 2021-07-14 18:51                 ` Guillaume Morin
  0 siblings, 0 replies; 39+ messages in thread
From: Guillaume Morin @ 2021-07-14 18:51 UTC (permalink / raw)
  To: Siddhesh Poyarekar
  Cc: fweimer, Siddhesh Poyarekar, Guillaume Morin, libc-alpha

On 15 Jul  0:13, Siddhesh Poyarekar wrote:
> This seems to be the central the point of difference.  A contract for an
> interface like that is not limited to hugetlbfs.

I do agree that it does seem to the central point of contention. I am
still a little confused about why that is though. The contract is: pass
a size_t, return the previous break. No other inferface necessary, mo special case or
anything necessary in the malloc code. You only need to provide the
default implementation that is just a straightforward call to sbrk().

> That said, Adhemerval's suggestion is perhaps a good compromise.  I'm far
> more comfortable with a tunable chosen hugetlbfs morecore implementation
> within glibc since it does not have any arbitrary interface contracts that
> we may be obliged to maintain indefinitely.

If that's workable, I do prefer this solution as well. A tunable is
stricly better.

-- 
Guillaume Morin <guillaume@morinfr.org>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 00/10] malloc hooks removal
  2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
                   ` (10 preceding siblings ...)
  2021-07-13 14:48 ` [PATCH v8 00/10] malloc hooks removal H.J. Lu via Libc-alpha
@ 2021-07-17 22:03 ` Carlos O'Donell via Libc-alpha
  11 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> This patchset removes the malloc hooks __malloc_hook, __free_hook,
> __realloc_hook and __memalign_hook from the API and leaves compatibility
> symbols so that existing applications can continue to link to them.  The
> reading and execution of the hooks has been moved to a DSO
> libc_malloc_debug.so, which can be preloaded for applications that need
> it.  By default these hooks no longer have any effect in the library.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

Awesome!

Thank you for taclking this.

I appreciate you sticking with the guidance and feedback on the patch series.
 
> Further, debugging features such as MALLOC_CHECK_, mcheck() and mtrace
> have been weaned away from these hooks and also moved to
> libc_malloc_debug.so.  With this change, these features are only enabled
> when libc_malloc_debug.so is preloaded using LD_PRELOAD.

As expected.

> Finally, the __morecore, __morecore_after_hook and __default_morecore
> hooks have also been moved to compat symbols and removed from the API.
> Existing applications will continue to link to them but they won't have
> any effect on malloc behaviour.

As expected.

> Testing:
> 
> The patchset has gone through a full build and test on x86_64, i686,
> s390x, ppc64le, armv7l and aarch64 through a scratch build on Fedora
> rawhide.  I also installed a test package on x86_64 and rebooted to make
> sure the system boots to shell.  I did a build-many-glibcs run with
> the patchset and it ran clean on all targets.

Awesome.

> Changes from v7:
> - Made mcheck tests conditional on GLIBC_2.24
> - Added SHLIB_COMPAT guard around __malloc_initialize_hook usage in
>   libc_malloc_debug.so
> - Fixed hurd build failure.
> - Add another patch to fix malloc_usable_size to mcheck
> 
> Changes from v6:
> - Moved malloc-check into libc_malloc_debug.so. Tweaked malloc.c to
>   allow building twice, once inside libc.so and next in
>   libc_malloc_debug.so
> - Included morecore.c into malloc.c
> - Moved hook initialization too into libc_malloc_debug.so.
> - Interposed more functions in libc_malloc_debug.so
> - Versioned all symbols exported from libc_malloc_debug.so and finalized
>   them so that the library cannot be linked against
> 
> Changes from v5:
> - Rebased on latest master
> - Fixed realloc-mcheck
> - Removed residual mention of libmalloc_compathooks
> - Removed LD_PRELOAD from elf/tst-setuid
> 
> Changes from v4:
> - Patchset has a different approach, starting with moving out hooks
>   first to restrict all major malloc.c changes to the first patch
> - Renamed libmalloc_compathooks.so to libc_malloc_debug.so
> - Moved all debugging features into libc_malloc_debug.so
> - Made more documentation updates
> - Simplified __malloc_initialized variable use
> - Removed debugging tests on static variables since that is no longer
>   supported
> 
> Changes from v3:
> - Remove source file dependencies
> - Commit mcheck tests
> 
> Changes from v2:
> - Move hooks dependencies to malloc.o{,sS}
> 
> Changes from v1:
> 
> - Added makefile dependencies for the new hooks files
> - Fixed memset call in calloc debugging hooks
> - Added the tr_break deprecation patch and mcheck test patch to this
>   series
> 
> 
> Siddhesh Poyarekar (10):
>   Make mcheck tests conditional on GLIBC_2.24 or earlier
>   Remove __after_morecore_hook
>   Remove __morecore and __default_morecore
>   Move malloc hooks into a compat DSO
>   mcheck: Wean away from malloc hooks
>   Simplify __malloc_initialized
>   mtrace: Wean away from malloc hooks
>   glibc.malloc.check: Wean away from malloc hooks
>   Remove malloc hooks
>   mcheck Fix malloc_usable_size [BZ #22057]
> 
>  NEWS                                          |  21 +
>  Rules                                         |   9 +-
>  catgets/Makefile                              |   4 +-
>  elf/Makefile                                  |  15 +-
>  elf/tst-leaks1-static.c                       |   1 -
>  iconvdata/Makefile                            |   3 +-
>  include/malloc.h                              |   6 -
>  include/mcheck.h                              |   4 -
>  include/stdlib.h                              |   3 -
>  intl/tst-gettext.sh                           |   1 +
>  libio/Makefile                                |  12 +-
>  localedata/Makefile                           |   3 +-
>  malloc/Makefile                               |  56 +-
>  malloc/Versions                               |  44 ++
>  malloc/arena.c                                |  48 +-
>  malloc/hooks.c                                |  71 ++-
>  malloc/malloc-check.c                         |  63 ++-
>  malloc/malloc-debug.c                         | 522 ++++++++++++++++++
>  malloc/malloc-hooks.h                         |  24 -
>  malloc/malloc.c                               | 163 ++----
>  malloc/malloc.h                               |  27 -
>  malloc/mcheck-impl.c                          | 412 ++++++++++++++
>  malloc/mcheck.c                               | 397 +------------
>  malloc/morecore.c                             |  34 +-
>  malloc/mtrace-impl.c                          | 226 ++++++++
>  malloc/mtrace.c                               | 313 +----------
>  malloc/tst-compathooks-off.c                  | 145 +++++
>  malloc/tst-compathooks-on.c                   |   2 +
>  malloc/tst-malloc-usable-static-tunables.c    |   1 -
>  malloc/tst-malloc-usable-static.c             |   1 -
>  malloc/tst-mtrace.sh                          |   1 +
>  manual/memory.texi                            | 207 +------
>  manual/tunables.texi                          |   4 +-
>  misc/Makefile                                 |   6 +-
>  nptl/Makefile                                 |   3 +-
>  posix/Makefile                                |  48 +-
>  resolv/Makefile                               |   9 +-
>  shlib-versions                                |   3 +
>  stdio-common/Makefile                         |  15 +-
>  sysdeps/aarch64/Makefile                      |   3 +
>  sysdeps/generic/libc_malloc_debug.abilist     |   0
>  sysdeps/generic/localplt.data                 |   1 -
>  sysdeps/mach/hurd/Makefile                    |   1 +
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |  26 +
>  sysdeps/mach/hurd/i386/localplt.data          |   1 -
>  sysdeps/pthread/Makefile                      |   3 +-
>  .../linux/aarch64/libc_malloc_debug.abilist   |  26 +
>  sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
>  .../linux/alpha/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |  26 +
>  sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
>  .../linux/arm/be/libc_malloc_debug.abilist    |  26 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |  26 +
>  sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
>  .../sysv/linux/csky/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
>  sysdeps/unix/sysv/linux/hppa/shlib-versions   |   2 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
>  sysdeps/unix/sysv/linux/ia64/shlib-versions   |   2 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
>  .../m68k/m680x0/libc_malloc_debug.abilist     |  26 +
>  .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
>  .../microblaze/be/libc_malloc_debug.abilist   |  26 +
>  .../microblaze/le/libc_malloc_debug.abilist   |  26 +
>  .../unix/sysv/linux/microblaze/localplt.data  |   1 -
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |  26 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |  26 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |  26 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |  26 +
>  sysdeps/unix/sysv/linux/mips/shlib-versions   |   2 +
>  .../linux/nios2/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |  26 +
>  .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |  26 +
>  .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
>  .../powerpc64/be/libc_malloc_debug.abilist    |  26 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |  26 +
>  .../linux/powerpc/powerpc64/localplt.data     |   1 -
>  sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
>  .../riscv/rv32/libc_malloc_debug.abilist      |  26 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |  26 +
>  sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
>  .../s390/s390-32/libc_malloc_debug.abilist    |  26 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |  26 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |  26 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |  26 +
>  sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
>  sysdeps/unix/sysv/linux/sh/shlib-versions     |   1 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
>  .../sparc/sparc64/libc_malloc_debug.abilist   |  26 +
>  .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
>  .../sysv/linux/sparc/sparc64/shlib-versions   |   1 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |  26 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |  26 +
>  sysdeps/x86_64/localplt.data                  |   1 -
>  104 files changed, 2557 insertions(+), 1266 deletions(-)
>  delete mode 100644 elf/tst-leaks1-static.c
>  create mode 100644 malloc/malloc-debug.c
>  delete mode 100644 malloc/malloc-hooks.h
>  create mode 100644 malloc/mcheck-impl.c
>  create mode 100644 malloc/mtrace-impl.c
>  create mode 100644 malloc/tst-compathooks-off.c
>  create mode 100644 malloc/tst-compathooks-on.c
>  delete mode 100644 malloc/tst-malloc-usable-static-tunables.c
>  delete mode 100644 malloc/tst-malloc-usable-static.c
>  create mode 100644 sysdeps/generic/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier
  2021-07-13  7:38 ` [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Targets with base versions later than 2.24 won't have
> __malloc_initialize_hook because of which the tests will essentially
> be the same as the regular malloc tests.  Avoid running them instead
> and save time.

Use have-GLIBC_2.23 for the release before the deprecation of a symbol.

Post v9 please and I'll ACK it quickly.

Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  malloc/Makefile | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/malloc/Makefile b/malloc/Makefile
> index 47369b6084..d15729569b 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -78,6 +78,8 @@ tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \
>  # Run all tests with MALLOC_CHECK_=3
>  tests-malloc-check = $(filter-out $(tests-exclude-malloc-check),$(tests))
>  
> +# -lmcheck needs __malloc_initialize_hook, which was deprecated in 2.24.

OK. Wow, 5 years ago.

> +ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)

Should be have-GLIBC_2.23, since if it was deprecated in 2.24, a new arch in 2.24
would not have it and it should be tested. You always want the conditional to
trigger on the last release to have the symbol.

>  # Tests that don't play well with mcheck.  They are either bugs in mcheck or
>  # the tests expect specific internal behavior that is changed due to linking to
>  # libmcheck.a.
> @@ -100,6 +102,7 @@ tests-exclude-mcheck = tst-mallocstate \
>  	tst-reallocarray
>  
>  tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
> +endif

OK.

>  
>  routines = malloc morecore mcheck mtrace obstack reallocarray \
>    scratch_buffer_dupfree \
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 02/10] Remove __after_morecore_hook
  2021-07-13  7:38 ` [PATCH v8 02/10] Remove __after_morecore_hook Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Remove __after_morecore_hook from the API and finalize the symbol so
> that it can no longer be used in new applications.  Old applications
> using __after_morecore_hook will find that their hook is no longer
> called.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  malloc/hooks.c  |  5 +++++
>  malloc/malloc.c | 22 +---------------------
>  malloc/malloc.h |  3 ---
>  3 files changed, 6 insertions(+), 24 deletions(-)
> 
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index daa5c7cfae..45c91d6502 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -17,6 +17,11 @@
>     License along with the GNU C Library; see the file COPYING.LIB.  If
>     not, see <https://www.gnu.org/licenses/>.  */
>  
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
> +void weak_variable (*__after_morecore_hook) (void) = NULL;
> +compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);

OK.

> +#endif
> +
>  /* Hooks for debugging versions.  The initial hooks just call the
>     initialization routine, then do the normal work. */
>  
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 154f6b460c..24e7854a0e 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -2041,8 +2041,6 @@ void *weak_variable (*__realloc_hook)
>  void *weak_variable (*__memalign_hook)
>    (size_t __alignment, size_t __size, const void *)
>    = memalign_hook_ini;
> -void weak_variable (*__after_morecore_hook) (void) = NULL;
> -

OK.

>  /* This function is called from the arena shutdown hook, to free the
>     thread cache (if it exists).  */
>  static void tcache_thread_shutdown (void);
> @@ -2668,14 +2666,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
>            LIBC_PROBE (memory_sbrk_more, 2, brk, size);
>          }
>  
> -      if (brk != (char *) (MORECORE_FAILURE))
> -        {
> -          /* Call the `morecore' hook if necessary.  */
> -          void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
> -          if (__builtin_expect (hook != NULL, 0))
> -            (*hook)();
> -        }
> -      else

OK.

> +      if (brk == (char *) (MORECORE_FAILURE))
>          {
>            /*
>               If have mmap, try using it as a backup when MORECORE fails or
> @@ -2814,13 +2805,6 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
>                        correction = 0;
>                        snd_brk = (char *) (MORECORE (0));
>                      }
> -                  else
> -                    {
> -                      /* Call the `morecore' hook if necessary.  */
> -                      void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
> -                      if (__builtin_expect (hook != NULL, 0))
> -                        (*hook)();
> -                    }

OK.

>                  }
>  
>                /* handle non-contiguous cases */
> @@ -2979,10 +2963,6 @@ systrim (size_t pad, mstate av)
>         */
>  
>        MORECORE (-extra);
> -      /* Call the `morecore' hook if necessary.  */
> -      void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
> -      if (__builtin_expect (hook != NULL, 0))
> -        (*hook)();

OK.

>        new_brk = (char *) (MORECORE (0));
>  
>        LIBC_PROBE (memory_sbrk_less, 2, new_brk, extra);
> diff --git a/malloc/malloc.h b/malloc/malloc.h
> index c1c0896d29..634b7db868 100644
> --- a/malloc/malloc.h
> +++ b/malloc/malloc.h
> @@ -179,9 +179,6 @@ extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
>                                                         size_t __size,
>                                                         const void *)
>  __MALLOC_DEPRECATED;
> -extern void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void)
> -  __MALLOC_DEPRECATED;

OK.

> -
>  
>  __END_DECLS
>  #endif /* malloc.h */
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 03/10] Remove __morecore and __default_morecore
  2021-07-13  7:38 ` [PATCH v8 03/10] Remove __morecore and __default_morecore Siddhesh Poyarekar via Libc-alpha
  2021-07-14  7:01   ` Siddhesh Poyarekar
@ 2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
  1 sibling, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Make the __morecore and __default_morecore symbols compat-only and
> remove their declarations from the API.  Also, include morecore.c
> directly into malloc.c; this should ideally get merged into malloc in
> a future cleanup.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  NEWS              |  5 +++++
>  include/stdlib.h  |  3 ---
>  malloc/Makefile   |  2 +-
>  malloc/arena.c    | 12 ++----------
>  malloc/hooks.c    |  2 ++
>  malloc/malloc.c   |  7 +++----
>  malloc/malloc.h   |  8 --------
>  malloc/morecore.c | 34 +++++++++++-----------------------
>  8 files changed, 24 insertions(+), 49 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index 13ffe627da..18d9e65eb2 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -113,6 +113,11 @@ Deprecated and removed features, and other changes affecting compatibility:
>    mtrace.  Similar functionality can be achieved by using conditional
>    breakpoints within mtrace functions from within gdb.
>  
> +* The __morecore and __after_morecore_hook malloc hooks and the default
> +  implementation __default_morecore have been removed from the API.  Existing
> +  applications will continue to link against these symbols but the interfaces
> +  no longer have any effect on malloc.

OK.

> +
>  Changes to build and runtime requirements:
>  
>  * On Linux, the shm_open, sem_open, and related functions now expect the
> diff --git a/include/stdlib.h b/include/stdlib.h
> index 1f6e1508e4..1c6f70b082 100644
> --- a/include/stdlib.h
> +++ b/include/stdlib.h
> @@ -306,9 +306,6 @@ libc_hidden_proto (__qfcvt_r)
>  #  define MB_CUR_MAX (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX))
>  # endif
>  
> -extern void *__default_morecore (ptrdiff_t) __THROW;
> -libc_hidden_proto (__default_morecore)

OK.

> -
>  struct abort_msg_s
>  {
>    unsigned int size;
> diff --git a/malloc/Makefile b/malloc/Makefile
> index d15729569b..020f781b59 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -104,7 +104,7 @@ tests-exclude-mcheck = tst-mallocstate \
>  tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
>  endif
>  
> -routines = malloc morecore mcheck mtrace obstack reallocarray \
> +routines = malloc mcheck mtrace obstack reallocarray \

OK.

>    scratch_buffer_dupfree \
>    scratch_buffer_grow scratch_buffer_grow_preserve \
>    scratch_buffer_set_array_size \
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 991fc21a7e..f1693ed48f 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -274,14 +274,6 @@ next_env_entry (char ***position)
>  #endif
>  
>  
> -#if defined(SHARED) || defined(USE_MTAG)
> -static void *
> -__failing_morecore (ptrdiff_t d)
> -{
> -  return (void *) MORECORE_FAILURE;
> -}
> -#endif
> -

OK.

>  #ifdef SHARED
>  extern struct dl_open_hook *_dl_open_hook;
>  libc_hidden_proto (_dl_open_hook);
> @@ -310,7 +302,7 @@ ptmalloc_init (void)
>  	 and that morecore does not support tagged regions, then
>  	 disable it.  */
>        if (__MTAG_SBRK_UNTAGGED)
> -	__morecore = __failing_morecore;
> +	__always_fail_morecore = true;

OK.

>  
>        mtag_enabled = true;
>        mtag_mmap_flags = __MTAG_MMAP_FLAGS;
> @@ -323,7 +315,7 @@ ptmalloc_init (void)
>       generic sbrk implementation also enforces this, but it is not
>       used on Hurd.  */
>    if (!__libc_initial)
> -    __morecore = __failing_morecore;
> +    __always_fail_morecore = true;

OK.

>  #endif
>  
>    thread_arena = &main_arena;
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index 45c91d6502..4aa6dadcff 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -20,6 +20,8 @@
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
>  void weak_variable (*__after_morecore_hook) (void) = NULL;
>  compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
> +void *(*__morecore)(ptrdiff_t);
> +compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);

OK.

>  #endif
>  
>  /* Hooks for debugging versions.  The initial hooks just call the
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 24e7854a0e..6e8fa9e424 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -384,12 +384,11 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
>  #define TRIM_FASTBINS  0
>  #endif
>  
> -
>  /* Definition for getting more memory from the OS.  */
> -#define MORECORE         (*__morecore)
> +#include "morecore.c"
> +
> +#define MORECORE         (*__glibc_morecore)

OK.

>  #define MORECORE_FAILURE 0
> -void * __default_morecore (ptrdiff_t);
> -void *(*__morecore)(ptrdiff_t) = __default_morecore;

OK.

>  
>  /* Memory tagging.  */
>  
> diff --git a/malloc/malloc.h b/malloc/malloc.h
> index 634b7db868..17ab9ee345 100644
> --- a/malloc/malloc.h
> +++ b/malloc/malloc.h
> @@ -76,14 +76,6 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__
>  extern void *pvalloc (size_t __size) __THROW __attribute_malloc__
>    __wur __attr_dealloc_free;
>  
> -/* Underlying allocation function; successive calls should return
> -   contiguous pieces of memory.  */
> -extern void *(*__morecore) (ptrdiff_t __size) __MALLOC_DEPRECATED;
> -
> -/* Default value of `__morecore'.  */
> -extern void *__default_morecore (ptrdiff_t __size)
> -__THROW __attribute_malloc__  __MALLOC_DEPRECATED;

OK.

> -
>  /* SVID2/XPG mallinfo structure */
>  
>  struct mallinfo
> diff --git a/malloc/morecore.c b/malloc/morecore.c
> index 047228779b..8168ef158c 100644
> --- a/malloc/morecore.c
> +++ b/malloc/morecore.c
> @@ -15,39 +15,27 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#ifndef _MALLOC_INTERNAL
> -# define _MALLOC_INTERNAL
> -# include <malloc.h>
> -#endif
> -
> -#ifndef __GNU_LIBRARY__
> -# define __sbrk  sbrk
> -#endif
> -
> -#ifdef __GNU_LIBRARY__
> -/* It is best not to declare this and cast its result on foreign operating
> -   systems with potentially hostile include files.  */
> -
> -# include <stddef.h>
> -# include <stdlib.h>
> -extern void *__sbrk (ptrdiff_t increment) __THROW;
> -libc_hidden_proto (__sbrk)
> -#endif
> -
> -#ifndef NULL
> -# define NULL 0

OK.

> +#if defined(SHARED) || defined(USE_MTAG)
> +static bool __always_fail_morecore = false;
>  #endif
>  
>  /* Allocate INCREMENT more bytes of data space,
>     and return the start of data space, or NULL on errors.
>     If INCREMENT is negative, shrink data space.  */
>  void *
> -__default_morecore (ptrdiff_t increment)
> +__glibc_morecore (ptrdiff_t increment)
>  {
> +#if defined(SHARED) || defined(USE_MTAG)
> +  if (__always_fail_morecore)
> +    return NULL;
> +#endif

OK.

> +
>    void *result = (void *) __sbrk (increment);
>    if (result == (void *) -1)
>      return NULL;
>  
>    return result;
>  }
> -libc_hidden_def (__default_morecore)
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
> +compat_symbol (libc, __glibc_morecore, __default_morecore, GLIBC_2_0);

OK. Use a new name and create a versioned compat symbol for __default_morecore
in case someone calls it.

> +#endif
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 04/10] Move malloc hooks into a compat DSO
  2021-07-13  7:38 ` [PATCH v8 04/10] Move malloc hooks into a compat DSO Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Remove all malloc hook uses from core malloc functions and move it
> into a new library libc_malloc_debug.so.  With this, the hooks now no
> longer have any effect on the core library.
> 
> libc_malloc_debug.so is a malloc interposer that needs to be preloaded
> to get hooks functionality back so that the debugging features that
> depend on the hooks, i.e. malloc-check, mcheck and mtrace work again.
> Without the preloaded DSO these debugging features will be nops.
> These features will be ported away from hooks in subsequent patches.
> 
> Similarly, legacy applications that need hooks functionality need to
> preload libc_malloc_debug.so.
> 
> The symbols exported by libc_malloc_debug.so are maintained at exactly
> the same version as libc.so.
> 
> Finally, static binaries will no longer be able to use malloc
> debugging features since they cannot preload the debugging DSO.

It is OK that static binaries can no longer use malloc debugging, they
can use other tooling, we do not have to make all the features available
to static binaries (where we have deprecated dlopen). It is easy enough
to use valgrind today on a static binary.

This needs a v9, we must interpose reallocarray since it has no guarantees
that it actually calls realloc and could be interposed by a subsequent
library and pointers returned from it must be compatible with free.

Tested without regression on x86_64 and i686.

Tested-by: Carlos O'Donell <carlos@redhat.com>


> ---
>  NEWS                                          |   6 +
>  Rules                                         |   9 +-
>  catgets/Makefile                              |   4 +-
>  elf/Makefile                                  |  15 +-
>  elf/tst-leaks1-static.c                       |   1 -
>  iconvdata/Makefile                            |   3 +-
>  intl/tst-gettext.sh                           |   1 +
>  libio/Makefile                                |  12 +-
>  localedata/Makefile                           |   3 +-
>  malloc/Makefile                               |  45 +++--
>  malloc/Versions                               |  20 ++
>  malloc/arena.c                                |   7 -
>  malloc/hooks.c                                |  64 +++++-
>  malloc/malloc-debug.c                         | 189 ++++++++++++++++++
>  malloc/malloc.c                               |  85 ++------
>  malloc/mcheck.c                               |   1 +
>  malloc/mtrace.c                               |   1 +
>  malloc/tst-compathooks-off.c                  | 145 ++++++++++++++
>  malloc/tst-compathooks-on.c                   |   2 +
>  malloc/tst-malloc-usable-static-tunables.c    |   1 -
>  malloc/tst-malloc-usable-static.c             |   1 -
>  malloc/tst-mtrace.sh                          |   1 +
>  manual/memory.texi                            |  16 +-
>  manual/tunables.texi                          |   4 +-
>  misc/Makefile                                 |   6 +-
>  nptl/Makefile                                 |   3 +-
>  posix/Makefile                                |  40 ++--
>  resolv/Makefile                               |   9 +-
>  shlib-versions                                |   3 +
>  stdio-common/Makefile                         |  15 +-
>  sysdeps/generic/libc_malloc_debug.abilist     |   0
>  sysdeps/mach/hurd/Makefile                    |   1 +
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |   9 +
>  sysdeps/pthread/Makefile                      |   3 +-
>  .../linux/aarch64/libc_malloc_debug.abilist   |   9 +
>  .../linux/alpha/libc_malloc_debug.abilist     |   9 +
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |   9 +
>  .../linux/arm/be/libc_malloc_debug.abilist    |   9 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |   9 +
>  .../sysv/linux/csky/libc_malloc_debug.abilist |   9 +
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |   9 +
>  sysdeps/unix/sysv/linux/hppa/shlib-versions   |   2 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |   9 +
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |   9 +
>  sysdeps/unix/sysv/linux/ia64/shlib-versions   |   2 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |   9 +
>  .../m68k/m680x0/libc_malloc_debug.abilist     |   9 +
>  .../microblaze/be/libc_malloc_debug.abilist   |   9 +
>  .../microblaze/le/libc_malloc_debug.abilist   |   9 +
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |   9 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |   9 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |   9 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |   9 +
>  sysdeps/unix/sysv/linux/mips/shlib-versions   |   2 +
>  .../linux/nios2/libc_malloc_debug.abilist     |   9 +
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |   9 +
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |   9 +
>  .../powerpc64/be/libc_malloc_debug.abilist    |   9 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |   9 +
>  .../riscv/rv32/libc_malloc_debug.abilist      |   9 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |   9 +
>  .../s390/s390-32/libc_malloc_debug.abilist    |   9 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |   9 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |   9 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |   9 +
>  sysdeps/unix/sysv/linux/sh/shlib-versions     |   1 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |   9 +
>  .../sparc/sparc64/libc_malloc_debug.abilist   |   9 +
>  .../sysv/linux/sparc/sparc64/shlib-versions   |   1 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |   9 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |   9 +
>  71 files changed, 864 insertions(+), 157 deletions(-)
>  delete mode 100644 elf/tst-leaks1-static.c
>  create mode 100644 malloc/malloc-debug.c
>  create mode 100644 malloc/tst-compathooks-off.c
>  create mode 100644 malloc/tst-compathooks-on.c
>  delete mode 100644 malloc/tst-malloc-usable-static-tunables.c
>  delete mode 100644 malloc/tst-malloc-usable-static.c
>  create mode 100644 sysdeps/generic/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
> 
> diff --git a/NEWS b/NEWS
> index 18d9e65eb2..0297d14f87 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -118,6 +118,12 @@ Deprecated and removed features, and other changes affecting compatibility:
>    applications will continue to link against these symbols but the interfaces
>    no longer have any effect on malloc.
>  
> +* Debugging features in malloc such as the MALLOC_CHECK_ environment variable
> +  (or the glibc.malloc.check tunable), mtrace() and mcheck() have now been
> +  disabled by default in the main C library.  Users looking to use these
> +  features now need to preload a new debugging DSO libc_malloc_debug.so to get
> +  this functionality back.

OK.

> +
>  Changes to build and runtime requirements:
>  
>  * On Linux, the shm_open, sem_open, and related functions now expect the
> diff --git a/Rules b/Rules
> index ba13598df6..b1137afe71 100644
> --- a/Rules
> +++ b/Rules
> @@ -279,10 +279,17 @@ endif
>  
>  # All malloc-check tests will be run with MALLOC_CHECK_=3
>  define malloc-check-ENVS
> -$(1)-malloc-check-ENV = MALLOC_CHECK_=3
> +$(1)-malloc-check-ENV = MALLOC_CHECK_=3 \
> +			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK. Exactly what I expected to support this. Good.

>  endef
>  $(foreach t,$(tests-malloc-check),$(eval $(call malloc-check-ENVS,$(t))))
>  
> +# mcheck tests need the debug DSO to support -lmcheck.
> +define mcheck-ENVS
> +$(1)-mcheck-ENV = LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
> +endef
> +$(foreach t,$(tests-mcheck),$(eval $(call mcheck-ENVS,$(t))))

OK.

> +
>  ifneq "$(strip $(tests) $(tests-internal) $(xtests) $(test-srcs))" ""
>  # These are the implicit rules for making test outputs
>  # from the test programs and whatever input files are present.
> diff --git a/catgets/Makefile b/catgets/Makefile
> index 54da9a985f..215965b352 100644
> --- a/catgets/Makefile
> +++ b/catgets/Makefile
> @@ -56,7 +56,9 @@ generated += tst-catgets.mtrace tst-catgets-mem.out
>  
>  generated-dirs += de
>  
> -tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace
> +tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de \
> +		  MALLOC_TRACE=$(objpfx)tst-catgets.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  ifeq ($(run-built-tests),yes)
>  # This test just checks whether the program produces any error or not.
> diff --git a/elf/Makefile b/elf/Makefile
> index 4b320e8b3a..66195ea419 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -156,7 +156,7 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force)
>  	$(do-install-program)
>  endif
>  
> -tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
> +tests-static-normal := tst-array1-static tst-array5-static \

OK. Dropped tst-leaks1-static because we don't support testing this in static
binaries anymore.

>  	       tst-dl-iter-static \
>  	       tst-tlsalign-static tst-tlsalign-extern-static \
>  	       tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
> @@ -242,7 +242,7 @@ endif
>  tests += $(tests-execstack-$(have-z-execstack))
>  ifeq ($(run-built-tests),yes)
>  tests-special += $(objpfx)tst-leaks1-mem.out \
> -		 $(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
> +		 $(objpfx)noload-mem.out \

OK. Removed tst-leaks1-mem.out.

>  		 $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
>  endif
>  tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
> @@ -895,7 +895,8 @@ $(objpfx)noload.out: $(objpfx)testobj5.so
>  $(objpfx)noload-mem.out: $(objpfx)noload.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)noload.mtrace > $@; \
>  	$(evaluate-test)
> -noload-ENV = MALLOC_TRACE=$(objpfx)noload.mtrace
> +noload-ENV = MALLOC_TRACE=$(objpfx)noload.mtrace \
> +	     LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  LDFLAGS-nodelete = -rdynamic
>  LDFLAGS-nodelmod1.so = -Wl,--enable-new-dtags,-z,nodelete
> @@ -1273,12 +1274,8 @@ $(objpfx)tst-leaks1-mem.out: $(objpfx)tst-leaks1.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@; \
>  	$(evaluate-test)
>  
> -$(objpfx)tst-leaks1-static-mem.out: $(objpfx)tst-leaks1-static.out
> -	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1-static.mtrace > $@; \
> -	$(evaluate-test)
> -
> -tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
> -tst-leaks1-static-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1-static.mtrace
> +tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)tst-thrlock: $(shared-thread-library)
>  $(objpfx)tst-thrlock.out: $(libm)
> diff --git a/elf/tst-leaks1-static.c b/elf/tst-leaks1-static.c
> deleted file mode 100644
> index b956d66905..0000000000
> --- a/elf/tst-leaks1-static.c
> +++ /dev/null
> @@ -1 +0,0 @@
> -#include "tst-leaks1.c"

OK.

> diff --git a/iconvdata/Makefile b/iconvdata/Makefile
> index bb3f621b49..c216f959df 100644
> --- a/iconvdata/Makefile
> +++ b/iconvdata/Makefile
> @@ -301,7 +301,8 @@ cpp-srcs-left := $(modules) $(generated-modules) $(libJIS-routines) \
>  lib := iconvdata
>  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
>  
> -tst-loading-ENV = MALLOC_TRACE=$(objpfx)tst-loading.mtrace
> +tst-loading-ENV = MALLOC_TRACE=$(objpfx)tst-loading.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)mtrace-tst-loading.out: $(objpfx)tst-loading.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-loading.mtrace > $@; \
>  	$(evaluate-test)
> diff --git a/intl/tst-gettext.sh b/intl/tst-gettext.sh
> index 77864de18c..37d9fcb80a 100755
> --- a/intl/tst-gettext.sh
> +++ b/intl/tst-gettext.sh
> @@ -50,6 +50,7 @@ msgfmt -o ${objpfx}domaindir/existing-locale/LC_TIME/existing-time-domain.mo \
>  ${test_program_prefix_before_env} \
>  ${run_program_env} \
>  MALLOC_TRACE=$malloc_trace \
> +LD_PRELOAD=${common_objpfx}malloc/libc_malloc_debug.so \

OK.

>  LOCPATH=${objpfx}localedir:${common_objpfx}localedata \
>  ${test_program_prefix_after_env} \
>  ${objpfx}tst-gettext > ${objpfx}tst-gettext.out ${objpfx}domaindir
> diff --git a/libio/Makefile b/libio/Makefile
> index 73f731e064..5336b7d595 100644
> --- a/libio/Makefile
> +++ b/libio/Makefile
> @@ -165,10 +165,14 @@ LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
>  
>  tst_wprintf2-ARGS = "Some Text"
>  
> -test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
> -tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
> -tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
> -tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
> +test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace \
> +		    LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
> +tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace \
> +		   LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
> +tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
> +tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  generated += test-fmemopen.mtrace test-fmemopen.check
>  generated += tst-fopenloc.mtrace tst-fopenloc.check
> diff --git a/localedata/Makefile b/localedata/Makefile
> index 14e04cd3c5..f585e0dd41 100644
> --- a/localedata/Makefile
> +++ b/localedata/Makefile
> @@ -456,7 +456,8 @@ $(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir
>  tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
>  tst-wctype-ENV = LC_ALL=ja_JP.EUC-JP
>  
> -tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
> +tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
> +		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@; \
>  	$(evaluate-test)
> diff --git a/malloc/Makefile b/malloc/Makefile
> index 020f781b59..7ea45d2358 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -46,12 +46,11 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
>  
>  tests-static := \
>  	 tst-interpose-static-nothread \
> -	 tst-interpose-static-thread \
> -	 tst-malloc-usable-static \
> +	 tst-interpose-static-thread

OK.

>  
>  # Test for the malloc_set_state symbol removed in glibc 2.25.
>  ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)
> -tests += tst-mallocstate
> +tests += tst-mallocstate tst-compathooks-off tst-compathooks-on

OK.

>  endif
>  
>  tests-internal := tst-scratch_buffer
> @@ -64,7 +63,6 @@ tests-internal += \
>  
>  ifneq (no,$(have-tunables))
>  tests += tst-malloc-usable-tunables tst-mxfast
> -tests-static += tst-malloc-usable-static-tunables

OK.

>  endif
>  
>  tests += $(tests-static)
> @@ -73,7 +71,8 @@ test-srcs = tst-mtrace
>  # These tests either are run with MALLOC_CHECK_=3 by default or do not work
>  # with MALLOC_CHECK_=3 because they expect a specific failure.
>  tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \
> -	tst-mxfast tst-safe-linking
> +	tst-mxfast tst-safe-linking \
> +	tst-compathooks-off tst-compathooks-on

OK.

>  
>  # Run all tests with MALLOC_CHECK_=3
>  tests-malloc-check = $(filter-out $(tests-exclude-malloc-check),$(tests))
> @@ -91,15 +90,14 @@ tests-exclude-mcheck = tst-mallocstate \
>  	tst-malloc-tcache-leak \
>  	tst-malloc-thread-exit \
>  	tst-malloc-thread-fail \
> -	tst-malloc-usable-static \
> -	tst-malloc-usable-static-tunables \

OK.

>  	tst-malloc-usable-tunables \
>  	tst-malloc_info \
>  	tst-memalign \
>  	tst-posix_memalign \
>  	tst-realloc \
>  	tst-pvalloc-fortify \
> -	tst-reallocarray
> +	tst-reallocarray \
> +	tst-compathooks-off tst-compathooks-on

OK.

>  
>  tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
>  endif
> @@ -122,8 +120,8 @@ routines = malloc mcheck mtrace obstack reallocarray \
>  install-lib := libmcheck.a
>  non-lib.a := libmcheck.a
>  
> -# Additional library.
> -extra-libs = libmemusage
> +# Additional libraries.
> +extra-libs = libmemusage libc_malloc_debug

OK.

>  extra-libs-others = $(extra-libs)
>  
>  # Helper objects for some tests.
> @@ -138,6 +136,9 @@ test-extras = \
>  libmemusage-routines = memusage
>  libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
>  
> +libc_malloc_debug-routines = malloc-debug
> +libc_malloc_debug-inhibit-o = $(filter-out .os,$(object-suffixes))

OK.

> +
>  $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
>  $(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
>  $(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
> @@ -243,11 +244,12 @@ endif
>  endif
>  endif
>  
> -tst-malloc-check-ENV = MALLOC_CHECK_=3
> -tst-malloc-usable-ENV = MALLOC_CHECK_=3
> -tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV)
> -tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3
> -tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV)
> +tst-malloc-check-ENV = MALLOC_CHECK_=3 \
> +		       LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
> +tst-malloc-usable-ENV = MALLOC_CHECK_=3 \
> +		       LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
> +tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
> +				 LD_PRELOAD=$(objpfx)/libc_malloc_debug.so

OK.

>  
>  tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
>  
> @@ -302,12 +304,14 @@ $(objpfx)tst-interpose-static-thread-mcheck: \
>  $(objpfx)tst-interpose-static-thread-malloc-check: \
>    $(objpfx)tst-interpose-aux-thread.o $(static-thread-library)
>  
> -tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace
> +tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace \
> +		   LD_PRELOAD=$(objpfx)libc_malloc_debug.so
>  $(objpfx)tst-dynarray-mem.out: $(objpfx)tst-dynarray.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
> +tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace \
> +			LD_PRELOAD=$(objpfx)libc_malloc_debug.so
>  $(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@; \
>  	$(evaluate-test)
> @@ -321,3 +325,10 @@ $(objpfx)tst-mallocfork2-mcheck: $(shared-thread-library)
>  $(objpfx)tst-malloc-tcache-leak-malloc-check: $(shared-thread-library)
>  $(objpfx)tst-malloc_info-malloc-check: $(shared-thread-library)
>  $(objpfx)tst-mallocfork2-malloc-check: $(shared-thread-library)
> +
> +tst-compathooks-on-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
> +tst-compathooks-on-mcheck-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
> +tst-compathooks-on-malloc-check-ENV = \
> +	LD_PRELOAD=$(objpfx)libc_malloc_debug.so
> +tst-mallocstate-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
> +tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so

OK.

> diff --git a/malloc/Versions b/malloc/Versions
> index 470a940666..c87f6df8ca 100644
> --- a/malloc/Versions
> +++ b/malloc/Versions
> @@ -98,3 +98,23 @@ libc {
>      __libc_alloc_buffer_create_failure;
>    }
>  }
> +
> +# Keep in sync with symbols in libc.
> +libc_malloc_debug {
> +  GLIBC_2.0 {
> +    calloc;
> +    free;
> +    malloc;
> +    memalign;
> +    pvalloc;
> +    realloc;
> +    valloc;

Need reallocarray.

> +
> +  }
> +  GLIBC_2.2 {
> +    posix_memalign;
> +  }
> +  GLIBC_2.16 {
> +    aligned_alloc;
> +  }
> +}

OK.

> diff --git a/malloc/arena.c b/malloc/arena.c
> index f1693ed48f..9111b49589 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -404,13 +404,6 @@ ptmalloc_init (void)
>    if (s && s[0] != '\0' && s[0] != '0')
>      __malloc_check_init ();
>  #endif
> -
> -#if HAVE_MALLOC_INIT_HOOK
> -  void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
> -  if (hook != NULL)
> -    (*hook)();
> -#endif
> -  __malloc_initialized = 1;

OK. Good, remove the hook.

>  }
>  
>  /* Managing heaps and arenas (for concurrent threads) */
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index 4aa6dadcff..3cd44eeb84 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -1,4 +1,4 @@
> -/* Malloc implementation for multiple threads without lock contention.
> +/* Compatibility code for malloc debugging and state management.
>     Copyright (C) 2001-2021 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>     Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
> @@ -17,6 +17,16 @@
>     License along with the GNU C Library; see the file COPYING.LIB.  If
>     not, see <https://www.gnu.org/licenses/>.  */
>  
> +#ifndef weak_variable
> +# define weak_variable weak_function
> +#endif
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_24)
> +void (*__malloc_initialize_hook) (void);
> +compat_symbol (libc, __malloc_initialize_hook,
> +	       __malloc_initialize_hook, GLIBC_2_0);
> +#endif
> +

OK.

>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
>  void weak_variable (*__after_morecore_hook) (void) = NULL;
>  compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
> @@ -24,32 +34,64 @@ 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;
> +

OK.

>  /* Hooks for debugging versions.  The initial hooks just call the
>     initialization routine, then do the normal work. */
>  
> -static void *
> -malloc_hook_ini (size_t sz, const void *caller)
> +/* 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 ();
> -  return __libc_malloc (sz);
> +
> +#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;

OK.

> +}
> +
> +static void *
> +malloc_hook_ini (size_t sz, const void *caller)
> +{
> +  generic_hook_ini ();
> +  return malloc (sz);

OK.

>  }
>  
>  static void *
>  realloc_hook_ini (void *ptr, size_t sz, const void *caller)
>  {
> -  __malloc_hook = NULL;
> -  __realloc_hook = NULL;
> -  ptmalloc_init ();
> -  return __libc_realloc (ptr, sz);
> +  generic_hook_ini ();
> +  return realloc (ptr, sz);

OK.

>  }
>  
>  static void *
>  memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
>  {
> -  __memalign_hook = NULL;
> -  ptmalloc_init ();
> -  return __libc_memalign (alignment, sz);
> +  generic_hook_ini ();
> +  return memalign (alignment, sz);

OK.

>  }
>  
>  #include "malloc-check.c"
> diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
> new file mode 100644
> index 0000000000..41dfcd3369
> --- /dev/null
> +++ b/malloc/malloc-debug.c
> @@ -0,0 +1,189 @@
> +/* Malloc debug DSO.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; see the file COPYING.LIB.  If
> +   not, see <https://www.gnu.org/licenses/>.  */
> +
> +#include <atomic.h>
> +#include <libc-symbols.h>
> +#include <shlib-compat.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <sys/param.h>
> +
> +/* Support only the glibc allocators.  */
> +extern void *__libc_malloc (size_t);
> +extern void __libc_free (void *);
> +extern void *__libc_realloc (void *, size_t);
> +extern void *__libc_memalign (size_t, size_t);
> +extern void *__libc_valloc (size_t);
> +extern void *__libc_pvalloc (size_t);
> +extern void *__libc_calloc (size_t, size_t);

OK. Using existing public symbols without interposition.

> +
> +#define DEBUG_FN(fn) \
> +  static __typeof (__libc_ ## fn) __debug_ ## fn
> +
> +DEBUG_FN(malloc);
> +DEBUG_FN(free);
> +DEBUG_FN(realloc);
> +DEBUG_FN(memalign);
> +DEBUG_FN(valloc);
> +DEBUG_FN(pvalloc);
> +DEBUG_FN(calloc);

OK.

> +
> +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 size_t pagesize;
> +
> +/* The allocator functions.  */
> +
> +static void *
> +__debug_malloc (size_t bytes)
> +{
> +  void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
> +  if (__builtin_expect (hook != NULL, 0))
> +    return (*hook)(bytes, RETURN_ADDRESS (0));
> +
> +  return __libc_malloc (bytes);
> +}
> +strong_alias (__debug_malloc, malloc)

OK.

> +
> +static void
> +__debug_free (void *mem)
> +{
> +  void (*hook) (void *, const void *) = atomic_forced_read (__free_hook);
> +  if (__builtin_expect (hook != NULL, 0))
> +    {
> +      (*hook)(mem, RETURN_ADDRESS (0));
> +      return;
> +    }
> +  __libc_free (mem);
> +}
> +strong_alias (__debug_free, free)

OK.

> +
> +static void *
> +__debug_realloc (void *oldmem, size_t bytes)
> +{
> +  void *(*hook) (void *, size_t, const void *) =
> +    atomic_forced_read (__realloc_hook);
> +  if (__builtin_expect (hook != NULL, 0))
> +    return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
> +
> +  return __libc_realloc (oldmem, bytes);
> +}
> +strong_alias (__debug_realloc, realloc)

OK.

> +
> +static void *
> +_debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
> +{
> +  void *(*hook) (size_t, size_t, const void *) =
> +    atomic_forced_read (__memalign_hook);
> +  if (__builtin_expect (hook != NULL, 0))
> +    return (*hook)(alignment, bytes, address);
> +
> +  return __libc_memalign (alignment, bytes);
> +}

OK.

> +
> +static void *
> +__debug_memalign (size_t alignment, size_t bytes)
> +{
> +  return _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
> +}
> +strong_alias (__debug_memalign, memalign)
> +strong_alias (__debug_memalign, aligned_alloc)

OK.

> +
> +static void *
> +__debug_pvalloc (size_t bytes)
> +{
> +  size_t rounded_bytes;
> +
> +  if (!pagesize)
> +    pagesize = sysconf (_SC_PAGESIZE);
> +
> +  /* ALIGN_UP with overflow check.  */
> +  if (__glibc_unlikely (__builtin_add_overflow (bytes,
> +						pagesize - 1,
> +						&rounded_bytes)))
> +    {
> +      errno = ENOMEM;
> +      return NULL;
> +    }
> +  rounded_bytes = rounded_bytes & -(pagesize - 1);
> +
> +  return _debug_mid_memalign (pagesize, rounded_bytes, RETURN_ADDRESS (0));
> +}
> +strong_alias (__debug_pvalloc, pvalloc)

OK.

> +
> +static void *
> +__debug_valloc (size_t bytes)
> +{
> +  if (!pagesize)
> +    pagesize = sysconf (_SC_PAGESIZE);
> +
> +  return _debug_mid_memalign (pagesize, bytes, RETURN_ADDRESS (0));
> +}
> +strong_alias (__debug_valloc, valloc)

OK.

> +
> +static int
> +__debug_posix_memalign (void **memptr, size_t alignment, size_t bytes)
> +{
> +  /* Test whether the SIZE argument is valid.  It must be a power of
> +     two multiple of sizeof (void *).  */
> +  if (alignment % sizeof (void *) != 0
> +      || !powerof2 (alignment / sizeof (void *))
> +      || alignment == 0)
> +    return EINVAL;
> +
> +  *memptr = _debug_mid_memalign (alignment, bytes, RETURN_ADDRESS (0));
> +
> +  if (*memptr == NULL)
> +    return ENOMEM;
> +
> +  return 0;
> +}
> +strong_alias (__debug_posix_memalign, posix_memalign)

OK.

> +
> +static void *
> +__debug_calloc (size_t nmemb, size_t size)
> +{
> +  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)
> +	memset (mem, 0, bytes);
> +
> +      return mem;
> +    }
> +
> +  return __libc_calloc (nmemb, size);
> +}

OK.

> +strong_alias (__debug_calloc, calloc)
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 6e8fa9e424..cf71314b2b 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -573,16 +573,6 @@ tag_at (void *ptr)
>  #define HAVE_MREMAP 0
>  #endif
>  
> -/* We may need to support __malloc_initialize_hook for backwards
> -   compatibility.  */
> -
> -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_24)
> -# define HAVE_MALLOC_INIT_HOOK 1
> -#else
> -# define HAVE_MALLOC_INIT_HOOK 0
> -#endif
> -
> -
>  /*
>    This version of malloc supports the standard SVID/XPG mallinfo
>    routine that returns a struct containing usage properties and
> @@ -2008,38 +1998,6 @@ static void     malloc_consolidate (mstate);
>  
>  /* -------------- Early definitions for debugging hooks ---------------- */
>  
> -/* Define and initialize the hook variables.  These weak definitions must
> -   appear before any use of the variables in a function (arena.c uses one).  */
> -#ifndef weak_variable
> -/* In GNU libc we want the hook variables to be weak definitions to
> -   avoid a problem with Emacs.  */
> -# define weak_variable weak_function
> -#endif
> -
> -/* Forward declarations.  */
> -static void *malloc_hook_ini (size_t sz,
> -                              const void *caller) __THROW;
> -static void *realloc_hook_ini (void *ptr, size_t sz,
> -                               const void *caller) __THROW;
> -static void *memalign_hook_ini (size_t alignment, size_t sz,
> -                                const void *caller) __THROW;
> -
> -#if HAVE_MALLOC_INIT_HOOK
> -void (*__malloc_initialize_hook) (void);
> -compat_symbol (libc, __malloc_initialize_hook,
> -	       __malloc_initialize_hook, GLIBC_2_0);
> -#endif
> -
> -void weak_variable (*__free_hook) (void *__ptr,
> -                                   const void *) = NULL;
> -void *weak_variable (*__malloc_hook)
> -  (size_t __size, const void *) = malloc_hook_ini;
> -void *weak_variable (*__realloc_hook)
> -  (void *__ptr, size_t __size, const void *)
> -  = realloc_hook_ini;
> -void *weak_variable (*__memalign_hook)
> -  (size_t __alignment, size_t __size, const void *)
> -  = memalign_hook_ini;
>  /* This function is called from the arena shutdown hook, to free the
>     thread cache (if it exists).  */
>  static void tcache_thread_shutdown (void);
> @@ -3237,10 +3195,8 @@ __libc_malloc (size_t bytes)
>    _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
>                    "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))
> -    return (*hook)(bytes, RETURN_ADDRESS (0));
> +  if (__malloc_initialized < 0)
> +    ptmalloc_init ();
>  #if USE_TCACHE
>    /* int_free also calls request2size, be careful to not pad twice.  */
>    size_t tbytes;
> @@ -3301,14 +3257,6 @@ __libc_free (void *mem)
>    mstate ar_ptr;
>    mchunkptr p;                          /* chunk corresponding to mem */
>  
> -  void (*hook) (void *, const void *)
> -    = atomic_forced_read (__free_hook);
> -  if (__builtin_expect (hook != NULL, 0))
> -    {
> -      (*hook)(mem, RETURN_ADDRESS (0));
> -      return;
> -    }
> -
>    if (mem == 0)                              /* free(0) has no effect */
>      return;
>  
> @@ -3360,10 +3308,8 @@ __libc_realloc (void *oldmem, size_t bytes)
>  
>    void *newp;             /* chunk to return */
>  
> -  void *(*hook) (void *, size_t, const void *) =
> -    atomic_forced_read (__realloc_hook);
> -  if (__builtin_expect (hook != NULL, 0))
> -    return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
> +  if (__malloc_initialized < 0)
> +    ptmalloc_init ();
>  
>  #if REALLOC_ZERO_BYTES_FREES
>    if (bytes == 0 && oldmem != NULL)
> @@ -3498,6 +3444,9 @@ libc_hidden_def (__libc_realloc)
>  void *
>  __libc_memalign (size_t alignment, size_t bytes)
>  {
> +  if (__malloc_initialized < 0)
> +    ptmalloc_init ();
> +
>    void *address = RETURN_ADDRESS (0);
>    return _mid_memalign (alignment, bytes, address);
>  }
> @@ -3508,11 +3457,6 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
>    mstate ar_ptr;
>    void *p;
>  
> -  void *(*hook) (size_t, size_t, const void *) =
> -    atomic_forced_read (__memalign_hook);
> -  if (__builtin_expect (hook != NULL, 0))
> -    return (*hook)(alignment, bytes, address);
> -
>    /* If we need less alignment than we give anyway, just relay to malloc.  */
>    if (alignment <= MALLOC_ALIGNMENT)
>      return __libc_malloc (bytes);
> @@ -3621,16 +3565,8 @@ __libc_calloc (size_t n, size_t elem_size)
>  
>    sz = bytes;
>  
> -  void *(*hook) (size_t, const void *) =
> -    atomic_forced_read (__malloc_hook);
> -  if (__builtin_expect (hook != NULL, 0))
> -    {
> -      mem = (*hook)(sz, RETURN_ADDRESS (0));
> -      if (mem == 0)
> -        return 0;
> -
> -      return memset (mem, 0, sz);
> -    }
> +  if (__malloc_initialized < 0)
> +    ptmalloc_init ();
>  
>    MAYBE_INIT_TCACHE ();
>  
> @@ -5659,6 +5595,9 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
>  {
>    void *mem;
>  
> +  if (__malloc_initialized < 0)
> +    ptmalloc_init ();
> +
>    /* Test whether the SIZE argument is valid.  It must be a power of
>       two multiple of sizeof (void *).  */
>    if (alignment % sizeof (void *) != 0
> diff --git a/malloc/mcheck.c b/malloc/mcheck.c
> index d2efcfb742..1e68cedbf5 100644
> --- a/malloc/mcheck.c
> +++ b/malloc/mcheck.c
> @@ -26,6 +26,7 @@
>  # include <stdio.h>
>  # include <libintl.h>
>  # include <errno.h>
> +# include <malloc-internal.h>
>  #endif
>  
>  /* Old hook values.  */
> diff --git a/malloc/mtrace.c b/malloc/mtrace.c
> index 6c2c58b706..fb58413d39 100644
> --- a/malloc/mtrace.c
> +++ b/malloc/mtrace.c
> @@ -22,6 +22,7 @@
>  # define _MALLOC_INTERNAL
>  # include <malloc.h>
>  # include <mcheck.h>
> +# include <malloc-internal.h>
>  # include <libc-lock.h>
>  #endif
>  
> diff --git a/malloc/tst-compathooks-off.c b/malloc/tst-compathooks-off.c
> new file mode 100644
> index 0000000000..7b3722d8b3
> --- /dev/null
> +++ b/malloc/tst-compathooks-off.c
> @@ -0,0 +1,145 @@
> +/* Minimal tests to verify libc_malloc_debug.so functionality.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <malloc.h>
> +#include <shlib-compat.h>
> +#include <libc-diag.h>
> +
> +#include <support/check.h>
> +#include <support/support.h>
> +
> +extern void (*volatile __free_hook) (void *, const void *);
> +extern void *(*volatile __malloc_hook)(size_t, const void *);
> +extern void *(*volatile __realloc_hook)(void *, size_t, const void *);
> +extern void *(*volatile __memalign_hook)(size_t, size_t, const void *);
> +
> +int hook_count, call_count;
> +
> +DIAG_PUSH_NEEDS_COMMENT;
> +DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
> +
> +void
> +free_called (void *mem, const void *address)
> +{
> +  hook_count++;
> +  __free_hook = NULL;
> +  free (mem);
> +  __free_hook = free_called;
> +}
> +
> +void *
> +malloc_called (size_t bytes, const void *address)
> +{
> +  hook_count++;
> +  __malloc_hook = NULL;
> +  void *mem = malloc (bytes);
> +  __malloc_hook = malloc_called;
> +  return mem;
> +}
> +
> +void *
> +realloc_called (void *oldptr, size_t bytes, const void *address)
> +{
> +  hook_count++;
> +  __realloc_hook = NULL;
> +  void *mem = realloc (oldptr, bytes);
> +  __realloc_hook = realloc_called;
> +  return mem;
> +}
> +
> +void *
> +calloc_called (size_t n, size_t size, const void *address)
> +{
> +  hook_count++;
> +  __malloc_hook = NULL;
> +  void *mem = calloc (n, size);
> +  __malloc_hook = malloc_called;
> +  return mem;
> +}
> +
> +void *
> +memalign_called (size_t align, size_t size, const void *address)
> +{
> +  hook_count++;
> +  __memalign_hook = NULL;
> +  void *mem = memalign (align, size);
> +  __memalign_hook = memalign_called;
> +  return mem;
> +}
> +
> +static void initialize_hooks (void)
> +{
> +  __free_hook = free_called;
> +  __malloc_hook = malloc_called;
> +  __realloc_hook = realloc_called;
> +  __memalign_hook = memalign_called;
> +}
> +void (*__malloc_initialize_hook) (void) = initialize_hooks;
> +compat_symbol_reference (libc, __malloc_initialize_hook,
> +			 __malloc_initialize_hook, GLIBC_2_0);
> +compat_symbol_reference (libc, __free_hook,
> +			 __free_hook, GLIBC_2_0);
> +compat_symbol_reference (libc, __malloc_hook,
> +			 __malloc_hook, GLIBC_2_0);
> +compat_symbol_reference (libc, __realloc_hook,
> +			 __realloc_hook, GLIBC_2_0);
> +compat_symbol_reference (libc, __memalign_hook,
> +			 __memalign_hook, GLIBC_2_0);

OK. Allows us to link against the hooks and try to use them.

> +
> +DIAG_POP_NEEDS_COMMENT;
> +
> +static int
> +do_test (void)
> +{
> +  void *p;
> +  p = malloc (0);
> +  TEST_VERIFY_EXIT (p != NULL);
> +  call_count++;
> +
> +  p = realloc (p, 0);
> +  TEST_VERIFY_EXIT (p == NULL);
> +  call_count++;
> +
> +  p = calloc (512, 1);
> +  TEST_VERIFY_EXIT (p != NULL);
> +  call_count++;
> +
> +  free (p);
> +  call_count++;
> +
> +  p = memalign (0x100, 0x100);
> +  TEST_VERIFY_EXIT (p != NULL);
> +  call_count++;
> +
> +  free (p);
> +  call_count++;
> +
> +  printf ("call_count: %d, hook_count: %d\n", call_count, hook_count);
> +
> +#ifdef HOOKS_ENABLED
> +  TEST_VERIFY_EXIT (call_count == hook_count);
> +#else
> +  TEST_VERIFY_EXIT (hook_count == 0);
> +#endif
> +
> +  exit (0);
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/malloc/tst-compathooks-on.c b/malloc/tst-compathooks-on.c
> new file mode 100644
> index 0000000000..4da183687a
> --- /dev/null
> +++ b/malloc/tst-compathooks-on.c
> @@ -0,0 +1,2 @@
> +#define HOOKS_ENABLED 1
> +#include "tst-compathooks-off.c"
> diff --git a/malloc/tst-malloc-usable-static-tunables.c b/malloc/tst-malloc-usable-static-tunables.c
> deleted file mode 100644
> index 8907db01a5..0000000000
> --- a/malloc/tst-malloc-usable-static-tunables.c
> +++ /dev/null
> @@ -1 +0,0 @@
> -#include <malloc/tst-malloc-usable.c>
> diff --git a/malloc/tst-malloc-usable-static.c b/malloc/tst-malloc-usable-static.c
> deleted file mode 100644
> index 8907db01a5..0000000000
> --- a/malloc/tst-malloc-usable-static.c
> +++ /dev/null
> @@ -1 +0,0 @@
> -#include <malloc/tst-malloc-usable.c>
> diff --git a/malloc/tst-mtrace.sh b/malloc/tst-mtrace.sh
> index 9295683aff..a830204d5e 100755
> --- a/malloc/tst-mtrace.sh
> +++ b/malloc/tst-mtrace.sh
> @@ -30,6 +30,7 @@ trap "rm -f ${common_objpfx}malloc/tst-mtrace.leak; exit 1" 1 2 15
>  ${test_program_prefix_before_env} \
>  ${run_program_env} \
>  MALLOC_TRACE=${common_objpfx}malloc/tst-mtrace.leak \
> +LD_PRELOAD=${common_objpfx}malloc/libc_malloc_debug.so \
>  ${test_program_prefix_after_env} \
>    ${common_objpfx}malloc/tst-mtrace || status=1

OK.

>  
> diff --git a/manual/memory.texi b/manual/memory.texi
> index 31ee36be8c..93305f289b 100644
> --- a/manual/memory.texi
> +++ b/manual/memory.texi
> @@ -1256,8 +1256,9 @@ environment variable @env{MALLOC_ARENA_MAX} to the desired value.
>  @cindex consistency checking, of heap
>  
>  You can ask @code{malloc} to check the consistency of dynamic memory by
> -using the @code{mcheck} function.  This function is a GNU extension,
> -declared in @file{mcheck.h}.
> +using the @code{mcheck} function and preloading the malloc debug library
> +@file{libc_malloc_debug.so} using the @var{LD_PRELOAD} environment variable.
> +This function is a GNU extension, declared in @file{mcheck.h}.

OK.

>  @pindex mcheck.h
>  
>  @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
> @@ -1368,7 +1369,10 @@ non-zero value less than 4, a special (less efficient) implementation is
>  used which is designed to be tolerant against simple errors, such as
>  double calls of @code{free} with the same argument, or overruns of a
>  single byte (off-by-one bugs).  Not all such errors can be protected
> -against, however, and memory leaks can result.
> +against, however, and memory leaks can result.  Like in the case of
> +@code{mcheck}, one would need to preload the @file{libc_malloc_debug.so}
> +library to enable @code{MALLOC_CHECK_} functionality.  Without this
> +preloaded library, setting @code{MALLOC_CHECK_} will have no effect.

OK.

>  
>  Any detected heap corruption results in immediate termination of the
>  process.
> @@ -1747,6 +1751,12 @@ penalties for the program if the debugging mode is not enabled.
>  @c  fprintf dup (on newly-created stream) @aculock
>  @c  __cxa_atexit (once) dup @asulock @aculock @acsmem
>  @c  free dup @ascuheap @acsmem
> +The @code{mtrace} function provides a way to trace memory allocation
> +events in the program that calls it.  It is disabled by default in the
> +library and can be enabled by preloading the debugging library
> +@file{libc_malloc_debug.so} using the @code{LD_PRELOAD} environment
> +variable.

OK.

> +
>  When the @code{mtrace} function is called it looks for an environment
>  variable named @code{MALLOC_TRACE}.  This variable is supposed to
>  contain a valid file name.  The user must have write access.  If the
> diff --git a/manual/tunables.texi b/manual/tunables.texi
> index ebdb562e36..e264e9150c 100644
> --- a/manual/tunables.texi
> +++ b/manual/tunables.texi
> @@ -113,7 +113,9 @@ following tunables in the @code{malloc} namespace:
>  
>  @deftp Tunable glibc.malloc.check
>  This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
> -identical in features.
> +identical in features. This tunable has no effect by default and needs the
> +debug library @file{libc_malloc_debug.so} to be preloaded using the
> +@code{LD_PRELOAD} environment variable.

OK.

>  
>  Setting this tunable to a non-zero value less than 4 enables a special (less
>  efficient) memory allocator for the @code{malloc} family of functions that is
> diff --git a/misc/Makefile b/misc/Makefile
> index ae03e26f1b..b144a3df6c 100644
> --- a/misc/Makefile
> +++ b/misc/Makefile
> @@ -152,13 +152,15 @@ $(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib)
>  
>  $(objpfx)tst-tsearch: $(libm)
>  
> -tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace
> +tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  tst-error1-ARGS = $(objpfx)tst-error1.out
>  $(objpfx)tst-error1-mem.out: $(objpfx)tst-error1.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-error1.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
> +tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace \
> +			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
>  	$(evaluate-test)
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 9b94bfcd31..ff4d590f11 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -494,7 +494,8 @@ CFLAGS-tst-initializers1-gnu11.c += $(CFLAGS-tst-initializers1-<)
>  tst-cancel7-ARGS = --command "exec $(host-test-program-cmd)"
>  tst-cancelx7-ARGS = $(tst-cancel7-ARGS)
>  
> -tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace
> +tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)tst-stack3-mem.out: $(objpfx)tst-stack3.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@; \
>  	$(evaluate-test)
> diff --git a/posix/Makefile b/posix/Makefile
> index d82e43eaad..b895638865 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -313,43 +313,50 @@ annexc-CFLAGS = -O
>  $(objpfx)annexc: annexc.c
>  	$(native-compile)
>  
> -tst-fnmatch-ENV += MALLOC_TRACE=$(objpfx)tst-fnmatch.mtrace
> +tst-fnmatch-ENV += MALLOC_TRACE=$(objpfx)tst-fnmatch.mtrace \
> +		   LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)tst-fnmatch-mem.out: $(objpfx)tst-fnmatch.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-fnmatch.mtrace > $@; \
>  	$(evaluate-test)
>  
> -bug-regex2-ENV = MALLOC_TRACE=$(objpfx)bug-regex2.mtrace
> +bug-regex2-ENV = MALLOC_TRACE=$(objpfx)bug-regex2.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-regex2-mem.out: $(objpfx)bug-regex2.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex2.mtrace > $@; \
>  	$(evaluate-test)
>  
> -bug-regex14-ENV = MALLOC_TRACE=$(objpfx)bug-regex14.mtrace
> +bug-regex14-ENV = MALLOC_TRACE=$(objpfx)bug-regex14.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-regex14-mem.out: $(objpfx)bug-regex14.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex14.mtrace > $@; \
>  	$(evaluate-test)
>  
> -bug-regex21-ENV = MALLOC_TRACE=$(objpfx)bug-regex21.mtrace
> +bug-regex21-ENV = MALLOC_TRACE=$(objpfx)bug-regex21.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-regex21-mem.out: $(objpfx)bug-regex21.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex21.mtrace > $@; \
>  	$(evaluate-test)
>  
> -bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace
> +bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-regex31-mem.out: $(objpfx)bug-regex31.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@; \
>  	$(evaluate-test)
>  
> -bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
> +bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
> +tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)tst-vfork3-mem.out: $(objpfx)tst-vfork3.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-vfork3.mtrace > $@; \
> @@ -358,18 +365,22 @@ $(objpfx)tst-vfork3-mem.out: $(objpfx)tst-vfork3.out
>  # tst-rxspencer.mtrace is not generated, only
>  # tst-rxspencer-no-utf8.mtrace, since otherwise the file has almost
>  # 100M and takes very long time to process.
> -tst-rxspencer-no-utf8-ENV += MALLOC_TRACE=$(objpfx)tst-rxspencer-no-utf8.mtrace
> +tst-rxspencer-no-utf8-ENV += \
> +  MALLOC_TRACE=$(objpfx)tst-rxspencer-no-utf8.mtrace \
> +  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)tst-rxspencer-no-utf8-mem.out: $(objpfx)tst-rxspencer-no-utf8.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-rxspencer-no-utf8.mtrace \
>  				      > $@; \
>  	$(evaluate-test)
>  
> -tst-pcre-ENV = MALLOC_TRACE=$(objpfx)tst-pcre.mtrace
> +tst-pcre-ENV = MALLOC_TRACE=$(objpfx)tst-pcre.mtrace \
> +	       LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)tst-pcre-mem.out: $(objpfx)tst-pcre.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-pcre.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-boost-ENV = MALLOC_TRACE=$(objpfx)tst-boost.mtrace
> +tst-boost-ENV = MALLOC_TRACE=$(objpfx)tst-boost.mtrace \
> +		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
OK.

>  $(objpfx)tst-boost-mem.out: $(objpfx)tst-boost.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-boost.mtrace > $@; \
>  	$(evaluate-test)
> @@ -384,15 +395,18 @@ $(objpfx)bug-ga2-mem.out: $(objpfx)bug-ga2.out
>  	&& $(common-objpfx)malloc/mtrace $(objpfx)bug-ga2.mtrace; } > $@; \
>  	$(evaluate-test)
>  
> -bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace
> +bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace \
> +	      LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so


OK.

>  
> -bug-glob2-ENV = MALLOC_TRACE=$(objpfx)bug-glob2.mtrace
> +bug-glob2-ENV = MALLOC_TRACE=$(objpfx)bug-glob2.mtrace \
> +		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)bug-glob2-mem.out: $(objpfx)bug-glob2.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace
> +tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace \
> +		     LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \
> diff --git a/resolv/Makefile b/resolv/Makefile
> index 1d3565d478..09b2f129eb 100644
> --- a/resolv/Makefile
> +++ b/resolv/Makefile
> @@ -156,19 +156,22 @@ $(objpfx)tst-res_hconf_reorder: $(shared-thread-library)
>  tst-res_hconf_reorder-ENV = RESOLV_REORDER=on
>  
>  $(objpfx)tst-leaks: $(objpfx)libresolv.so
> -tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
> +tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
> +		LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@; \
>  	$(evaluate-test)
>  
> -tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
> +tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace \
> +		 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
>  	{ test -r $(objpfx)tst-leaks2.mtrace \
>  	|| ( echo "tst-leaks2.mtrace does not exist"; exit 77; ) \
>  	&& $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace; } > $@; \
>  	$(evaluate-test)
>  
> -tst-resolv-res_ninit-ENV = MALLOC_TRACE=$(objpfx)tst-resolv-res_ninit.mtrace
> +tst-resolv-res_ninit-ENV = MALLOC_TRACE=$(objpfx)tst-resolv-res_ninit.mtrace \
> +			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)mtrace-tst-resolv-res_ninit.out: $(objpfx)tst-resolv-res_ninit.out
>  	$(common-objpfx)malloc/mtrace \
>  	  $(objpfx)tst-resolv-res_ninit.mtrace > $@; \
> diff --git a/shlib-versions b/shlib-versions
> index edabba08eb..df6603e699 100644
> --- a/shlib-versions
> +++ b/shlib-versions
> @@ -73,3 +73,6 @@ libgcc_s=1
>  
>  # The vector math library
>  libmvec=1
> +
> +# The malloc debug library
> +libc_malloc_debug=0

OK.

> diff --git a/stdio-common/Makefile b/stdio-common/Makefile
> index f87796a8ce..803f16dae0 100644
> --- a/stdio-common/Makefile
> +++ b/stdio-common/Makefile
> @@ -110,15 +110,20 @@ $(objpfx)tst-swprintf.out: $(gen-locales)
>  $(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales)
>  endif
>  
> -tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace
> +tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \
> +			LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
>  tst-vfprintf-width-prec-ENV = \
> -  MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace
> +  MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace \
> +  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
>  tst-printf-bz25691-ENV = \
> -  MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace
> +  MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace \
> +  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
>  tst-printf-fp-free-ENV = \
> -  MALLOC_TRACE=$(objpfx)tst-printf-fp-free.mtrace
> +  MALLOC_TRACE=$(objpfx)tst-printf-fp-free.mtrace \
> +  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
>  tst-printf-fp-leak-ENV = \
> -  MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace
> +  MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \
> +  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  
>  $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
>  	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
> diff --git a/sysdeps/generic/libc_malloc_debug.abilist b/sysdeps/generic/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
> index 46bd7b4600..17bb643c18 100644
> --- a/sysdeps/mach/hurd/Makefile
> +++ b/sysdeps/mach/hurd/Makefile
> @@ -222,5 +222,6 @@ CFLAGS-ypclnt.c += -DUSE_BINDINGDIR=1
>  endif
>  
>  LDLIBS-pthread.so += $(objdir)/hurd/libhurduser.so
> +LDLIBS-c_malloc_debug.so += $(link-rpcuserlibs)

OK.

>  
>  endif	# in-Makerules
> diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..393ef2acd7
> --- /dev/null
> +++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2.6 calloc F
> +GLIBC_2.2.6 free F
> +GLIBC_2.2.6 malloc F
> +GLIBC_2.2.6 memalign F
> +GLIBC_2.2.6 posix_memalign F
> +GLIBC_2.2.6 pvalloc F
> +GLIBC_2.2.6 realloc F
> +GLIBC_2.2.6 valloc F

All the abilists need reallocarray.

> diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
> index 9b862b93c4..42f9fc5072 100644
> --- a/sysdeps/pthread/Makefile
> +++ b/sysdeps/pthread/Makefile
> @@ -211,7 +211,8 @@ tst-umask1-ARGS = $(objpfx)tst-umask1.temp
>  
>  $(objpfx)tst-atfork2: $(shared-thread-library)
>  LDFLAGS-tst-atfork2 = -rdynamic
> -tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
> +tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace \
> +		  LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so

OK.

>  $(objpfx)tst-atfork2mod.so: $(shared-thread-library)
>  
>  ifeq ($(build-shared),yes)
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..2b183c90d4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.17 aligned_alloc F
> +GLIBC_2.17 calloc F
> +GLIBC_2.17 free F
> +GLIBC_2.17 malloc F
> +GLIBC_2.17 memalign F
> +GLIBC_2.17 posix_memalign F
> +GLIBC_2.17 pvalloc F
> +GLIBC_2.17 realloc F
> +GLIBC_2.17 valloc F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..3ec745c9ac
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.32 aligned_alloc F
> +GLIBC_2.32 calloc F
> +GLIBC_2.32 free F
> +GLIBC_2.32 malloc F
> +GLIBC_2.32 memalign F
> +GLIBC_2.32 posix_memalign F
> +GLIBC_2.32 pvalloc F
> +GLIBC_2.32 realloc F
> +GLIBC_2.32 valloc 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
> new file mode 100644
> index 0000000000..f7938d075f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.4 calloc F
> +GLIBC_2.4 free F
> +GLIBC_2.4 malloc F
> +GLIBC_2.4 memalign F
> +GLIBC_2.4 posix_memalign F
> +GLIBC_2.4 pvalloc F
> +GLIBC_2.4 realloc F
> +GLIBC_2.4 valloc 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
> new file mode 100644
> index 0000000000..f7938d075f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.4 calloc F
> +GLIBC_2.4 free F
> +GLIBC_2.4 malloc F
> +GLIBC_2.4 memalign F
> +GLIBC_2.4 posix_memalign F
> +GLIBC_2.4 pvalloc F
> +GLIBC_2.4 realloc F
> +GLIBC_2.4 valloc F
> diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..54da2c3e38
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.29 aligned_alloc F
> +GLIBC_2.29 calloc F
> +GLIBC_2.29 free F
> +GLIBC_2.29 malloc F
> +GLIBC_2.29 memalign F
> +GLIBC_2.29 posix_memalign F
> +GLIBC_2.29 pvalloc F
> +GLIBC_2.29 realloc F
> +GLIBC_2.29 valloc F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc F
> diff --git a/sysdeps/unix/sysv/linux/hppa/shlib-versions b/sysdeps/unix/sysv/linux/hppa/shlib-versions
> index 3a2d496220..7818a32cc4 100644
> --- a/sysdeps/unix/sysv/linux/hppa/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/hppa/shlib-versions
> @@ -7,3 +7,5 @@ ld=ld.so.1		GLIBC_2.2
>  libBrokenLocale=1	GLIBC_2.2
>  
>  libpthread=0		GLIBC_2.2
> +
> +libc_malloc_debug=0	GLIBC_2.2
> diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc F
> diff --git a/sysdeps/unix/sysv/linux/ia64/shlib-versions b/sysdeps/unix/sysv/linux/ia64/shlib-versions
> index 37374c0e20..f57e5bae5e 100644
> --- a/sysdeps/unix/sysv/linux/ia64/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/ia64/shlib-versions
> @@ -6,3 +6,5 @@ ld=ld-linux-ia64.so.2	GLIBC_2.2
>  libBrokenLocale=1	GLIBC_2.2
>  
>  libpthread=0		GLIBC_2.2
> +
> +libc_malloc_debug=0	GLIBC_2.2
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..f7938d075f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.4 calloc F
> +GLIBC_2.4 free F
> +GLIBC_2.4 malloc F
> +GLIBC_2.4 memalign F
> +GLIBC_2.4 posix_memalign F
> +GLIBC_2.4 pvalloc F
> +GLIBC_2.4 realloc F
> +GLIBC_2.4 valloc 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..d02da8ef66
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.18 aligned_alloc F
> +GLIBC_2.18 calloc F
> +GLIBC_2.18 free F
> +GLIBC_2.18 malloc F
> +GLIBC_2.18 memalign F
> +GLIBC_2.18 posix_memalign F
> +GLIBC_2.18 pvalloc F
> +GLIBC_2.18 realloc F
> +GLIBC_2.18 valloc 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
> new file mode 100644
> index 0000000000..d02da8ef66
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.18 aligned_alloc F
> +GLIBC_2.18 calloc F
> +GLIBC_2.18 free F
> +GLIBC_2.18 malloc F
> +GLIBC_2.18 memalign F
> +GLIBC_2.18 posix_memalign F
> +GLIBC_2.18 pvalloc F
> +GLIBC_2.18 realloc F
> +GLIBC_2.18 valloc 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 posix_memalign F
> diff --git a/sysdeps/unix/sysv/linux/mips/shlib-versions b/sysdeps/unix/sysv/linux/mips/shlib-versions
> index ecfe1845f4..c57674deec 100644
> --- a/sysdeps/unix/sysv/linux/mips/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/mips/shlib-versions
> @@ -23,3 +23,5 @@ libnsl=1		GLIBC_2.0 GLIBC_2.2
>  librt=1			GLIBC_2.0 GLIBC_2.2
>  
>  libpthread=0		GLIBC_2.0 GLIBC_2.2
> +
> +libc_malloc_debug=0	GLIBC_2.0 GLIBC_2.2
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..658c965b08
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.21 aligned_alloc F
> +GLIBC_2.21 calloc F
> +GLIBC_2.21 free F
> +GLIBC_2.21 malloc F
> +GLIBC_2.21 memalign F
> +GLIBC_2.21 posix_memalign F
> +GLIBC_2.21 pvalloc F
> +GLIBC_2.21 realloc F
> +GLIBC_2.21 valloc 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..921079580c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.3 calloc F
> +GLIBC_2.3 free F
> +GLIBC_2.3 malloc F
> +GLIBC_2.3 memalign F
> +GLIBC_2.3 posix_memalign F
> +GLIBC_2.3 pvalloc F
> +GLIBC_2.3 realloc F
> +GLIBC_2.3 valloc 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
> new file mode 100644
> index 0000000000..2b183c90d4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.17 aligned_alloc F
> +GLIBC_2.17 calloc F
> +GLIBC_2.17 free F
> +GLIBC_2.17 malloc F
> +GLIBC_2.17 memalign F
> +GLIBC_2.17 posix_memalign F
> +GLIBC_2.17 pvalloc F
> +GLIBC_2.17 realloc F
> +GLIBC_2.17 valloc 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
> new file mode 100644
> index 0000000000..05c8ba8c9f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.33 aligned_alloc F
> +GLIBC_2.33 calloc F
> +GLIBC_2.33 free F
> +GLIBC_2.33 malloc F
> +GLIBC_2.33 memalign F
> +GLIBC_2.33 posix_memalign F
> +GLIBC_2.33 pvalloc F
> +GLIBC_2.33 realloc F
> +GLIBC_2.33 valloc 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
> new file mode 100644
> index 0000000000..20531a7372
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.27 aligned_alloc F
> +GLIBC_2.27 calloc F
> +GLIBC_2.27 free F
> +GLIBC_2.27 malloc F
> +GLIBC_2.27 memalign F
> +GLIBC_2.27 posix_memalign F
> +GLIBC_2.27 pvalloc F
> +GLIBC_2.27 realloc F
> +GLIBC_2.27 valloc 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
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc 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
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc 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
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc F
> diff --git a/sysdeps/unix/sysv/linux/sh/shlib-versions b/sysdeps/unix/sysv/linux/sh/shlib-versions
> index 9333bbd7a3..3124264300 100644
> --- a/sysdeps/unix/sysv/linux/sh/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/sh/shlib-versions
> @@ -3,3 +3,4 @@ libc=6			GLIBC_2.2
>  ld=ld-linux.so.2	GLIBC_2.2
>  libBrokenLocale=1	GLIBC_2.2
>  libpthread=0		GLIBC_2.2
> +libc_malloc_debug=0	GLIBC_2.2
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> new file mode 100644
> index 0000000000..7621d1266e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.0 calloc F
> +GLIBC_2.0 free F
> +GLIBC_2.0 malloc F
> +GLIBC_2.0 memalign 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 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
> new file mode 100644
> index 0000000000..3ea834d9a2
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2 calloc F
> +GLIBC_2.2 free F
> +GLIBC_2.2 malloc F
> +GLIBC_2.2 memalign F
> +GLIBC_2.2 posix_memalign F
> +GLIBC_2.2 pvalloc F
> +GLIBC_2.2 realloc F
> +GLIBC_2.2 valloc F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions b/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
> index 9333bbd7a3..3124264300 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/shlib-versions
> @@ -3,3 +3,4 @@ libc=6			GLIBC_2.2
>  ld=ld-linux.so.2	GLIBC_2.2
>  libBrokenLocale=1	GLIBC_2.2
>  libpthread=0		GLIBC_2.2
> +libc_malloc_debug=0	GLIBC_2.2
> 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
> new file mode 100644
> index 0000000000..723c5f48f0
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.2.5 calloc F
> +GLIBC_2.2.5 free F
> +GLIBC_2.2.5 malloc F
> +GLIBC_2.2.5 memalign F
> +GLIBC_2.2.5 posix_memalign F
> +GLIBC_2.2.5 pvalloc F
> +GLIBC_2.2.5 realloc F
> +GLIBC_2.2.5 valloc 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
> new file mode 100644
> index 0000000000..c506f45101
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc_malloc_debug.abilist
> @@ -0,0 +1,9 @@
> +GLIBC_2.16 aligned_alloc F
> +GLIBC_2.16 calloc F
> +GLIBC_2.16 free F
> +GLIBC_2.16 malloc F
> +GLIBC_2.16 memalign F
> +GLIBC_2.16 posix_memalign F
> +GLIBC_2.16 pvalloc F
> +GLIBC_2.16 realloc F
> +GLIBC_2.16 valloc F
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 05/10] mcheck: Wean away from malloc hooks
  2021-07-13  7:38 ` [PATCH v8 05/10] mcheck: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
  2021-07-13 15:47   ` H.J. Lu via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  1 sibling, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Split the mcheck implementation into the debugging hooks and API so
> that the API can be replicated in libc and libc_malloc_debug.so.  The
> libc APIs always result in failure.
> 
> The mcheck implementation has also been moved entirely into
> libc_malloc_debug.so and with it, all of the hook initialization code
> can now be moved into the debug library.  Now the initialization can
> be done independently of libc internals.
> 
> With this patch, libc_malloc_debug.so can no longer be used with older
> libcs, which is not its goal anyway.  tst-vfork3 breaks due to this
> since it spawns shell scripts, which in turn execute using the system
> glibc.  Move the test to tests-container so that only the built glibc
> is used.
> 
> This move also fixes bugs in the mcheck version of memalign and
> realloc, thus allowing removal of the tests from tests-mcheck
> exclusion list.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>


> ---
>  include/mcheck.h                              |   4 -
>  malloc/Makefile                               |   3 -
>  malloc/Versions                               |   9 +
>  malloc/hooks.c                                |  61 +--
>  malloc/malloc-debug.c                         | 173 +++++++-
>  malloc/mcheck-impl.c                          | 406 ++++++++++++++++++
>  malloc/mcheck.c                               | 398 +----------------
>  posix/Makefile                                |   8 +-
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |   8 +
>  .../linux/aarch64/libc_malloc_debug.abilist   |   8 +
>  .../linux/alpha/libc_malloc_debug.abilist     |   8 +
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |   8 +
>  .../linux/arm/be/libc_malloc_debug.abilist    |   8 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |   8 +
>  .../sysv/linux/csky/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |   8 +
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |   8 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |   8 +
>  .../m68k/m680x0/libc_malloc_debug.abilist     |   8 +
>  .../microblaze/be/libc_malloc_debug.abilist   |   8 +
>  .../microblaze/le/libc_malloc_debug.abilist   |   8 +
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |   8 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |   8 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |   8 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |   8 +
>  .../linux/nios2/libc_malloc_debug.abilist     |   8 +
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |   8 +
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |   8 +
>  .../powerpc64/be/libc_malloc_debug.abilist    |   8 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |   8 +
>  .../riscv/rv32/libc_malloc_debug.abilist      |   8 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |   8 +
>  .../s390/s390-32/libc_malloc_debug.abilist    |   8 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |   8 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |   8 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |   8 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |   8 +
>  .../sparc/sparc64/libc_malloc_debug.abilist   |   8 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |   8 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |   8 +
>  41 files changed, 861 insertions(+), 465 deletions(-)
>  create mode 100644 malloc/mcheck-impl.c
> 
> 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)

OK.

> -
>  # endif /* !_ISOMAC */
>  #endif
> diff --git a/malloc/Makefile b/malloc/Makefile
> index 7ea45d2358..c0dbe04b57 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 \

OK.

>  	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;

OK.

>  
>  #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
>  }

OK. Do-nothing for libc, but implement for libc_malloc_debug.so.

> 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
> 

OK.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 06/10] Simplify __malloc_initialized
  2021-07-13  7:38 ` [PATCH v8 06/10] Simplify __malloc_initialized Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Now that mcheck no longer needs to check __malloc_initialized (and no
> other third party hook can since the symbol is not exported), make the
> variable boolean and static so that it is used strictly within malloc.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  include/malloc.h |  6 ------
>  malloc/arena.c   | 12 ++++++------
>  malloc/malloc.c  | 24 ++++++++++++------------
>  3 files changed, 18 insertions(+), 24 deletions(-)
> 
> diff --git a/include/malloc.h b/include/malloc.h
> index b77761f74d..f9c9610548 100644
> --- a/include/malloc.h
> +++ b/include/malloc.h
> @@ -5,12 +5,6 @@
>  # ifndef _ISOMAC
>  #  include <rtld-malloc.h>
>  
> -/* In the GNU libc we rename the global variable
> -   `__malloc_initialized' to `__libc_malloc_initialized'.  */
> -#define __malloc_initialized __libc_malloc_initialized
> -/* Nonzero if the malloc is already initialized.  */
> -extern int __malloc_initialized attribute_hidden;

OK.

> -
>  struct malloc_state;
>  typedef struct malloc_state *mstate;
>  
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 9111b49589..840426f9fb 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -97,7 +97,7 @@ static mstate free_list;
>  __libc_lock_define_initialized (static, list_lock);
>  
>  /* Already initialized? */
> -int __malloc_initialized = -1;
> +static bool __malloc_initialized = false;

OK.

>  
>  /**************************************************************************/
>  
> @@ -143,7 +143,7 @@ int __malloc_initialized = -1;
>  void
>  __malloc_fork_lock_parent (void)
>  {
> -  if (__malloc_initialized < 1)
> +  if (!__malloc_initialized)

OK.

>      return;
>  
>    /* We do not acquire free_list_lock here because we completely
> @@ -163,7 +163,7 @@ __malloc_fork_lock_parent (void)
>  void
>  __malloc_fork_unlock_parent (void)
>  {
> -  if (__malloc_initialized < 1)
> +  if (!__malloc_initialized)
>      return;
>  
>    for (mstate ar_ptr = &main_arena;; )
> @@ -179,7 +179,7 @@ __malloc_fork_unlock_parent (void)
>  void
>  __malloc_fork_unlock_child (void)
>  {
> -  if (__malloc_initialized < 1)
> +  if (!__malloc_initialized)
>      return;
>  
>    /* Push all arenas to the free list, except thread_arena, which is
> @@ -286,10 +286,10 @@ static void tcache_key_initialize (void);
>  static void
>  ptmalloc_init (void)
>  {
> -  if (__malloc_initialized >= 0)
> +  if (__malloc_initialized)
>      return;
>  
> -  __malloc_initialized = 0;
> +  __malloc_initialized = true;
>  
>  #if USE_TCACHE
>    tcache_key_initialize ();
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index cf71314b2b..ed0316e690 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -3195,7 +3195,7 @@ __libc_malloc (size_t bytes)
>    _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
>                    "PTRDIFF_MAX is not more than half of SIZE_MAX");
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  #if USE_TCACHE
>    /* int_free also calls request2size, be careful to not pad twice.  */
> @@ -3308,7 +3308,7 @@ __libc_realloc (void *oldmem, size_t bytes)
>  
>    void *newp;             /* chunk to return */
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>  #if REALLOC_ZERO_BYTES_FREES
> @@ -3444,7 +3444,7 @@ libc_hidden_def (__libc_realloc)
>  void *
>  __libc_memalign (size_t alignment, size_t bytes)
>  {
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    void *address = RETURN_ADDRESS (0);
> @@ -3515,7 +3515,7 @@ libc_hidden_def (__libc_memalign)
>  void *
>  __libc_valloc (size_t bytes)
>  {
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    void *address = RETURN_ADDRESS (0);
> @@ -3526,7 +3526,7 @@ __libc_valloc (size_t bytes)
>  void *
>  __libc_pvalloc (size_t bytes)
>  {
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    void *address = RETURN_ADDRESS (0);
> @@ -3565,7 +3565,7 @@ __libc_calloc (size_t n, size_t elem_size)
>  
>    sz = bytes;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    MAYBE_INIT_TCACHE ();
> @@ -5022,7 +5022,7 @@ __malloc_trim (size_t s)
>  {
>    int result = 0;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    mstate ar_ptr = &main_arena;
> @@ -5157,7 +5157,7 @@ __libc_mallinfo2 (void)
>    struct mallinfo2 m;
>    mstate ar_ptr;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    memset (&m, 0, sizeof (m));
> @@ -5208,7 +5208,7 @@ __malloc_stats (void)
>    mstate ar_ptr;
>    unsigned int in_use_b = mp_.mmapped_mem, system_b = in_use_b;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>    _IO_flockfile (stderr);
>    int old_flags2 = stderr->_flags2;
> @@ -5377,7 +5377,7 @@ __libc_mallopt (int param_number, int value)
>    mstate av = &main_arena;
>    int res = 1;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>    __libc_lock_lock (av->mutex);
>  
> @@ -5595,7 +5595,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
>  {
>    void *mem;
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    /* Test whether the SIZE argument is valid.  It must be a power of
> @@ -5639,7 +5639,7 @@ __malloc_info (int options, FILE *fp)
>  
>  
>  
> -  if (__malloc_initialized < 0)
> +  if (!__malloc_initialized)
>      ptmalloc_init ();
>  
>    fputs ("<malloc version=\"1\">\n", fp);
> 

OK.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 07/10] mtrace: Wean away from malloc hooks
  2021-07-13  7:38 ` [PATCH v8 07/10] mtrace: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Wean mtrace away from the malloc hooks and move them into the debug
> DSO.  Split the API away from the implementation so that we can add
> the API to libc.so as well as libc_malloc_debug.so, with the libc
> implementations being empty.
> 
> Update localplt data since memalign no longer has any callers after
> this change.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  malloc/Versions                               |   2 +
>  malloc/malloc-debug.c                         |  13 +
>  malloc/mtrace-impl.c                          | 226 +++++++++++++
>  malloc/mtrace.c                               | 314 +-----------------
>  sysdeps/generic/localplt.data                 |   1 -
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |   2 +
>  sysdeps/mach/hurd/i386/localplt.data          |   1 -
>  .../linux/aarch64/libc_malloc_debug.abilist   |   2 +
>  sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
>  .../linux/alpha/libc_malloc_debug.abilist     |   2 +
>  sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |   2 +
>  sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
>  .../linux/arm/be/libc_malloc_debug.abilist    |   2 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |   2 +
>  sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
>  .../sysv/linux/csky/libc_malloc_debug.abilist |   2 +
>  sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |   2 +
>  sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
>  .../sysv/linux/i386/libc_malloc_debug.abilist |   2 +
>  sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |   2 +
>  sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
>  .../m68k/coldfire/libc_malloc_debug.abilist   |   2 +
>  .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
>  .../m68k/m680x0/libc_malloc_debug.abilist     |   2 +
>  .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
>  .../microblaze/be/libc_malloc_debug.abilist   |   2 +
>  .../microblaze/le/libc_malloc_debug.abilist   |   2 +
>  .../unix/sysv/linux/microblaze/localplt.data  |   1 -
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |   2 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |   2 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |   2 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |   2 +
>  .../linux/nios2/libc_malloc_debug.abilist     |   2 +
>  sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |   2 +
>  .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |   2 +
>  .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
>  .../powerpc64/be/libc_malloc_debug.abilist    |   2 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |   2 +
>  .../linux/powerpc/powerpc64/localplt.data     |   1 -
>  sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
>  .../riscv/rv32/libc_malloc_debug.abilist      |   2 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |   2 +
>  sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
>  .../s390/s390-32/libc_malloc_debug.abilist    |   2 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |   2 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |   2 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |   2 +
>  sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
>  .../sparc/sparc32/libc_malloc_debug.abilist   |   2 +
>  .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
>  .../sparc/sparc64/libc_malloc_debug.abilist   |   2 +
>  .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
>  .../linux/x86_64/64/libc_malloc_debug.abilist |   2 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |   2 +
>  sysdeps/x86_64/localplt.data                  |   1 -
>  60 files changed, 319 insertions(+), 325 deletions(-)
>  create mode 100644 malloc/mtrace-impl.c
> 
> diff --git a/malloc/Versions b/malloc/Versions
> index 6548970419..71d933de19 100644
> --- a/malloc/Versions
> +++ b/malloc/Versions
> @@ -117,6 +117,8 @@ libc_malloc_debug {
>  
>      mcheck;
>      mprobe;
> +    mtrace;
> +    muntrace;

OK.

>    }
>    GLIBC_2.2 {
>      mcheck_check_all;
> diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
> index 7c3a1e26b5..9942124e02 100644
> --- a/malloc/malloc-debug.c
> +++ b/malloc/malloc-debug.c
> @@ -49,6 +49,7 @@ enum malloc_debug_hooks
>  {
>    MALLOC_NONE_HOOK = 0,
>    MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck()  */
> +  MALLOC_MTRACE_HOOK = 1 << 1, /* mtrace()  */

OK.

>  };
>  static unsigned __malloc_debugging_hooks;
>  
> @@ -71,6 +72,7 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
>  }
>  
>  #include "mcheck.c"
> +#include "mtrace.c"
>  
>  extern void (*__malloc_initialize_hook) (void);
>  compat_symbol_reference (libc, __malloc_initialize_hook,
> @@ -154,6 +156,8 @@ __debug_malloc (size_t bytes)
>      }
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = malloc_mcheck_after (victim, orig_bytes);
> +  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +    malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
>  
>    return victim;
>  }
> @@ -171,6 +175,8 @@ __debug_free (void *mem)
>  
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
>      mem = free_mcheck (mem);
> +  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +    free_mtrace (mem, RETURN_ADDRESS (0));
>  
>    __libc_free (mem);
>  }
> @@ -195,6 +201,8 @@ __debug_realloc (void *oldmem, size_t bytes)
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
>  				   oldsize);
> +  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +    realloc_mtrace_after (victim, oldmem, orig_bytes, RETURN_ADDRESS (0));
>  
>    return victim;
>  }
> @@ -218,6 +226,8 @@ _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
>      }
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = memalign_mcheck_after (victim, alignment, orig_bytes);
> +  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +    memalign_mtrace_after (victim, orig_bytes, address);
>  
>    return victim;
>  }
> @@ -317,6 +327,9 @@ __debug_calloc (size_t nmemb, size_t size)
>  	victim = malloc_mcheck_after (victim, orig_bytes);
>        memset (victim, 0, orig_bytes);
>      }
> +  if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +    malloc_mtrace_after (victim, orig_bytes, RETURN_ADDRESS (0));
> +
>    return victim;
>  }
>  strong_alias (__debug_calloc, calloc)

OK.

> diff --git a/malloc/mtrace-impl.c b/malloc/mtrace-impl.c
> new file mode 100644
> index 0000000000..0e10ab7f60
> --- /dev/null
> +++ b/malloc/mtrace-impl.c
> @@ -0,0 +1,226 @@
> +/* mtrace implementation for `malloc'.
> +   Copyright (C) 1991-2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +                 Written April 2, 1991 by John Gilmore of Cygnus Support.
> +                 Based on mcheck.c 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.h>
> +#include <mcheck.h>
> +
> +#include <dlfcn.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +
> +#include <libc-internal.h>
> +#include <dso_handle.h>
> +
> +#include <kernel-features.h>
> +
> +#define TRACE_BUFFER_SIZE 512
> +
> +static FILE *mallstream;
> +static const char mallenv[] = "MALLOC_TRACE";
> +static char *malloc_trace_buffer;
> +
> +static void
> +tr_where (const void *caller, Dl_info *info)
> +{
> +  if (caller != NULL)
> +    {
> +      if (info != NULL)
> +        {
> +          char *buf = (char *) "";
> +          if (info->dli_sname != NULL)
> +            {
> +              size_t len = strlen (info->dli_sname);
> +              buf = alloca (len + 6 + 2 * sizeof (void *));
> +	      char sign;
> +	      ptrdiff_t offset =
> +		(ptrdiff_t) info->dli_saddr - (ptrdiff_t) caller;
> +
> +	      if (caller >= (const void *) info->dli_saddr)
> +		{
> +		  sign = '+';
> +		  offset = -offset;
> +		}
> +	      else
> +		  sign = '-';
> +
> +	      sprintf (buf, "(%s%c%" PRIxPTR ")", info->dli_sname, sign,
> +		       offset);
> +            }
> +
> +	  fprintf (mallstream, "@ %s%s%s[%p] ", info->dli_fname ? : "",
> +		   info->dli_fname ? ":" : "",
> +                   buf, caller);
> +        }
> +      else
> +        fprintf (mallstream, "@ [%p] ", caller);
> +    }
> +}
> +
> +static Dl_info *
> +lock_and_info (const void *caller, Dl_info *mem)
> +{
> +  if (caller == NULL)
> +    return NULL;
> +
> +  Dl_info *res = dladdr (caller, mem) ? mem : NULL;
> +
> +  flockfile (mallstream);
> +
> +  return res;
> +}
> +
> +static void
> +free_mtrace (void *ptr, const void *caller)
> +{
> +  if (ptr == NULL)
> +    return;
> +
> +  Dl_info mem;
> +  Dl_info *info = lock_and_info (caller, &mem);
> +  tr_where (caller, info);
> +  /* Be sure to print it first.  */
> +  fprintf (mallstream, "- %p\n", ptr);
> +  funlockfile (mallstream);
> +}
> +
> +static void
> +malloc_mtrace_after (void *block, size_t size, const void *caller)
> +{
> +  Dl_info mem;
> +  Dl_info *info = lock_and_info (caller, &mem);
> +
> +  tr_where (caller, info);
> +  /* We could be printing a NULL here; that's OK.  */
> +  fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
> +
> +  funlockfile (mallstream);
> +}
> +
> +static void
> +realloc_mtrace_after (void *block, const void *oldptr, size_t size,
> +		      const void *caller)
> +{
> +  Dl_info mem;
> +  Dl_info *info = lock_and_info (caller, &mem);
> +
> +  tr_where (caller, info);
> +  if (block == NULL)
> +    {
> +      if (size != 0)
> +        /* Failed realloc.  */
> +	fprintf (mallstream, "! %p %#lx\n", oldptr, (unsigned long int) size);
> +      else
> +        fprintf (mallstream, "- %p\n", oldptr);
> +    }
> +  else if (oldptr == NULL)
> +    fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
> +  else
> +    {
> +      fprintf (mallstream, "< %p\n", oldptr);
> +      tr_where (caller, info);
> +      fprintf (mallstream, "> %p %#lx\n", block, (unsigned long int) size);
> +    }
> +
> +  funlockfile (mallstream);
> +}
> +
> +static void
> +memalign_mtrace_after (void *block, size_t size, const void *caller)
> +{
> +  Dl_info mem;
> +  Dl_info *info = lock_and_info (caller, &mem);
> +
> +  tr_where (caller, info);
> +  /* We could be printing a NULL here; that's OK.  */
> +  fprintf (mallstream, "+ %p %#lx\n", block, (unsigned long int) size);
> +
> +  funlockfile (mallstream);
> +}
> +
> +/* This function gets called to make sure all memory the library
> +   allocates get freed and so does not irritate the user when studying
> +   the mtrace output.  */
> +static void
> +release_libc_mem (void)
> +{
> +  /* Only call the free function if we still are running in mtrace mode.  */
> +  if (mallstream != NULL)
> +    __libc_freeres ();
> +}
> +
> +/* We enable tracing if the environment variable MALLOC_TRACE is set.  */
> +
> +static void
> +do_mtrace (void)
> +{
> +  static int added_atexit_handler;
> +  char *mallfile;
> +
> +  /* Don't panic if we're called more than once.  */
> +  if (mallstream != NULL)
> +    return;
> +
> +  mallfile = secure_getenv (mallenv);
> +  if (mallfile != NULL)
> +    {
> +      char *mtb = malloc (TRACE_BUFFER_SIZE);
> +      if (mtb == NULL)
> +        return;
> +
> +      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
> +      if (mallstream != NULL)
> +        {
> +          /* Be sure it doesn't malloc its buffer!  */
> +          malloc_trace_buffer = mtb;
> +          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
> +          fprintf (mallstream, "= Start\n");
> +          if (!added_atexit_handler)
> +            {
> +              added_atexit_handler = 1;
> +              __cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
> +			    __dso_handle);
> +            }
> +	  __malloc_debug_enable (MALLOC_MTRACE_HOOK);
> +        }
> +      else
> +        free (mtb);
> +    }
> +}
> +
> +static void
> +do_muntrace (void)
> +{
> +  __malloc_debug_disable (MALLOC_MTRACE_HOOK);
> +  if (mallstream == NULL)
> +    return;
> +
> +  /* Do the reverse of what done in mtrace: first reset the hooks and
> +     MALLSTREAM, and only after that write the trailer and close the
> +     file.  */
> +  FILE *f = mallstream;
> +  mallstream = NULL;
> +
> +  fprintf (f, "= End\n");
> +  fclose (f);
> +}

OK.

> diff --git a/malloc/mtrace.c b/malloc/mtrace.c
> index fb58413d39..c1c836a740 100644
> --- a/malloc/mtrace.c
> +++ b/malloc/mtrace.c
> @@ -1,4 +1,4 @@
> -/* More debugging hooks for `malloc'.
> +/* mtrace API for `malloc'.
>     Copyright (C) 1991-2021 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>                   Written April 2, 1991 by John Gilmore of Cygnus Support.
> @@ -18,40 +18,14 @@
>     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 <mcheck.h>
> -# include <malloc-internal.h>
> -# include <libc-lock.h>
> +#if !IS_IN (libc)
> +# include "mtrace-impl.c"
> +#else
> +# include <shlib-compat.h>
> +# include <libc-symbols.h>
>  #endif
>  
> -#include <dlfcn.h>
> -#include <fcntl.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <stdlib.h>
> -
> -#include <_itoa.h>
> -
> -#include <libc-internal.h>
> -#include <dso_handle.h>
> -
> -#include <libio/iolibio.h>
> -#define setvbuf(s, b, f, l) _IO_setvbuf (s, b, f, l)
> -#define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp)
> -
> -#include <kernel-features.h>
> -
> -#define TRACE_BUFFER_SIZE 512
> -
> -static FILE *mallstream;
> -static const char mallenv[] = "MALLOC_TRACE";
> -static char *malloc_trace_buffer;
> -
> -__libc_lock_define_initialized (static, lock);
> -
> -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
> +#if IS_IN (libc) && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
>  /* Compatibility symbols that were introduced to help break at allocation sites
>     for specific memory allocations.  This is unusable with ASLR, although gdb
>     may allow predictable allocation addresses.  Even then, gdb has watchpoint
> @@ -71,282 +45,18 @@ compat_symbol (libc, tr_break, tr_break, GLIBC_2_0);
>  #endif
>  
>  
> -/* Old hook values.  */
> -static void (*tr_old_free_hook) (void *ptr, const void *);
> -static void *(*tr_old_malloc_hook) (size_t size, const void *);
> -static void *(*tr_old_realloc_hook) (void *ptr, size_t size,
> -				     const void *);
> -static void *(*tr_old_memalign_hook) (size_t __alignment, size_t __size,
> -				      const void *);
> -
> -static void
> -tr_where (const void *caller, Dl_info *info)
> -{
> -  if (caller != NULL)
> -    {
> -      if (info != NULL)
> -        {
> -          char *buf = (char *) "";
> -          if (info->dli_sname != NULL)
> -            {
> -              size_t len = strlen (info->dli_sname);
> -              buf = alloca (len + 6 + 2 * sizeof (void *));
> -
> -              buf[0] = '(';
> -              __stpcpy (_fitoa (caller >= (const void *) info->dli_saddr
> -                                ? caller - (const void *) info->dli_saddr
> -                                : (const void *) info->dli_saddr - caller,
> -                                __stpcpy (__mempcpy (buf + 1, info->dli_sname,
> -                                                     len),
> -                                          caller >= (void *) info->dli_saddr
> -                                          ? "+0x" : "-0x"),
> -                                16, 0),
> -                        ")");
> -            }
> -
> -          fprintf (mallstream, "@ %s%s%s[%p] ",
> -                   info->dli_fname ? : "", info->dli_fname ? ":" : "",
> -                   buf, caller);
> -        }
> -      else
> -        fprintf (mallstream, "@ [%p] ", caller);
> -    }
> -}
> -
> -static Dl_info *
> -lock_and_info (const void *caller, Dl_info *mem)
> -{
> -  if (caller == NULL)
> -    return NULL;
> -
> -  Dl_info *res = _dl_addr (caller, mem, NULL, NULL) ? mem : NULL;
> -
> -  __libc_lock_lock (lock);
> -
> -  return res;
> -}
> -
> -static void tr_freehook (void *, const void *);
> -static void * tr_mallochook (size_t, const void *);
> -static void * tr_reallochook (void *, size_t, const void *);
> -static void * tr_memalignhook (size_t, size_t, const void *);
> -
> -/* Set all the default non-trace hooks.  */
> -static __always_inline void
> -set_default_hooks (void)
> -{
> -  __free_hook = tr_old_free_hook;
> -  __malloc_hook = tr_old_malloc_hook;
> -  __realloc_hook = tr_old_realloc_hook;
> -  __memalign_hook = tr_old_memalign_hook;
> -}
> -
> -/* Set all of the tracing hooks used for mtrace.  */
> -static __always_inline void
> -set_trace_hooks (void)
> -{
> -  __free_hook = tr_freehook;
> -  __malloc_hook = tr_mallochook;
> -  __realloc_hook = tr_reallochook;
> -  __memalign_hook = tr_memalignhook;
> -}
> -
> -/* Save the current set of hooks as the default hooks.  */
> -static __always_inline void
> -save_default_hooks (void)
> -{
> -  tr_old_free_hook = __free_hook;
> -  tr_old_malloc_hook = __malloc_hook;
> -  tr_old_realloc_hook = __realloc_hook;
> -  tr_old_memalign_hook = __memalign_hook;
> -}
> -
> -static void
> -tr_freehook (void *ptr, const void *caller)
> -{
> -  if (ptr == NULL)
> -    return;
> -
> -  Dl_info mem;
> -  Dl_info *info = lock_and_info (caller, &mem);
> -  tr_where (caller, info);
> -  /* Be sure to print it first.  */
> -  fprintf (mallstream, "- %p\n", ptr);
> -  set_default_hooks ();
> -  if (tr_old_free_hook != NULL)
> -    (*tr_old_free_hook)(ptr, caller);
> -  else
> -    free (ptr);
> -  set_trace_hooks ();
> -  __libc_lock_unlock (lock);
> -}
> -
> -static void *
> -tr_mallochook (size_t size, const void *caller)
> -{
> -  void *hdr;
> -
> -  Dl_info mem;
> -  Dl_info *info = lock_and_info (caller, &mem);
> -
> -  set_default_hooks ();
> -  if (tr_old_malloc_hook != NULL)
> -    hdr = (void *) (*tr_old_malloc_hook)(size, caller);
> -  else
> -    hdr = (void *) malloc (size);
> -  set_trace_hooks ();
> -
> -  tr_where (caller, info);
> -  /* We could be printing a NULL here; that's OK.  */
> -  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
> -
> -  __libc_lock_unlock (lock);
> -
> -  return hdr;
> -}
> -
> -static void *
> -tr_reallochook (void *ptr, size_t size, const void *caller)
> -{
> -  void *hdr;
> -
> -  Dl_info mem;
> -  Dl_info *info = lock_and_info (caller, &mem);
> -
> -  set_default_hooks ();
> -  if (tr_old_realloc_hook != NULL)
> -    hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
> -  else
> -    hdr = (void *) realloc (ptr, size);
> -  set_trace_hooks ();
> -
> -  tr_where (caller, info);
> -  if (hdr == NULL)
> -    {
> -      if (size != 0)
> -        /* Failed realloc.  */
> -        fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
> -      else
> -        fprintf (mallstream, "- %p\n", ptr);
> -    }
> -  else if (ptr == NULL)
> -    fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
> -  else
> -    {
> -      fprintf (mallstream, "< %p\n", ptr);
> -      tr_where (caller, info);
> -      fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
> -    }
> -
> -  __libc_lock_unlock (lock);
> -
> -  return hdr;
> -}
> -
> -static void *
> -tr_memalignhook (size_t alignment, size_t size, const void *caller)
> -{
> -  void *hdr;
> -
> -  Dl_info mem;
> -  Dl_info *info = lock_and_info (caller, &mem);
> -
> -  set_default_hooks ();
> -  if (tr_old_memalign_hook != NULL)
> -    hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
> -  else
> -    hdr = (void *) memalign (alignment, size);
> -  set_trace_hooks ();
> -
> -  tr_where (caller, info);
> -  /* We could be printing a NULL here; that's OK.  */
> -  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
> -
> -  __libc_lock_unlock (lock);
> -
> -  return hdr;
> -}
> -
> -
> -#ifdef _LIBC
> -
> -/* This function gets called to make sure all memory the library
> -   allocates get freed and so does not irritate the user when studying
> -   the mtrace output.  */
> -static void __libc_freeres_fn_section
> -release_libc_mem (void)
> -{
> -  /* Only call the free function if we still are running in mtrace mode.  */
> -  if (mallstream != NULL)
> -    __libc_freeres ();
> -}
> -#endif
> -
> -
> -/* We enable tracing if the environment variable MALLOC_TRACE is set.  */
> -
>  void
>  mtrace (void)
>  {
> -#ifdef _LIBC
> -  static int added_atexit_handler;
> +#if !IS_IN (libc)
> +  do_mtrace ();
>  #endif
> -  char *mallfile;
> -
> -  /* Don't panic if we're called more than once.  */
> -  if (mallstream != NULL)
> -    return;
> -
> -#ifdef _LIBC
> -  /* When compiling the GNU libc we use the secure getenv function
> -     which prevents the misuse in case of SUID or SGID enabled
> -     programs.  */
> -  mallfile = __libc_secure_getenv (mallenv);
> -#else
> -  mallfile = getenv (mallenv);
> -#endif
> -  if (mallfile != NULL)
> -    {
> -      char *mtb = malloc (TRACE_BUFFER_SIZE);
> -      if (mtb == NULL)
> -        return;
> -
> -      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
> -      if (mallstream != NULL)
> -        {
> -          /* Be sure it doesn't malloc its buffer!  */
> -          malloc_trace_buffer = mtb;
> -          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
> -          fprintf (mallstream, "= Start\n");
> -	  save_default_hooks ();
> -	  set_trace_hooks ();
> -#ifdef _LIBC
> -          if (!added_atexit_handler)
> -            {
> -              added_atexit_handler = 1;
> -              __cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
> -			    __dso_handle);
> -            }
> -#endif
> -        }
> -      else
> -        free (mtb);
> -    }
>  }
>  
>  void
>  muntrace (void)
>  {
> -  if (mallstream == NULL)
> -    return;
> -
> -  /* Do the reverse of what done in mtrace: first reset the hooks and
> -     MALLSTREAM, and only after that write the trailer and close the
> -     file.  */
> -  FILE *f = mallstream;
> -  mallstream = NULL;
> -  set_default_hooks ();
> -
> -  fprintf (f, "= End\n");
> -  fclose (f);
> +#if !IS_IN (libc)
> +  do_muntrace ();
> +#endif
>  }

OK.

> diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data
> index e2083c0ce6..9b4f35786a 100644
> --- a/sysdeps/generic/localplt.data
> +++ b/sysdeps/generic/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign

OK.

>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> index c5e1192b27..798d3ae8a3 100644
> --- a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> +++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2.6 muntrace F
>  GLIBC_2.2.6 posix_memalign F
>  GLIBC_2.2.6 pvalloc F
>  GLIBC_2.2.6 realloc F
> diff --git a/sysdeps/mach/hurd/i386/localplt.data b/sysdeps/mach/hurd/i386/localplt.data
> index 94064ecbc5..47fbe1e2a7 100644
> --- a/sysdeps/mach/hurd/i386/localplt.data
> +++ b/sysdeps/mach/hurd/i386/localplt.data
> @@ -6,7 +6,6 @@
>  libc.so: calloc + REL R_386_GLOB_DAT
>  libc.so: free + REL R_386_GLOB_DAT
>  libc.so: malloc + REL R_386_GLOB_DAT
> -libc.so: memalign + REL R_386_GLOB_DAT
>  libc.so: realloc + REL R_386_GLOB_DAT
>  libm.so: matherr + REL R_386_GLOB_DAT
>  # The TLS-enabled version of these functions is interposed from libc.so.
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> index cc6531b017..bf543ed1e0 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.17 muntrace F
>  GLIBC_2.17 posix_memalign F
>  GLIBC_2.17 pvalloc F
>  GLIBC_2.17 realloc F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data
> index 2c14b652ef..348b3f3793 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/localplt.data
> +++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # If outline atomics are used, libgcc (built outside of glibc) may
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> index 5fe020dca6..fa8beb5e83 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data
> index 43f6fdaea1..44bf36f4f1 100644
> --- a/sysdeps/unix/sysv/linux/alpha/localplt.data
> +++ b/sysdeps/unix/sysv/linux/alpha/localplt.data
> @@ -18,7 +18,6 @@ libc.so: _Unwind_Find_FDE
>  libc.so: calloc + RELA R_ALPHA_GLOB_DAT
>  libc.so: free + RELA R_ALPHA_GLOB_DAT
>  libc.so: malloc + RELA R_ALPHA_GLOB_DAT
> -libc.so: memalign + RELA R_ALPHA_GLOB_DAT
>  libc.so: realloc + RELA R_ALPHA_GLOB_DAT
>  libm.so: matherr + RELA R_ALPHA_GLOB_DAT
>  # We used to offer inline functions that used this, so it must be exported.
> diff --git a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> index b5e9d10b9f..14bad4f83a 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.32 muntrace F
>  GLIBC_2.32 posix_memalign F
>  GLIBC_2.32 pvalloc F
>  GLIBC_2.32 realloc F
> diff --git a/sysdeps/unix/sysv/linux/arc/localplt.data b/sysdeps/unix/sysv/linux/arc/localplt.data
> index 4479e8ee8a..ac5332caf7 100644
> --- a/sysdeps/unix/sysv/linux/arc/localplt.data
> +++ b/sysdeps/unix/sysv/linux/arc/localplt.data
> @@ -1,6 +1,5 @@
>  libc.so: realloc
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: calloc
>  libc.so: free
>  # At -Os, a struct assignment in libgcc-static pulls this in
> 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 c90d894b22..97b470a989 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.4 muntrace 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 c90d894b22..97b470a989 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.4 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data
> index eb315da2f1..78896444c6 100644
> --- a/sysdeps/unix/sysv/linux/arm/localplt.data
> +++ b/sysdeps/unix/sysv/linux/arm/localplt.data
> @@ -1,7 +1,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: raise
>  libc.so: realloc
>  libm.so: matherr
> diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> index 932cbbd382..eac818b681 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.29 muntrace F
>  GLIBC_2.29 posix_memalign F
>  GLIBC_2.29 pvalloc F
>  GLIBC_2.29 realloc F
> diff --git a/sysdeps/unix/sysv/linux/csky/localplt.data b/sysdeps/unix/sysv/linux/csky/localplt.data
> index 0ed8650b65..817ab2659a 100644
> --- a/sysdeps/unix/sysv/linux/csky/localplt.data
> +++ b/sysdeps/unix/sysv/linux/csky/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  # The TLS-enabled version of these functions is interposed from libc.so.
>  ld.so: _dl_signal_error
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> index 88ed3c09c8..88cdf04cbe 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace F
>  GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
> diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data
> index 09893d4dcf..baf857a750 100644
> --- a/sysdeps/unix/sysv/linux/hppa/localplt.data
> +++ b/sysdeps/unix/sysv/linux/hppa/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libc.so: __sigsetjmp
>  libc.so: _IO_funlockfile
> diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> index c847b1ee49..96955644d5 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
> index 5334875b4b..f9bf7fb410 100644
> --- a/sysdeps/unix/sysv/linux/i386/localplt.data
> +++ b/sysdeps/unix/sysv/linux/i386/localplt.data
> @@ -4,7 +4,6 @@ libc.so: _Unwind_Find_FDE + REL R_386_GLOB_DAT
>  libc.so: calloc + REL R_386_GLOB_DAT
>  libc.so: free + REL R_386_GLOB_DAT
>  libc.so: malloc + REL R_386_GLOB_DAT
> -libc.so: memalign + REL R_386_GLOB_DAT
>  libc.so: realloc + REL R_386_GLOB_DAT
>  libm.so: matherr + REL R_386_GLOB_DAT
>  # The TLS-enabled version of these functions is interposed from libc.so.
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> index bc8a2be276..ee940be29a 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace F
>  GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
> diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data
> index 1c566a503e..174fb88128 100644
> --- a/sysdeps/unix/sysv/linux/ia64/localplt.data
> +++ b/sysdeps/unix/sysv/linux/ia64/localplt.data
> @@ -1,7 +1,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  libm.so: matherrf
> 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 c90d894b22..97b470a989 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.4 muntrace 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/coldfire/localplt.data b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
> index 3c5efb7204..42fa90508c 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
> @@ -2,7 +2,6 @@ libc.so: __m68k_read_tp
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 c847b1ee49..96955644d5 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
> index 843f4e25f2..34bd4c1aca 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
> @@ -3,7 +3,6 @@ libc.so: __m68k_read_tp
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 0502f3001e..48db59ebb1 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.18 muntrace 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 0502f3001e..48db59ebb1 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.18 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data
> index 0e98d5251e..c3801314c9 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/localplt.data
> +++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data
> @@ -2,7 +2,6 @@ libc.so: __errno_location
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The dynamic loader needs __tls_get_addr for TLS.
> 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc 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 5fe020dca6..fa8beb5e83 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> index 3a4599773d..3a3f0a2861 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.21 muntrace F
>  GLIBC_2.21 posix_memalign F
>  GLIBC_2.21 pvalloc F
>  GLIBC_2.21 realloc F
> diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data
> index b37987c7c0..17fcfdd4db 100644
> --- a/sysdeps/unix/sysv/linux/nios2/localplt.data
> +++ b/sysdeps/unix/sysv/linux/nios2/localplt.data
> @@ -6,7 +6,6 @@ libc.so: __gedf2
>  libc.so: malloc
>  libc.so: __gtsf2 ?
>  libc.so: __nesf2
> -libc.so: memalign
>  libc.so: __mulsf3
>  libc.so: __floatunsisf
>  libc.so: __addsf3
> 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
> index a02dd5cc24..c0af84eef7 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
> @@ -2,7 +2,6 @@ libc.so: _Unwind_Find_FDE
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
> index d8072597b7..581e54b95c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
> @@ -30,7 +30,6 @@ libc.so: abort ?
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: memset ?
>  libc.so: realloc
>  libm.so: copysignl ?
> 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 0696d526d4..9e0c7a48c0 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
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.3 muntrace 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 cc6531b017..bf543ed1e0 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
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.17 muntrace F
>  GLIBC_2.17 posix_memalign F
>  GLIBC_2.17 pvalloc F
>  GLIBC_2.17 realloc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
> index bb498fbe3a..d69b7ae646 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
> @@ -1,7 +1,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> diff --git a/sysdeps/unix/sysv/linux/riscv/localplt.data b/sysdeps/unix/sysv/linux/riscv/localplt.data
> index 0a235592c3..e6d5330d5b 100644
> --- a/sysdeps/unix/sysv/linux/riscv/localplt.data
> +++ b/sysdeps/unix/sysv/linux/riscv/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: memset ?
>  libc.so: realloc
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 4ded2f9640..e2448d7b83 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.33 muntrace 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 f878912895..622ee2e67a 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.27 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data
> index a02dd5cc24..c0af84eef7 100644
> --- a/sysdeps/unix/sysv/linux/s390/localplt.data
> +++ b/sysdeps/unix/sysv/linux/s390/localplt.data
> @@ -2,7 +2,6 @@ libc.so: _Unwind_Find_FDE
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 c847b1ee49..96955644d5 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
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc 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 bc8a2be276..ee940be29a 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
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace 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 88ed3c09c8..88cdf04cbe 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace 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 88ed3c09c8..88cdf04cbe 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace 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/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data
> index 3225177c50..6491b9e37b 100644
> --- a/sysdeps/unix/sysv/linux/sh/localplt.data
> +++ b/sysdeps/unix/sysv/linux/sh/localplt.data
> @@ -4,7 +4,6 @@
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libc.so: _Unwind_Find_FDE
>  libc.so: _exit
> 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 c847b1ee49..96955644d5 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> @@ -8,6 +8,8 @@ GLIBC_2.0 malloc F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> +GLIBC_2.0 mtrace F
> +GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
> index be51efd566..38309a1393 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
> @@ -16,7 +16,6 @@ libc.so: _Unwind_Find_FDE
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 bc8a2be276..ee940be29a 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2 muntrace 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/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
> index 809062d46c..6a216f3a5a 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
> @@ -15,7 +15,6 @@ libc.so: _Unwind_Find_FDE
>  libc.so: calloc
>  libc.so: free
>  libc.so: malloc
> -libc.so: memalign
>  libc.so: realloc
>  libm.so: matherr
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 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 3fa0aa3cc3..e734b8f088 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
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.2.5 muntrace 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 4c213fcbef..14efc6602f 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
> @@ -11,6 +11,8 @@ 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 mtrace F
> +GLIBC_2.16 muntrace F
>  GLIBC_2.16 posix_memalign F
>  GLIBC_2.16 pvalloc F
>  GLIBC_2.16 realloc F
> diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data
> index 8f41e92870..d1f2e26612 100644
> --- a/sysdeps/x86_64/localplt.data
> +++ b/sysdeps/x86_64/localplt.data
> @@ -6,7 +6,6 @@
>  libc.so: calloc + RELA R_X86_64_GLOB_DAT
>  libc.so: free + RELA R_X86_64_GLOB_DAT
>  libc.so: malloc + RELA R_X86_64_GLOB_DAT
> -libc.so: memalign + RELA R_X86_64_GLOB_DAT
>  libc.so: realloc + RELA R_X86_64_GLOB_DAT
>  libm.so: matherr + RELA R_X86_64_GLOB_DAT
>  # The TLS-enabled version of these functions is interposed from libc.so.
> 

OK.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 08/10] glibc.malloc.check: Wean away from malloc hooks
  2021-07-13  7:38 ` [PATCH v8 08/10] glibc.malloc.check: " Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> The malloc-check debugging feature is tightly integrated into glibc
> malloc, so thanks to an idea from Florian Weimer, much of the malloc
> implementation has been moved into libc_malloc_debug.so to support
> malloc-check.  Due to this, glibc malloc and malloc-check can no
> longer work together; they use altogether different (but identical)
> structures for heap management.  This should not make a difference
> though since the malloc check hook is not disabled anywhere.
> malloc_set_state does, but it does so early enough and that behaviour
> has been ported to the debug DSO.
> 
> The only changes to malloc.c in this change is to add #if IS_IN (libc)
> to not compile some functions into the debug DSO, especially the
> allocator function entry points.

I can't believe this works, but it "recreates" a partial malloc oustside
of libc inside libc_malloc_debug but with calls to the internal routines
for everything else.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>


> The malloc check tunable is now in the debug DSO and has no effect
> when the DSO is not preloaded.
> ---
>  malloc/Makefile                               |   3 +-
>  malloc/Versions                               |  13 ++
>  malloc/arena.c                                |  17 +-
>  malloc/hooks.c                                |  17 +-
>  malloc/malloc-check.c                         |  63 +++---
>  malloc/malloc-debug.c                         | 181 ++++++++++++++++--
>  malloc/malloc.c                               |  35 ++--
>  sysdeps/aarch64/Makefile                      |   3 +
>  .../mach/hurd/i386/libc_malloc_debug.abilist  |   7 +
>  .../linux/aarch64/libc_malloc_debug.abilist   |   7 +
>  .../linux/alpha/libc_malloc_debug.abilist     |   7 +
>  .../sysv/linux/arc/libc_malloc_debug.abilist  |   7 +
>  .../linux/arm/be/libc_malloc_debug.abilist    |   7 +
>  .../linux/arm/le/libc_malloc_debug.abilist    |   7 +
>  .../sysv/linux/csky/libc_malloc_debug.abilist |   7 +
>  .../sysv/linux/hppa/libc_malloc_debug.abilist |   7 +
>  .../sysv/linux/i386/libc_malloc_debug.abilist |   7 +
>  .../sysv/linux/ia64/libc_malloc_debug.abilist |   7 +
>  .../m68k/coldfire/libc_malloc_debug.abilist   |   7 +
>  .../m68k/m680x0/libc_malloc_debug.abilist     |   7 +
>  .../microblaze/be/libc_malloc_debug.abilist   |   7 +
>  .../microblaze/le/libc_malloc_debug.abilist   |   7 +
>  .../mips/mips32/fpu/libc_malloc_debug.abilist |   7 +
>  .../mips32/nofpu/libc_malloc_debug.abilist    |   7 +
>  .../mips/mips64/n32/libc_malloc_debug.abilist |   7 +
>  .../mips/mips64/n64/libc_malloc_debug.abilist |   7 +
>  .../linux/nios2/libc_malloc_debug.abilist     |   7 +
>  .../powerpc32/fpu/libc_malloc_debug.abilist   |   7 +
>  .../powerpc32/nofpu/libc_malloc_debug.abilist |   7 +
>  .../powerpc64/be/libc_malloc_debug.abilist    |   7 +
>  .../powerpc64/le/libc_malloc_debug.abilist    |   7 +
>  .../riscv/rv32/libc_malloc_debug.abilist      |   7 +
>  .../riscv/rv64/libc_malloc_debug.abilist      |   7 +
>  .../s390/s390-32/libc_malloc_debug.abilist    |   7 +
>  .../s390/s390-64/libc_malloc_debug.abilist    |   7 +
>  .../linux/sh/be/libc_malloc_debug.abilist     |   7 +
>  .../linux/sh/le/libc_malloc_debug.abilist     |   7 +
>  .../sparc/sparc32/libc_malloc_debug.abilist   |   7 +
>  .../sparc/sparc64/libc_malloc_debug.abilist   |   7 +
>  .../linux/x86_64/64/libc_malloc_debug.abilist |   7 +
>  .../x86_64/x32/libc_malloc_debug.abilist      |   7 +
>  41 files changed, 482 insertions(+), 81 deletions(-)
> 
> diff --git a/malloc/Makefile b/malloc/Makefile
> index c0dbe04b57..c9504d0916 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -133,7 +133,7 @@ test-extras = \
>  libmemusage-routines = memusage
>  libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
>  
> -libc_malloc_debug-routines = malloc-debug
> +libc_malloc_debug-routines = malloc-debug $(sysdep_malloc_debug_routines)

OK.

>  libc_malloc_debug-inhibit-o = $(filter-out .os,$(object-suffixes))
>  
>  $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
> @@ -250,6 +250,7 @@ tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
>  
>  tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
>  
> +CPPFLAGS-malloc-debug.c += -DUSE_TCACHE=0

OK, build the internal malloc implementations without tcache.

>  ifeq ($(experimental-malloc),yes)
>  CPPFLAGS-malloc.c += -DUSE_TCACHE=1
>  else
> diff --git a/malloc/Versions b/malloc/Versions
> index 71d933de19..2961d0796d 100644
> --- a/malloc/Versions
> +++ b/malloc/Versions
> @@ -119,13 +119,26 @@ libc_malloc_debug {
>      mprobe;
>      mtrace;
>      muntrace;
> +
> +    mallinfo;
> +    malloc_set_state;
> +    malloc_stats;
> +    malloc_trim;
> +    malloc_usable_size;
> +    mallopt;
>    }
>    GLIBC_2.2 {
>      mcheck_check_all;
>      mcheck_pedantic;
>      posix_memalign;
>    }
> +  GLIBC_2.10 {
> +    malloc_info;
> +  }
>    GLIBC_2.16 {
>      aligned_alloc;
>    }
> +  GLIBC_2.33 {
> +    mallinfo2;
> +  }
>  }
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 840426f9fb..edcaa8816d 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -79,7 +79,9 @@ static __thread mstate thread_arena attribute_tls_model_ie;
>     acquired after free_list_lock has been acquired.  */
>  
>  __libc_lock_define_initialized (static, free_list_lock);
> +#if IS_IN (libc)
>  static size_t narenas = 1;
> +#endif
>  static mstate free_list;
>  
>  /* list_lock prevents concurrent writes to the next member of struct
> @@ -207,14 +209,6 @@ __malloc_fork_unlock_child (void)
>  }
>  
>  #if HAVE_TUNABLES
> -static void
> -TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
> -{
> -  int32_t value = (int32_t) valp->numval;
> -  if (value != 0)
> -    __malloc_check_init ();
> -}
> -
>  # define TUNABLE_CALLBACK_FNDECL(__name, __type) \
>  static inline int do_ ## __name (__type value);				      \
>  static void									      \
> @@ -309,7 +303,7 @@ ptmalloc_init (void)
>      }
>  #endif
>  
> -#ifdef SHARED
> +#if defined SHARED && IS_IN (libc)
>    /* In case this libc copy is in a non-default namespace, never use
>       brk.  Likewise if dlopened from statically linked program.  The
>       generic sbrk implementation also enforces this, but it is not
> @@ -323,7 +317,6 @@ ptmalloc_init (void)
>    malloc_init_state (&main_arena);
>  
>  #if HAVE_TUNABLES
> -  TUNABLE_GET (check, int32_t, TUNABLE_CALLBACK (set_mallopt_check));
>    TUNABLE_GET (top_pad, size_t, TUNABLE_CALLBACK (set_top_pad));
>    TUNABLE_GET (perturb, int32_t, TUNABLE_CALLBACK (set_perturb_byte));
>    TUNABLE_GET (mmap_threshold, size_t, TUNABLE_CALLBACK (set_mmap_threshold));
> @@ -401,8 +394,6 @@ ptmalloc_init (void)
>              }
>          }
>      }
> -  if (s && s[0] != '\0' && s[0] != '0')
> -    __malloc_check_init ();
>  #endif
>  }
>  
> @@ -672,6 +663,7 @@ heap_trim (heap_info *heap, size_t pad)
>  
>  /* Create a new arena with initial size "size".  */
>  
> +#if IS_IN (libc)
>  /* If REPLACED_ARENA is not NULL, detach it from this thread.  Must be
>     called while free_list_lock is held.  */
>  static void
> @@ -947,6 +939,7 @@ arena_get_retry (mstate ar_ptr, size_t bytes)
>  
>    return ar_ptr;
>  }
> +#endif
>  
>  void
>  __malloc_arena_thread_freeres (void)
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index 8e9fefe6c3..af72b622c5 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -39,10 +39,10 @@ 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"
> -
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
>  
> +static void ptmalloc_init (void);
> +
>  /* Support for restoring dumped heaps contained in historic Emacs
>     executables.  The heap saving feature (malloc_get_state) is no
>     longer implemented in this version of glibc, but we have a heap
> @@ -106,14 +106,11 @@ malloc_set_state (void *msptr)
>       must be called before the first call into the malloc subsytem
>       (usually via __malloc_initialize_hook).  pthread_create always
>       calls calloc and thus must be called only afterwards, so there
> -     cannot be more than one thread when we reach this point.  */
> -
> -  /* Disable the malloc hooks (and malloc checking).  */
> -  __malloc_hook = NULL;
> -  __realloc_hook = NULL;
> -  __free_hook = NULL;
> -  __memalign_hook = NULL;
> -  using_malloc_checking = 0;
> +     cannot be more than one thread when we reach this point.  Since the
> +     initialization hook is now in libc_malloc_debug.so, we may need to
> +     initialize malloc.  */
> +  if (!__malloc_initialized)
> +    ptmalloc_init ();
>  
>    /* Patch the dumped heap.  We no longer try to integrate into the
>       existing heap.  Instead, we mark the existing chunks as mmapped.
> diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
> index dcab880510..a444c7478e 100644
> --- a/malloc/malloc-check.c
> +++ b/malloc/malloc-check.c
> @@ -17,20 +17,8 @@
>     License along with the GNU C Library; see the file COPYING.LIB.  If
>     not, see <https://www.gnu.org/licenses/>.  */
>  
> -
> -/* Whether we are using malloc checking.  */
> -static int using_malloc_checking;
> -
> -/* Activate a standard set of debugging hooks. */
> -void
> -__malloc_check_init (void)
> -{
> -  using_malloc_checking = 1;
> -  __malloc_hook = malloc_check;
> -  __free_hook = free_check;
> -  __realloc_hook = realloc_check;
> -  __memalign_hook = memalign_check;
> -}
> +#define __mremap mremap
> +#include "malloc.c"

OK. Wow, this is a complete compilation of malloc.

>  
>  /* When memory is tagged, the checking data is stored in the user part
>     of the chunk.  We can't rely on the user not having modified the
> @@ -63,14 +51,13 @@ magicbyte (const void *p)
>     must reach it with this iteration, otherwise we have witnessed a memory
>     corruption.  */
>  static size_t
> -malloc_check_get_size (mchunkptr p)
> +malloc_check_get_size (void *mem)
>  {
>    size_t size;
>    unsigned char c;
> +  mchunkptr p = mem2chunk (mem);
>    unsigned char magic = magicbyte (p);
>  
> -  assert (using_malloc_checking == 1);
> -
>    for (size = CHUNK_HDR_SZ + memsize (p) - 1;
>         (c = *SAFE_CHAR_OFFSET (p, size)) != magic;
>         size -= c)
> @@ -203,7 +190,7 @@ top_check (void)
>  }
>  
>  static void *
> -malloc_check (size_t sz, const void *caller)
> +malloc_check (size_t sz)
>  {
>    void *victim;
>    size_t nb;
> @@ -222,7 +209,7 @@ malloc_check (size_t sz, const void *caller)
>  }
>  
>  static void
> -free_check (void *mem, const void *caller)
> +free_check (void *mem)
>  {
>    mchunkptr p;
>  
> @@ -256,7 +243,7 @@ free_check (void *mem, const void *caller)
>  }
>  
>  static void *
> -realloc_check (void *oldmem, size_t bytes, const void *caller)
> +realloc_check (void *oldmem, size_t bytes)
>  {
>    INTERNAL_SIZE_T chnb;
>    void *newmem = 0;
> @@ -269,11 +256,11 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
>        return NULL;
>      }
>    if (oldmem == 0)
> -    return malloc_check (bytes, NULL);
> +    return malloc_check (bytes);
>  
>    if (bytes == 0)
>      {
> -      free_check (oldmem, NULL);
> +      free_check (oldmem);
>        return NULL;
>      }
>  
> @@ -348,12 +335,12 @@ invert:
>  }
>  
>  static void *
> -memalign_check (size_t alignment, size_t bytes, const void *caller)
> +memalign_check (size_t alignment, size_t bytes)
>  {
>    void *mem;
>  
>    if (alignment <= MALLOC_ALIGNMENT)
> -    return malloc_check (bytes, NULL);
> +    return malloc_check (bytes);
>  
>    if (alignment < MINSIZE)
>      alignment = MINSIZE;
> @@ -363,14 +350,14 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
>    if (alignment > SIZE_MAX / 2 + 1)
>      {
>        __set_errno (EINVAL);
> -      return 0;
> +      return NULL;
>      }
>  
>    /* Check for overflow.  */
>    if (bytes > SIZE_MAX - alignment - MINSIZE)
>      {
>        __set_errno (ENOMEM);
> -      return 0;
> +      return NULL;
>      }
>  
>    /* Make sure alignment is power of 2.  */
> @@ -388,3 +375,27 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
>    __libc_lock_unlock (main_arena.mutex);
>    return mem2mem_check (tag_new_usable (mem), bytes);
>  }
> +
> +static void
> +TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
> +{
> +  int32_t value = (int32_t) valp->numval;
> +  if (value != 0)
> +    __malloc_debug_enable (MALLOC_CHECK_HOOK);
> +}
> +
> +static bool
> +initialize_malloc_check (void)
> +{
> +  /* This is the copy of the malloc initializer that we pulled in along with
> +     malloc-check.  This does not affect any of the libc malloc structures.  */
> +  ptmalloc_init ();
> +#if HAVE_TUNABLES
> +  TUNABLE_GET (check, int32_t, TUNABLE_CALLBACK (set_mallopt_check));
> +#else
> +  const char *s = secure_getenv ("MALLOC_CHECK_");
> +  if (s && s[0] != '\0' && s[0] != '0')
> +    __malloc_debug_enable (MALLOC_CHECK_HOOK);
> +#endif
> +  return __is_malloc_debug_enabled (MALLOC_CHECK_HOOK);
> +}
> diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
> index 9942124e02..6e5402f20c 100644
> --- a/malloc/malloc-debug.c
> +++ b/malloc/malloc-debug.c
> @@ -50,6 +50,7 @@ enum malloc_debug_hooks
>    MALLOC_NONE_HOOK = 0,
>    MALLOC_MCHECK_HOOK = 1 << 0, /* mcheck()  */
>    MALLOC_MTRACE_HOOK = 1 << 1, /* mtrace()  */
> +  MALLOC_CHECK_HOOK = 1 << 2,  /* MALLOC_CHECK_ or glibc.malloc.check.  */
>  };
>  static unsigned __malloc_debugging_hooks;
>  
> @@ -73,6 +74,7 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
>  
>  #include "mcheck.c"
>  #include "mtrace.c"
> +#include "malloc-check.c"
>  
>  extern void (*__malloc_initialize_hook) (void);
>  compat_symbol_reference (libc, __malloc_initialize_hook,
> @@ -105,13 +107,18 @@ generic_hook_ini (void)
>    __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));
> +
> +  /* malloc check does not quite co-exist with libc malloc, so initialize
> +     either on or the other.  */
> +  if (!initialize_malloc_check ())
> +    /* 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;
>  }
>  
> @@ -149,10 +156,11 @@ __debug_malloc (size_t bytes)
>  
>    void *victim = NULL;
>    size_t orig_bytes = bytes;
> -  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> -      || !malloc_mcheck_before (&bytes, &victim))
> +  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> +       || !malloc_mcheck_before (&bytes, &victim)))
>      {
> -      victim = __libc_malloc (bytes);
> +      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> +		? malloc_check (bytes) : __libc_malloc (bytes));
>      }
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = malloc_mcheck_after (victim, orig_bytes);
> @@ -175,10 +183,12 @@ __debug_free (void *mem)
>  
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
>      mem = free_mcheck (mem);
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    free_check (mem);
> +  else
> +    __libc_free (mem);
>    if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
>      free_mtrace (mem, RETURN_ADDRESS (0));
> -
> -  __libc_free (mem);
>  }
>  strong_alias (__debug_free, free)
>  
> @@ -193,10 +203,12 @@ __debug_realloc (void *oldmem, size_t 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))
> +  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> +       || !realloc_mcheck_before (&oldmem, &bytes, &oldsize, &victim)))
>      {
> -      victim = __libc_realloc (oldmem, bytes);
> +      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> +		? realloc_check (oldmem, bytes)
> +		: __libc_realloc (oldmem, bytes));
>      }
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = realloc_mcheck_after (victim, oldmem, orig_bytes,
> @@ -219,10 +231,12 @@ _debug_mid_memalign (size_t alignment, size_t bytes, const void *address)
>    void *victim = NULL;
>    size_t orig_bytes = bytes;
>  
> -  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> -      || !memalign_mcheck_before (alignment, &bytes, &victim))
> +  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> +       || !memalign_mcheck_before (alignment, &bytes, &victim)))
>      {
> -      victim = __libc_memalign (alignment, bytes);
> +      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> +		? memalign_check (alignment, bytes)
> +		: __libc_memalign (alignment, bytes));
>      }
>    if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && victim != NULL)
>      victim = memalign_mcheck_after (victim, alignment, orig_bytes);
> @@ -316,10 +330,11 @@ __debug_calloc (size_t nmemb, size_t size)
>    size_t orig_bytes = bytes;
>    void *victim = NULL;
>  
> -  if (!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> -      || !malloc_mcheck_before (&bytes, &victim))
> +  if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
> +       || !malloc_mcheck_before (&bytes, &victim)))
>      {
> -      victim = __libc_malloc (bytes);
> +      victim = (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> +		? malloc_check (bytes) : __libc_malloc (bytes));
>      }
>    if (victim != NULL)
>      {
> @@ -333,3 +348,135 @@ __debug_calloc (size_t nmemb, size_t size)
>    return victim;
>  }
>  strong_alias (__debug_calloc, calloc)
> +
> +size_t
> +malloc_usable_size (void *mem)
> +{
> +  return (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> +	  ? malloc_check_get_size (mem) : musable (mem));
> +}
> +
> +#define LIBC_SYMBOL(sym) libc_ ## sym
> +#define SYMHANDLE(sym) sym ## _handle
> +
> +#define LOAD_SYM(sym) ({ \
> +  static void *SYMHANDLE (sym);						      \
> +  if (SYMHANDLE (sym) == NULL)						      \
> +    SYMHANDLE (sym) = dlsym (RTLD_NEXT, #sym);				      \
> +  SYMHANDLE (sym);							      \
> +})
> +
> +int
> +malloc_info (int options, FILE *fp)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __malloc_info (options, fp);
> +
> +  int (*LIBC_SYMBOL (malloc_info)) (int, FILE *) = LOAD_SYM (malloc_info);
> +  if (LIBC_SYMBOL (malloc_info) == NULL)
> +    return -1;
> +
> +  return LIBC_SYMBOL (malloc_info) (options, fp);
> +}
> +
> +int
> +mallopt (int param_number, int value)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __libc_mallopt (param_number, value);
> +
> +  int (*LIBC_SYMBOL (mallopt)) (int, int) = LOAD_SYM (mallopt);
> +  if (LIBC_SYMBOL (mallopt) == NULL)
> +    return 0;
> +
> +  return LIBC_SYMBOL (mallopt) (param_number, value);
> +}
> +
> +void
> +malloc_stats (void)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __malloc_stats ();
> +
> +  void (*LIBC_SYMBOL (malloc_stats)) (void) = LOAD_SYM (malloc_stats);
> +  if (LIBC_SYMBOL (malloc_stats) == NULL)
> +    return;
> +
> +  LIBC_SYMBOL (malloc_stats) ();
> +}
> +
> +struct mallinfo2
> +mallinfo2 (void)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __libc_mallinfo2 ();
> +
> +  struct mallinfo2 (*LIBC_SYMBOL (mallinfo2)) (void) = LOAD_SYM (mallinfo2);
> +  if (LIBC_SYMBOL (mallinfo2) == NULL)
> +    {
> +      struct mallinfo2 ret = {0};
> +      return ret;
> +    }
> +
> +  return LIBC_SYMBOL (mallinfo2) ();
> +}
> +
> +struct mallinfo
> +mallinfo (void)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __libc_mallinfo ();
> +
> +  struct mallinfo (*LIBC_SYMBOL (mallinfo)) (void) = LOAD_SYM (mallinfo);
> +  if (LIBC_SYMBOL (mallinfo) == NULL)
> +    {
> +      struct mallinfo ret = {0};
> +      return ret;
> +    }
> +
> +  return LIBC_SYMBOL (mallinfo) ();
> +}
> +
> +int
> +malloc_trim (size_t s)
> +{
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return __malloc_trim (s);
> +
> +  int (*LIBC_SYMBOL (malloc_trim)) (size_t) = LOAD_SYM (malloc_trim);
> +  if (LIBC_SYMBOL (malloc_trim) == NULL)
> +    return 0;
> +
> +  return LIBC_SYMBOL (malloc_trim) (s);
> +}
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
> +int
> +malloc_set_state (void *msptr)
> +{
> +  if (ms->magic != MALLOC_STATE_MAGIC)
> +    return -1;
> +
> +  /* Must fail if the major version is too high. */
> +  if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
> +    return -2;
> +
> +  if (debug_initialized && __is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return -1;
> +
> +  /* It's not too late, so disable MALLOC_CHECK_ and hand off to the libc
> +     malloc_set_state.  */
> +  __malloc_debug_disable (MALLOC_CHECK_HOOK);
> +  __malloc_hook = NULL;
> +  __realloc_hook = NULL;
> +  __free_hook = NULL;
> +  __memalign_hook = NULL;
> +
> +  int (*LIBC_SYMBOL (malloc_set_state)) (void *) = LOAD_SYM (malloc_set_state);
> +  if (LIBC_SYMBOL (malloc_set_state) == NULL)
> +    return -1;
> +
> +  return LIBC_SYMBOL (malloc_set_state) (msptr);
> +}
> +compat_symbol (libc, malloc_set_state, malloc_set_state, GLIBC_2_0);
> +#endif
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index ed0316e690..b8fcb2f2d3 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -288,6 +288,7 @@
>  #define MALLOC_DEBUG 0
>  #endif
>  
> +#if IS_IN (libc)
>  #ifndef NDEBUG
>  # define __assert_fail(assertion, file, line, function)			\
>  	 __malloc_assert(assertion, file, line, function)
> @@ -307,6 +308,7 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
>    abort ();
>  }
>  #endif
> +#endif
>  
>  #if USE_TCACHE
>  /* We want 64 entries.  This is an arbitrary limit, which tunables can reduce.  */
> @@ -592,6 +594,7 @@ tag_at (void *ptr)
>  
>  /* ---------- description of public routines ------------ */
>  
> +#if IS_IN (libc)
>  /*
>    malloc(size_t n)
>    Returns a pointer to a newly allocated chunk of at least n bytes, or null
> @@ -815,6 +818,7 @@ void     __malloc_stats(void);
>    POSIX wrapper like memalign(), checking for validity of size.
>  */
>  int      __posix_memalign(void **, size_t, size_t);
> +#endif /* IS_IN (libc) */
>  
>  /* mallopt tuning options */
>  
> @@ -1106,24 +1110,17 @@ static void     _int_free(mstate, mchunkptr, int);
>  static void*  _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
>  			   INTERNAL_SIZE_T);
>  static void*  _int_memalign(mstate, size_t, size_t);
> +#if IS_IN (libc)
>  static void*  _mid_memalign(size_t, size_t, void *);
> +#endif
>  
>  static void malloc_printerr(const char *str) __attribute__ ((noreturn));
>  
> -static void* mem2mem_check(void *p, size_t sz);
> -static void top_check(void);
>  static void munmap_chunk(mchunkptr p);
>  #if HAVE_MREMAP
>  static mchunkptr mremap_chunk(mchunkptr p, size_t new_size);
>  #endif
>  
> -static void*   malloc_check(size_t sz, const void *caller);
> -static void      free_check(void* mem, const void *caller);
> -static void*   realloc_check(void* oldmem, size_t bytes,
> -			       const void *caller);
> -static void*   memalign_check(size_t alignment, size_t bytes,
> -				const void *caller);
> -
>  /* ------------------ MMAP support ------------------  */
>  
>  
> @@ -2385,7 +2382,9 @@ do_check_malloc_state (mstate av)
>  
>  
>  /* ----------------- Support for debugging hooks -------------------- */
> +#if IS_IN (libc)
>  #include "hooks.c"
> +#endif
>  
>  
>  /* ----------- Routines dealing with system allocation -------------- */
> @@ -3186,6 +3185,7 @@ tcache_thread_shutdown (void)
>  
>  #endif /* !USE_TCACHE  */
>  
> +#if IS_IN (libc)
>  void *
>  __libc_malloc (size_t bytes)
>  {
> @@ -3686,6 +3686,7 @@ __libc_calloc (size_t n, size_t elem_size)
>  
>    return mem;
>  }
> +#endif /* IS_IN (libc) */
>  
>  /*
>     ------------------------------ malloc ------------------------------
> @@ -5054,9 +5055,6 @@ musable (void *mem)
>  
>        p = mem2chunk (mem);
>  
> -      if (__builtin_expect (using_malloc_checking == 1, 0))
> -	return malloc_check_get_size (p);
> -
>        if (chunk_is_mmapped (p))
>  	{
>  	  if (DUMPED_MAIN_ARENA_CHUNK (p))
> @@ -5072,7 +5070,7 @@ musable (void *mem)
>    return 0;
>  }
>  
> -
> +#if IS_IN (libc)
>  size_t
>  __malloc_usable_size (void *m)
>  {
> @@ -5081,12 +5079,12 @@ __malloc_usable_size (void *m)
>    result = musable (m);
>    return result;
>  }
> +#endif
>  
>  /*
>     ------------------------------ mallinfo ------------------------------
>     Accumulate malloc statistics for arena AV into M.
>   */
> -
>  static void
>  int_mallinfo (mstate av, struct mallinfo2 *m)
>  {
> @@ -5585,10 +5583,15 @@ extern char **__libc_argv attribute_hidden;
>  static void
>  malloc_printerr (const char *str)
>  {
> +#if IS_IN (libc)
>    __libc_message (do_abort, "%s\n", str);
> +#else
> +  __libc_fatal (str);
> +#endif
>    __builtin_unreachable ();
>  }
>  
> +#if IS_IN (libc)
>  /* We need a wrapper function for one of the additions of POSIX.  */
>  int
>  __posix_memalign (void **memptr, size_t alignment, size_t size)
> @@ -5618,6 +5621,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
>    return ENOMEM;
>  }
>  weak_alias (__posix_memalign, posix_memalign)
> +#endif
>  
>  
>  int
> @@ -5821,9 +5825,9 @@ __malloc_info (int options, FILE *fp)
>  
>    return 0;
>  }
> +#if IS_IN (libc)
>  weak_alias (__malloc_info, malloc_info)
>  
> -
>  strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
>  strong_alias (__libc_free, __free) strong_alias (__libc_free, free)
>  strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc)
> @@ -5841,6 +5845,7 @@ strong_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
>  weak_alias (__malloc_stats, malloc_stats)
>  weak_alias (__malloc_usable_size, malloc_usable_size)
>  weak_alias (__malloc_trim, malloc_trim)
> +#endif
>  
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
>  compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index 1099f1d657..7c66fb97aa 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -42,5 +42,8 @@ ifeq ($(subdir),misc)
>  sysdep_headers += sys/ifunc.h
>  sysdep_routines += __mtag_tag_zero_region \
>  		   __mtag_tag_region
> +endif
>  
> +ifeq ($(subdir),malloc)
> +sysdep_malloc_debug_routines = __mtag_tag_zero_region __mtag_tag_region
>  endif
> diff --git a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> index 798d3ae8a3..c1ff86dfbd 100644
> --- a/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> +++ b/sysdeps/mach/hurd/i386/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2.6 __free_hook D 0x4
>  GLIBC_2.2.6 __malloc_hook D 0x4
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2.6 malloc F
> +GLIBC_2.2.6 malloc_stats F
> +GLIBC_2.2.6 malloc_trim F
> +GLIBC_2.2.6 malloc_usable_size F
> +GLIBC_2.2.6 mallopt F
>  GLIBC_2.2.6 mcheck F
>  GLIBC_2.2.6 mcheck_check_all F
>  GLIBC_2.2.6 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2.6 posix_memalign F
>  GLIBC_2.2.6 pvalloc F
>  GLIBC_2.2.6 realloc F
>  GLIBC_2.2.6 valloc F
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> index bf543ed1e0..65fb5036bd 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.17 malloc F
> +GLIBC_2.17 malloc_info F
> +GLIBC_2.17 malloc_stats F
> +GLIBC_2.17 malloc_trim F
> +GLIBC_2.17 malloc_usable_size F
> +GLIBC_2.17 mallopt F
>  GLIBC_2.17 mcheck F
>  GLIBC_2.17 mcheck_check_all F
>  GLIBC_2.17 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.17 posix_memalign F
>  GLIBC_2.17 pvalloc F
>  GLIBC_2.17 realloc F
>  GLIBC_2.17 valloc F
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> index fa8beb5e83..bdf3541c24 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc_malloc_debug.abilist
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> index 14bad4f83a..cf9f611403 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.32 malloc F
> +GLIBC_2.32 malloc_info F
> +GLIBC_2.32 malloc_stats F
> +GLIBC_2.32 malloc_trim F
> +GLIBC_2.32 malloc_usable_size F
> +GLIBC_2.32 mallopt F
>  GLIBC_2.32 mcheck F
>  GLIBC_2.32 mcheck_check_all F
>  GLIBC_2.32 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.32 posix_memalign F
>  GLIBC_2.32 pvalloc F
>  GLIBC_2.32 realloc F
>  GLIBC_2.32 valloc F
> +GLIBC_2.33 mallinfo2 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 97b470a989..81be491d53 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc_malloc_debug.abilist
> @@ -1,11 +1,18 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
> +GLIBC_2.33 mallinfo2 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 mallinfo F
>  GLIBC_2.4 malloc F
> +GLIBC_2.4 malloc_stats F
> +GLIBC_2.4 malloc_trim F
> +GLIBC_2.4 malloc_usable_size F
> +GLIBC_2.4 mallopt F
>  GLIBC_2.4 mcheck F
>  GLIBC_2.4 mcheck_check_all F
>  GLIBC_2.4 mcheck_pedantic 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 97b470a989..81be491d53 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc_malloc_debug.abilist
> @@ -1,11 +1,18 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
> +GLIBC_2.33 mallinfo2 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 mallinfo F
>  GLIBC_2.4 malloc F
> +GLIBC_2.4 malloc_stats F
> +GLIBC_2.4 malloc_trim F
> +GLIBC_2.4 malloc_usable_size F
> +GLIBC_2.4 mallopt F
>  GLIBC_2.4 mcheck F
>  GLIBC_2.4 mcheck_check_all F
>  GLIBC_2.4 mcheck_pedantic F
> diff --git a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> index eac818b681..4cd866430b 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.29 malloc F
> +GLIBC_2.29 malloc_info F
> +GLIBC_2.29 malloc_stats F
> +GLIBC_2.29 malloc_trim F
> +GLIBC_2.29 malloc_usable_size F
> +GLIBC_2.29 mallopt F
>  GLIBC_2.29 mcheck F
>  GLIBC_2.29 mcheck_check_all F
>  GLIBC_2.29 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.29 posix_memalign F
>  GLIBC_2.29 pvalloc F
>  GLIBC_2.29 realloc F
>  GLIBC_2.29 valloc F
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> index 88cdf04cbe..22d0bf2d8a 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x4
>  GLIBC_2.2 __malloc_hook D 0x4
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> index 96955644d5..6b3c5bfd0b 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc_malloc_debug.abilist
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> index ee940be29a..6d5574a760 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x8
>  GLIBC_2.2 __malloc_hook D 0x8
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 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 97b470a989..81be491d53 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc_malloc_debug.abilist
> @@ -1,11 +1,18 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
> +GLIBC_2.33 mallinfo2 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 mallinfo F
>  GLIBC_2.4 malloc F
> +GLIBC_2.4 malloc_stats F
> +GLIBC_2.4 malloc_trim F
> +GLIBC_2.4 malloc_usable_size F
> +GLIBC_2.4 mallopt F
>  GLIBC_2.4 mcheck F
>  GLIBC_2.4 mcheck_check_all F
>  GLIBC_2.4 mcheck_pedantic 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 96955644d5..6b3c5bfd0b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc_malloc_debug.abilist
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 48db59ebb1..daa80c4772 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.18 malloc F
> +GLIBC_2.18 malloc_info F
> +GLIBC_2.18 malloc_stats F
> +GLIBC_2.18 malloc_trim F
> +GLIBC_2.18 malloc_usable_size F
> +GLIBC_2.18 mallopt F
>  GLIBC_2.18 mcheck F
>  GLIBC_2.18 mcheck_check_all F
>  GLIBC_2.18 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.18 posix_memalign F
>  GLIBC_2.18 pvalloc F
>  GLIBC_2.18 realloc F
>  GLIBC_2.18 valloc F
> +GLIBC_2.33 mallinfo2 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 48db59ebb1..daa80c4772 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.18 malloc F
> +GLIBC_2.18 malloc_info F
> +GLIBC_2.18 malloc_stats F
> +GLIBC_2.18 malloc_trim F
> +GLIBC_2.18 malloc_usable_size F
> +GLIBC_2.18 mallopt F
>  GLIBC_2.18 mcheck F
>  GLIBC_2.18 mcheck_check_all F
>  GLIBC_2.18 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.18 posix_memalign F
>  GLIBC_2.18 pvalloc F
>  GLIBC_2.18 realloc F
>  GLIBC_2.18 valloc F
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 fa8beb5e83..bdf3541c24 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> index 3a3f0a2861..ce6c5f7631 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.21 malloc F
> +GLIBC_2.21 malloc_info F
> +GLIBC_2.21 malloc_stats F
> +GLIBC_2.21 malloc_trim F
> +GLIBC_2.21 malloc_usable_size F
> +GLIBC_2.21 mallopt F
>  GLIBC_2.21 mcheck F
>  GLIBC_2.21 mcheck_check_all F
>  GLIBC_2.21 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.21 posix_memalign F
>  GLIBC_2.21 pvalloc F
>  GLIBC_2.21 realloc F
>  GLIBC_2.21 valloc F
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 9e0c7a48c0..7f134f9b48 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,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.3 __free_hook D 0x8
>  GLIBC_2.3 __malloc_hook D 0x8
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.3 malloc F
> +GLIBC_2.3 malloc_stats F
> +GLIBC_2.3 malloc_trim F
> +GLIBC_2.3 malloc_usable_size F
> +GLIBC_2.3 mallopt F
>  GLIBC_2.3 mcheck F
>  GLIBC_2.3 mcheck_check_all F
>  GLIBC_2.3 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.3 posix_memalign F
>  GLIBC_2.3 pvalloc F
>  GLIBC_2.3 realloc F
>  GLIBC_2.3 valloc F
> +GLIBC_2.33 mallinfo2 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 bf543ed1e0..65fb5036bd 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
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.17 malloc F
> +GLIBC_2.17 malloc_info F
> +GLIBC_2.17 malloc_stats F
> +GLIBC_2.17 malloc_trim F
> +GLIBC_2.17 malloc_usable_size F
> +GLIBC_2.17 mallopt F
>  GLIBC_2.17 mcheck F
>  GLIBC_2.17 mcheck_check_all F
>  GLIBC_2.17 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.17 posix_memalign F
>  GLIBC_2.17 pvalloc F
>  GLIBC_2.17 realloc F
>  GLIBC_2.17 valloc F
> +GLIBC_2.33 mallinfo2 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 e2448d7b83..ff6713a479 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc_malloc_debug.abilist
> @@ -5,7 +5,14 @@ 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 mallinfo F
> +GLIBC_2.33 mallinfo2 F
>  GLIBC_2.33 malloc F
> +GLIBC_2.33 malloc_info F
> +GLIBC_2.33 malloc_stats F
> +GLIBC_2.33 malloc_trim F
> +GLIBC_2.33 malloc_usable_size F
> +GLIBC_2.33 mallopt F
>  GLIBC_2.33 mcheck F
>  GLIBC_2.33 mcheck_check_all F
>  GLIBC_2.33 mcheck_pedantic 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 622ee2e67a..65425a03ee 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc_malloc_debug.abilist
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.27 malloc F
> +GLIBC_2.27 malloc_info F
> +GLIBC_2.27 malloc_stats F
> +GLIBC_2.27 malloc_trim F
> +GLIBC_2.27 malloc_usable_size F
> +GLIBC_2.27 mallopt F
>  GLIBC_2.27 mcheck F
>  GLIBC_2.27 mcheck_check_all F
>  GLIBC_2.27 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.27 posix_memalign F
>  GLIBC_2.27 pvalloc F
>  GLIBC_2.27 realloc F
>  GLIBC_2.27 valloc F
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 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
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 ee940be29a..6d5574a760 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,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x8
>  GLIBC_2.2 __malloc_hook D 0x8
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 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 88cdf04cbe..22d0bf2d8a 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x4
>  GLIBC_2.2 __malloc_hook D 0x4
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 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 88cdf04cbe..22d0bf2d8a 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x4
>  GLIBC_2.2 __malloc_hook D 0x4
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 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 96955644d5..6b3c5bfd0b 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc_malloc_debug.abilist
> @@ -4,7 +4,12 @@ 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 mallinfo F
>  GLIBC_2.0 malloc F
> +GLIBC_2.0 malloc_stats F
> +GLIBC_2.0 malloc_trim F
> +GLIBC_2.0 malloc_usable_size F
> +GLIBC_2.0 mallopt F
>  GLIBC_2.0 mcheck F
>  GLIBC_2.0 memalign F
>  GLIBC_2.0 mprobe F
> @@ -13,7 +18,9 @@ GLIBC_2.0 muntrace F
>  GLIBC_2.0 pvalloc F
>  GLIBC_2.0 realloc F
>  GLIBC_2.0 valloc F
> +GLIBC_2.10 malloc_info 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
> +GLIBC_2.33 mallinfo2 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 ee940be29a..6d5574a760 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc_malloc_debug.abilist
> @@ -1,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2 __free_hook D 0x8
>  GLIBC_2.2 __malloc_hook D 0x8
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2 malloc F
> +GLIBC_2.2 malloc_stats F
> +GLIBC_2.2 malloc_trim F
> +GLIBC_2.2 malloc_usable_size F
> +GLIBC_2.2 mallopt F
>  GLIBC_2.2 mcheck F
>  GLIBC_2.2 mcheck_check_all F
>  GLIBC_2.2 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2 posix_memalign F
>  GLIBC_2.2 pvalloc F
>  GLIBC_2.2 realloc F
>  GLIBC_2.2 valloc F
> +GLIBC_2.33 mallinfo2 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 e734b8f088..3b7b729d64 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,3 +1,4 @@
> +GLIBC_2.10 malloc_info F
>  GLIBC_2.16 aligned_alloc F
>  GLIBC_2.2.5 __free_hook D 0x8
>  GLIBC_2.2.5 __malloc_hook D 0x8
> @@ -5,7 +6,12 @@ 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 mallinfo F
>  GLIBC_2.2.5 malloc F
> +GLIBC_2.2.5 malloc_stats F
> +GLIBC_2.2.5 malloc_trim F
> +GLIBC_2.2.5 malloc_usable_size F
> +GLIBC_2.2.5 mallopt F
>  GLIBC_2.2.5 mcheck F
>  GLIBC_2.2.5 mcheck_check_all F
>  GLIBC_2.2.5 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.2.5 posix_memalign F
>  GLIBC_2.2.5 pvalloc F
>  GLIBC_2.2.5 realloc F
>  GLIBC_2.2.5 valloc F
> +GLIBC_2.33 mallinfo2 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 14efc6602f..91d737a7f8 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
> @@ -5,7 +5,13 @@ 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 mallinfo F
>  GLIBC_2.16 malloc F
> +GLIBC_2.16 malloc_info F
> +GLIBC_2.16 malloc_stats F
> +GLIBC_2.16 malloc_trim F
> +GLIBC_2.16 malloc_usable_size F
> +GLIBC_2.16 mallopt F
>  GLIBC_2.16 mcheck F
>  GLIBC_2.16 mcheck_check_all F
>  GLIBC_2.16 mcheck_pedantic F
> @@ -17,3 +23,4 @@ GLIBC_2.16 posix_memalign F
>  GLIBC_2.16 pvalloc F
>  GLIBC_2.16 realloc F
>  GLIBC_2.16 valloc F
> +GLIBC_2.33 mallinfo2 F
> 

OK.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 09/10] Remove malloc hooks
  2021-07-13  7:38 ` [PATCH v8 09/10] Remove " Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Make malloc hooks symbols compat-only so that new applications cannot
> link against them and remove the declarations from the API.  Also
> remove the unused malloc-hooks.h.
> 
> Finally, mark all symbols in libc_malloc_debug.so as compat so that
> the library cannot be linked against.
> 
> Add a note about the deprecation in NEWS.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  NEWS                  |  10 +++
>  malloc/hooks.c        |   6 +-
>  malloc/malloc-debug.c |  36 ++++++++
>  malloc/malloc-hooks.h |  24 ------
>  malloc/malloc.h       |  16 ----
>  manual/memory.texi    | 191 ++----------------------------------------
>  6 files changed, 57 insertions(+), 226 deletions(-)
>  delete mode 100644 malloc/malloc-hooks.h
> 
> diff --git a/NEWS b/NEWS
> index 0297d14f87..f1685e7d40 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -124,6 +124,16 @@ Deprecated and removed features, and other changes affecting compatibility:
>    features now need to preload a new debugging DSO libc_malloc_debug.so to get
>    this functionality back.
>  
> +* The deprecated memory allocation hooks __malloc_hook, __realloc_hook,
> +  __memalign_hook and __free_hook are now removed from the API.  Compatibility
> +  symbols are present to support legacy programs but new applications can no
> +  longer link to these symbols.  These hooks no longer have any effect on glibc
> +  functionality.  The malloc debugging DSO libc_malloc_debug.so currently
> +  supports hooks and can be preloaded to get this functionality back for older
> +  programs.  However this is a transitional measure and may be removed in a
> +  future release of the GNU C Library.  Users may port away from these hooks by
> +  writing and preloading their own malloc interposition library.

OK.

> +
>  Changes to build and runtime requirements:
>  
>  * On Linux, the shm_open, sem_open, and related functions now expect the
> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index af72b622c5..fff6fe76db 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -32,12 +32,16 @@ void weak_variable (*__after_morecore_hook) (void) = NULL;
>  compat_symbol (libc, __after_morecore_hook, __after_morecore_hook, GLIBC_2_0);
>  void *(*__morecore)(ptrdiff_t);
>  compat_symbol (libc, __morecore, __morecore, GLIBC_2_0);
> -#endif
>  
>  void weak_variable (*__free_hook) (void *, const void *) = NULL;
>  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;
> +compat_symbol (libc, __free_hook, __free_hook, GLIBC_2_0);
> +compat_symbol (libc, __malloc_hook, __malloc_hook, GLIBC_2_0);
> +compat_symbol (libc, __realloc_hook, __realloc_hook, GLIBC_2_0);
> +compat_symbol (libc, __memalign_hook, __memalign_hook, GLIBC_2_0);
> +#endif

OK.

>  
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
>  
> diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
> index 6e5402f20c..ef44546a4e 100644
> --- a/malloc/malloc-debug.c
> +++ b/malloc/malloc-debug.c
> @@ -23,6 +23,7 @@
>  #include <unistd.h>
>  #include <sys/param.h>
>  
> +#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_34)
>  /* Support only the glibc allocators.  */
>  extern void *__libc_malloc (size_t);
>  extern void __libc_free (void *);
> @@ -76,9 +77,11 @@ __malloc_debug_disable (enum malloc_debug_hooks flag)
>  #include "mtrace.c"
>  #include "malloc-check.c"
>  
> +#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
>  extern void (*__malloc_initialize_hook) (void);
>  compat_symbol_reference (libc, __malloc_initialize_hook,
>  			 __malloc_initialize_hook, 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;
> @@ -115,9 +118,11 @@ generic_hook_ini (void)
>         will not try to optimize it away.  */
>      __libc_free (__libc_malloc (0));
>  
> +#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_24)
>    void (*hook) (void) = __malloc_initialize_hook;
>    if (hook != NULL)
>      (*hook)();
> +#endif

OK.

>  
>    debug_initialized = 1;
>  }
> @@ -480,3 +485,34 @@ malloc_set_state (void *msptr)
>  }
>  compat_symbol (libc, malloc_set_state, malloc_set_state, GLIBC_2_0);
>  #endif
> +
> +/* Do not allow linking against the library.  */

OK. Yes! Good idea!

> +compat_symbol (libc_malloc_debug, aligned_alloc, aligned_alloc, GLIBC_2_16);
> +compat_symbol (libc_malloc_debug, calloc, calloc, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, free, free, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mallinfo2, mallinfo2, GLIBC_2_33);
> +compat_symbol (libc_malloc_debug, mallinfo, mallinfo, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, malloc_info, malloc_info, GLIBC_2_10);
> +compat_symbol (libc_malloc_debug, malloc, malloc, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, malloc_stats, malloc_stats, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, malloc_trim, malloc_trim, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, malloc_usable_size, malloc_usable_size,
> +	       GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mallopt, mallopt, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mcheck_check_all, mcheck_check_all,
> +	       GLIBC_2_2);
> +compat_symbol (libc_malloc_debug, mcheck, mcheck, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mcheck_pedantic, mcheck_pedantic, GLIBC_2_2);
> +compat_symbol (libc_malloc_debug, memalign, memalign, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mprobe, mprobe, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, mtrace, mtrace, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, muntrace, muntrace, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, posix_memalign, posix_memalign, GLIBC_2_2);
> +compat_symbol (libc_malloc_debug, pvalloc, pvalloc, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, realloc, realloc, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, valloc, valloc, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, __free_hook, __free_hook, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, __malloc_hook, __malloc_hook, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, __realloc_hook, __realloc_hook, GLIBC_2_0);
> +compat_symbol (libc_malloc_debug, __memalign_hook, __memalign_hook, GLIBC_2_0);
> +#endif
> diff --git a/malloc/malloc-hooks.h b/malloc/malloc-hooks.h
> deleted file mode 100644
> index 0133331b83..0000000000
> --- a/malloc/malloc-hooks.h
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -/* Internal declarations of malloc hooks no longer in the public API.
> -   Copyright (C) 2016-2021 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   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; see the file COPYING.LIB.  If
> -   not, see <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _MALLOC_HOOKS_H
> -#define _MALLOC_HOOKS_H
> -
> -void (*__malloc_initialize_hook) (void);
> -
> -#endif  /* _MALLOC_HOOKS_H */

OK. Gone!

> diff --git a/malloc/malloc.h b/malloc/malloc.h
> index 17ab9ee345..2df0b38050 100644
> --- a/malloc/malloc.h
> +++ b/malloc/malloc.h
> @@ -156,21 +156,5 @@ extern void malloc_stats (void) __THROW;
>  /* Output information about state of allocator to stream FP.  */
>  extern int malloc_info (int __options, FILE *__fp) __THROW;
>  
> -/* Hooks for debugging and user-defined versions. */
> -extern void (*__MALLOC_HOOK_VOLATILE __free_hook) (void *__ptr,
> -                                                   const void *)
> -__MALLOC_DEPRECATED;
> -extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook)(size_t __size,
> -                                                     const void *)
> -__MALLOC_DEPRECATED;
> -extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook)(void *__ptr,
> -                                                      size_t __size,
> -                                                      const void *)
> -__MALLOC_DEPRECATED;
> -extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
> -                                                       size_t __size,
> -                                                       const void *)
> -__MALLOC_DEPRECATED;
> -

OK. Gone!

>  __END_DECLS
>  #endif /* malloc.h */
> diff --git a/manual/memory.texi b/manual/memory.texi
> index 93305f289b..69c8894602 100644
> --- a/manual/memory.texi
> +++ b/manual/memory.texi
> @@ -328,8 +328,6 @@ any time (or never).
>  * Malloc Tunable Parameters::   Use @code{mallopt} to adjust allocation
>                                   parameters.
>  * Heap Consistency Checking::   Automatic checking for errors.
> -* Hooks for Malloc::            You can use these hooks for debugging
> -				 programs that use @code{malloc}.
>  * Statistics of Malloc::        Getting information about how much
>  				 memory your program is using.
>  * Summary of Malloc::           Summary of @code{malloc} and related functions.
> @@ -1392,170 +1390,6 @@ compatibility.  Both @code{MALLOC_CHECK_} and @samp{-lmcheck} should
>  uncover the same bugs - but using @code{MALLOC_CHECK_} you don't need to
>  recompile your application.
>  
> -@node Hooks for Malloc
> -@subsubsection Memory Allocation Hooks
> -@cindex allocation hooks, for @code{malloc}
> -
> -@Theglibc{} lets you modify the behavior of @code{malloc},
> -@code{realloc}, and @code{free} by specifying appropriate hook
> -functions.  You can use these hooks to help you debug programs that use
> -dynamic memory allocation, for example.
> -
> -The hook variables are declared in @file{malloc.h}.
> -@pindex malloc.h
> -
> -@defvar __malloc_hook
> -@standards{GNU, malloc.h}
> -The value of this variable is a pointer to the function that
> -@code{malloc} uses whenever it is called.  You should define this
> -function to look like @code{malloc}; that is, like:
> -
> -@smallexample
> -void *@var{function} (size_t @var{size}, const void *@var{caller})
> -@end smallexample
> -
> -The value of @var{caller} is the return address found on the stack when
> -the @code{malloc} function was called.  This value allows you to trace
> -the memory consumption of the program.
> -@end defvar
> -
> -@defvar __realloc_hook
> -@standards{GNU, malloc.h}
> -The value of this variable is a pointer to function that @code{realloc}
> -uses whenever it is called.  You should define this function to look
> -like @code{realloc}; that is, like:
> -
> -@smallexample
> -void *@var{function} (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
> -@end smallexample
> -
> -The value of @var{caller} is the return address found on the stack when
> -the @code{realloc} function was called.  This value allows you to trace the
> -memory consumption of the program.
> -@end defvar
> -
> -@defvar __free_hook
> -@standards{GNU, malloc.h}
> -The value of this variable is a pointer to function that @code{free}
> -uses whenever it is called.  You should define this function to look
> -like @code{free}; that is, like:
> -
> -@smallexample
> -void @var{function} (void *@var{ptr}, const void *@var{caller})
> -@end smallexample
> -
> -The value of @var{caller} is the return address found on the stack when
> -the @code{free} function was called.  This value allows you to trace the
> -memory consumption of the program.
> -@end defvar
> -
> -@defvar __memalign_hook
> -@standards{GNU, malloc.h}
> -The value of this variable is a pointer to function that @code{aligned_alloc},
> -@code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they
> -are called.  You should define this function to look like @code{aligned_alloc};
> -that is, like:
> -
> -@smallexample
> -void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller})
> -@end smallexample
> -
> -The value of @var{caller} is the return address found on the stack when
> -the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or
> -@code{valloc} functions are called.  This value allows you to trace the
> -memory consumption of the program.
> -@end defvar
> -
> -You must make sure that the function you install as a hook for one of
> -these functions does not call that function recursively without restoring
> -the old value of the hook first!  Otherwise, your program will get stuck
> -in an infinite recursion.  Before calling the function recursively, one
> -should make sure to restore all the hooks to their previous value.  When
> -coming back from the recursive call, all the hooks should be resaved
> -since a hook might modify itself.
> -
> -An issue to look out for is the time at which the hook functions
> -can be safely installed.  If the hook functions call the @code{malloc}-related
> -functions recursively, it is necessary that @code{malloc} has already properly
> -initialized itself at the time when @code{__malloc_hook} etc. is
> -assigned to.  On the other hand, if the hook functions provide a
> -complete @code{malloc} implementation of their own, it is vital that the hooks
> -are assigned to @emph{before} the very first @code{malloc} call has
> -completed, because otherwise a chunk obtained from the ordinary,
> -un-hooked @code{malloc} may later be handed to @code{__free_hook}, for example.
> -
> -Here is an example showing how to use @code{__malloc_hook} and
> -@code{__free_hook} properly.  It installs a function that prints out
> -information every time @code{malloc} or @code{free} is called.  We just
> -assume here that @code{realloc} and @code{memalign} are not used in our
> -program.
> -
> -@smallexample
> -/* Prototypes for __malloc_hook, __free_hook */
> -#include <malloc.h>
> -
> -/* Prototypes for our hooks.  */
> -static void my_init_hook (void);
> -static void *my_malloc_hook (size_t, const void *);
> -static void my_free_hook (void*, const void *);
> -
> -static void
> -my_init (void)
> -@{
> -  old_malloc_hook = __malloc_hook;
> -  old_free_hook = __free_hook;
> -  __malloc_hook = my_malloc_hook;
> -  __free_hook = my_free_hook;
> -@}
> -
> -static void *
> -my_malloc_hook (size_t size, const void *caller)
> -@{
> -  void *result;
> -  /* Restore all old hooks */
> -  __malloc_hook = old_malloc_hook;
> -  __free_hook = old_free_hook;
> -  /* Call recursively */
> -  result = malloc (size);
> -  /* Save underlying hooks */
> -  old_malloc_hook = __malloc_hook;
> -  old_free_hook = __free_hook;
> -  /* @r{@code{printf} might call @code{malloc}, so protect it too.} */
> -  printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
> -  /* Restore our own hooks */
> -  __malloc_hook = my_malloc_hook;
> -  __free_hook = my_free_hook;
> -  return result;
> -@}
> -
> -static void
> -my_free_hook (void *ptr, const void *caller)
> -@{
> -  /* Restore all old hooks */
> -  __malloc_hook = old_malloc_hook;
> -  __free_hook = old_free_hook;
> -  /* Call recursively */
> -  free (ptr);
> -  /* Save underlying hooks */
> -  old_malloc_hook = __malloc_hook;
> -  old_free_hook = __free_hook;
> -  /* @r{@code{printf} might call @code{free}, so protect it too.} */
> -  printf ("freed pointer %p\n", ptr);
> -  /* Restore our own hooks */
> -  __malloc_hook = my_malloc_hook;
> -  __free_hook = my_free_hook;
> -@}
> -
> -main ()
> -@{
> -  my_init ();
> -  @dots{}
> -@}
> -@end smallexample
> -
> -The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by
> -installing such hooks.
> -
>  @c __morecore, __after_morecore_hook are undocumented
>  @c It's not clear whether to document them.
>  
> @@ -1690,19 +1524,6 @@ Tell @code{malloc} to perform occasional consistency checks on
>  dynamically allocated memory, and to call @var{abortfn} when an
>  inconsistency is found.  @xref{Heap Consistency Checking}.
>  
> -@item void *(*__malloc_hook) (size_t @var{size}, const void *@var{caller})
> -A pointer to a function that @code{malloc} uses whenever it is called.
> -
> -@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
> -A pointer to a function that @code{realloc} uses whenever it is called.
> -
> -@item void (*__free_hook) (void *@var{ptr}, const void *@var{caller})
> -A pointer to a function that @code{free} uses whenever it is called.
> -
> -@item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller})
> -A pointer to a function that @code{aligned_alloc}, @code{memalign},
> -@code{posix_memalign} and @code{valloc} use whenever they are called.
> -
>  @item struct mallinfo2 mallinfo2 (void)
>  Return information about the current dynamic memory usage.
>  @xref{Statistics of Malloc}.
> @@ -1737,7 +1558,7 @@ penalties for the program if the debugging mode is not enabled.
>  
>  @deftypefun void mtrace (void)
>  @standards{GNU, mcheck.h}
> -@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
> +@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
>  @c Like the mcheck hooks, these are not designed with thread safety in
>  @c mind, because the hook pointers are temporarily modified without
>  @c regard to other threads, signals or cancellation.
> @@ -1768,10 +1589,10 @@ with the SUID or SGID bit set.
>  
>  If the named file is successfully opened, @code{mtrace} installs special
>  handlers for the functions @code{malloc}, @code{realloc}, and
> -@code{free} (@pxref{Hooks for Malloc}).  From then on, all uses of these
> -functions are traced and protocolled into the file.  There is now of
> -course a speed penalty for all calls to the traced functions so tracing
> -should not be enabled during normal use.
> +@code{free}.  From then on, all uses of these functions are traced and
> +protocolled into the file.  There is now of course a speed penalty for all
> +calls to the traced functions so tracing should not be enabled during normal
> +use.
>  
>  This function is a GNU extension and generally not available on other
>  systems.  The prototype can be found in @file{mcheck.h}.
> @@ -1779,7 +1600,7 @@ systems.  The prototype can be found in @file{mcheck.h}.
>  
>  @deftypefun void muntrace (void)
>  @standards{GNU, mcheck.h}
> -@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
> +@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
>  
>  @c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
>  @c  fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
> 

OK.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057]
  2021-07-13  7:38 ` [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057] Siddhesh Poyarekar via Libc-alpha
@ 2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
  0 siblings, 0 replies; 39+ messages in thread
From: Carlos O'Donell via Libc-alpha @ 2021-07-17 22:04 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer

On 7/13/21 3:38 AM, Siddhesh Poyarekar wrote:
> Interpose malloc_usable_size to return the correct mcheck value for
> malloc_usable_size.

OK for 2.34.

Tested without regression on x86_64 and i686.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  malloc/Makefile       | 4 +---
>  malloc/malloc-debug.c | 8 ++++++--
>  malloc/mcheck-impl.c  | 6 ++++++
>  3 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/malloc/Makefile b/malloc/Makefile
> index c9504d0916..04c6b09949 100644
> --- a/malloc/Makefile
> +++ b/malloc/Makefile
> @@ -83,7 +83,7 @@ ifeq ($(have-GLIBC_2.24)$(build-shared),yesyes)
>  # the tests expect specific internal behavior that is changed due to linking to
>  # libmcheck.a.
>  tests-exclude-mcheck = tst-mallocstate \
> -	tst-safe-linking tst-malloc-usable \
> +	tst-safe-linking \

OK.

>  	tst-malloc-backtrace \
>  	tst-malloc-fork-deadlock \
>  	tst-malloc-stats-cancellation \
> @@ -92,8 +92,6 @@ tests-exclude-mcheck = tst-mallocstate \
>  	tst-malloc-thread-fail \
>  	tst-malloc-usable-tunables \
>  	tst-malloc_info \
> -	tst-pvalloc-fortify \
> -	tst-reallocarray \

OK.

>  	tst-compathooks-off tst-compathooks-on
>  
>  tests-mcheck = $(filter-out $(tests-exclude-mcheck), $(tests))
> diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
> index ef44546a4e..7968787ad6 100644
> --- a/malloc/malloc-debug.c
> +++ b/malloc/malloc-debug.c
> @@ -357,8 +357,12 @@ strong_alias (__debug_calloc, calloc)
>  size_t
>  malloc_usable_size (void *mem)
>  {
> -  return (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK)
> -	  ? malloc_check_get_size (mem) : musable (mem));
> +  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
> +    return mcheck_usable_size (mem);
> +  if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
> +    return malloc_check_get_size (mem);
> +
> +  return musable (mem);

OK.

>  }
>  
>  #define LIBC_SYMBOL(sym) libc_ ## sym
> diff --git a/malloc/mcheck-impl.c b/malloc/mcheck-impl.c
> index 8857e6b179..6597a290a6 100644
> --- a/malloc/mcheck-impl.c
> +++ b/malloc/mcheck-impl.c
> @@ -404,3 +404,9 @@ __mcheck_initialize (void (*func) (enum mcheck_status), bool in_pedantic)
>    pedantic = in_pedantic;
>    return 0;
>  }
> +
> +static int
> +mcheck_usable_size (struct hdr *h)
> +{
> +  return (h - 1)->size;
> +}

OK.

> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2021-07-17 22:12 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-13  7:38 [PATCH v8 00/10] malloc hooks removal Siddhesh Poyarekar via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 01/10] Make mcheck tests conditional on GLIBC_2.24 or earlier Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 02/10] Remove __after_morecore_hook Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 03/10] Remove __morecore and __default_morecore Siddhesh Poyarekar via Libc-alpha
2021-07-14  7:01   ` Siddhesh Poyarekar
2021-07-14 12:54     ` Guillaume Morin
2021-07-14 14:13       ` Siddhesh Poyarekar
2021-07-14 16:42         ` Guillaume Morin
2021-07-14 17:15           ` Carlos O'Donell via Libc-alpha
2021-07-14 17:42             ` Adhemerval Zanella via Libc-alpha
2021-07-14 18:37               ` Guillaume Morin
2021-07-14 18:48               ` Siddhesh Poyarekar
2021-07-14 18:31             ` Guillaume Morin
2021-07-14 17:32           ` Siddhesh Poyarekar
2021-07-14 18:25             ` Guillaume Morin
2021-07-14 18:43               ` Siddhesh Poyarekar
2021-07-14 18:51                 ` Guillaume Morin
2021-07-17 22:03   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 04/10] Move malloc hooks into a compat DSO Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 05/10] mcheck: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
2021-07-13 15:47   ` H.J. Lu via Libc-alpha
2021-07-14  2:44     ` Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 06/10] Simplify __malloc_initialized Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 07/10] mtrace: Wean away from malloc hooks Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 08/10] glibc.malloc.check: " Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 09/10] Remove " Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13  7:38 ` [PATCH v8 10/10] mcheck Fix malloc_usable_size [BZ #22057] Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:04   ` Carlos O'Donell via Libc-alpha
2021-07-13 14:48 ` [PATCH v8 00/10] malloc hooks removal H.J. Lu via Libc-alpha
2021-07-13 15:41   ` Siddhesh Poyarekar via Libc-alpha
2021-07-17 22:03 ` Carlos O'Donell via Libc-alpha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).