@@ -44,8 +44,6 @@
/***************************************************************************/
-#define top(ar_ptr) ((ar_ptr)->top)
-
/* A heap is a single contiguous memory region holding (coalesceable)
malloc_chunks. It is allocated with mmap() and always starts at an
address aligned to HEAP_MAX_SIZE. */
@@ -21,35 +21,107 @@
corrupt pointer is detected: do nothing (0), print an error message
(1), or call abort() (2). */
-/* Hooks for debugging versions. The initial hooks just call the
- initialization routine, then do the normal work. */
+/* 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. */
+
+#if HAVE_MALLOC_INIT_HOOK
+void (*__malloc_initialize_hook) (void) __attribute__ ((nocommon));
+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 *) = NULL;
+void *weak_variable (*__realloc_hook)
+ (void *__ptr, size_t __size, const void *) = NULL;
+void *weak_variable (*__memalign_hook)
+ (size_t __alignment, size_t __size, const void *) = NULL;
+
+static void ptmalloc_init (void);
-static void *
-malloc_hook_ini (size_t sz, const void *caller)
+#include "malloc-check.c"
+
+static __always_inline bool
+_malloc_debug_before (size_t bytes, void **victimp, const void *address)
{
- __malloc_hook = NULL;
- ptmalloc_init ();
- return __libc_malloc (sz);
+ _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))
+ {
+ *victimp = (*hook)(bytes, address);
+ return true;
+ }
+ return false;
}
-static void *
-realloc_hook_ini (void *ptr, size_t sz, const void *caller)
+static __always_inline bool
+_free_debug_before (void *mem, const void *address)
{
- __malloc_hook = NULL;
- __realloc_hook = NULL;
- ptmalloc_init ();
- return __libc_realloc (ptr, sz);
+ void (*hook) (void *, const void *)
+ = atomic_forced_read (__free_hook);
+ if (__builtin_expect (hook != NULL, 0))
+ {
+ (*hook)(mem, address);
+ return true;
+ }
+ return false;
}
-static void *
-memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
+static __always_inline bool
+_realloc_debug_before (void *oldmem, size_t bytes, void **victimp,
+ const void *address)
{
- __memalign_hook = NULL;
- ptmalloc_init ();
- return __libc_memalign (alignment, sz);
+ void *(*hook) (void *, size_t, const void *) =
+ atomic_forced_read (__realloc_hook);
+ if (__builtin_expect (hook != NULL, 0))
+ {
+ *victimp = (*hook)(oldmem, bytes, address);
+ return true;
+ }
+
+ return false;
}
-#include "malloc-check.c"
+static __always_inline bool
+_memalign_debug_before (size_t alignment, size_t bytes, void **victimp,
+ const void *address)
+{
+ void *(*hook) (size_t, size_t, const void *) =
+ atomic_forced_read (__memalign_hook);
+ if (__builtin_expect (hook != NULL, 0))
+ {
+ *victimp = (*hook)(alignment, bytes, address);
+ return true;
+ }
+ return false;
+}
+
+static __always_inline bool
+_calloc_debug_before (size_t bytes, void **victimp, const void *address)
+{
+ void *(*hook) (size_t, const void *) =
+ atomic_forced_read (__malloc_hook);
+ if (__builtin_expect (hook != NULL, 0))
+ {
+ *victimp = (*hook)(bytes, address);
+ if (*victimp != NULL)
+ memset (*victimp, 0, bytes);
+ return true;
+ }
+ return false;
+}
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25)
@@ -61,6 +61,7 @@
/* The corresponding bit mask value. */
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
+#define top(ar_ptr) ((ar_ptr)->top)
/* Called in the parent process before a fork. */
void __malloc_fork_lock_parent (void) attribute_hidden;
@@ -2013,30 +2013,6 @@ static void malloc_consolidate (mstate);
# 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) __attribute__ ((nocommon));
-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;
void weak_variable (*__after_morecore_hook) (void) = NULL;
/* This function is called from the arena shutdown hook, to free the
@@ -2065,6 +2041,9 @@ free_perturb (char *p, size_t n)
#include <stap-probe.h>
+/* ----------------- Support for debugging hooks -------------------- */
+#include "hooks.c"
+
/* ------------------- Support for multiple arenas -------------------- */
#include "arena.c"
@@ -2425,10 +2404,6 @@ do_check_malloc_state (mstate av)
#endif
-/* ----------------- Support for debugging hooks -------------------- */
-#include "hooks.c"
-
-
/* ----------- Routines dealing with system allocation -------------- */
/*
@@ -3225,13 +3200,12 @@ __libc_malloc (size_t bytes)
mstate ar_ptr;
void *victim;
- _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
- "PTRDIFF_MAX is not more than half of SIZE_MAX");
+ if (__malloc_initialized < 0)
+ ptmalloc_init ();
+
+ if (_malloc_debug_before (bytes, &victim, RETURN_ADDRESS (0)))
+ return victim;
- void *(*hook) (size_t, const void *)
- = atomic_forced_read (__malloc_hook);
- if (__builtin_expect (hook != NULL, 0))
- return (*hook)(bytes, RETURN_ADDRESS (0));
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes;
@@ -3292,13 +3266,11 @@ __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 (__malloc_initialized < 0)
+ ptmalloc_init ();
+
+ if (_free_debug_before (mem, RETURN_ADDRESS (0)))
+ return;
if (mem == 0) /* free(0) has no effect */
return;
@@ -3351,10 +3323,11 @@ __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_debug_before (oldmem, bytes, &newp, RETURN_ADDRESS (0)))
+ return newp;
#if REALLOC_ZERO_BYTES_FREES
if (bytes == 0 && oldmem != NULL)
@@ -3490,6 +3463,9 @@ void *
__libc_memalign (size_t alignment, size_t bytes)
{
void *address = RETURN_ADDRESS (0);
+ if (__malloc_initialized < 0)
+ ptmalloc_init ();
+
return _mid_memalign (alignment, bytes, address);
}
@@ -3499,10 +3475,8 @@ _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 (_memalign_debug_before (alignment, bytes, &p, address))
+ return p;
/* If we need less alignment than we give anyway, just relay to malloc. */
if (alignment <= MALLOC_ALIGNMENT)
@@ -3612,16 +3586,11 @@ __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;
+ if (__malloc_initialized < 0)
+ ptmalloc_init ();
- return memset (mem, 0, sz);
- }
+ if (_calloc_debug_before (sz, &mem, RETURN_ADDRESS (0)))
+ return mem;
MAYBE_INIT_TCACHE ();