11/* malloc_hook.c - Provides low level hooks for malloc/free
22 * Copyright 2023 - chris.rohlf@gmail.com */
33
4- #include "iso_alloc.h"
5- #include "iso_alloc_internal.h"
4+ /* This file must be included from iso_alloc_interfaces.c so that
5+ * alias targets (iso_alloc, iso_free, etc.) are defined in the same
6+ * translation unit. When compiled directly the guard
7+ * below produces an empty translation unit with no effect. */
8+ // clang-format off
9+ #if !defined(ISO_IN_INTERFACES_C )
10+ #error "malloc_hook.c must be included from iso_alloc_interfaces.c (so aliases can work)"
11+ #endif
12+
13+ #include "iso_alloc_hook.h"
614
715/* The MALLOC_HOOK configuration allows us to hook the usual
816 * malloc interfaces and redirect them to the iso_alloc API.
1321 */
1422#if MALLOC_HOOK
1523
16- EXTERNAL_API void * __libc_malloc (size_t s ) {
17- return iso_alloc (s );
18- }
24+ /* malloc/free/calloc/realloc and their __libc_ variants are
25+ * direct linker aliases for the iso_ equivalents on GCC >= 9
26+ * and Clang >= 10 (see iso_alloc_hook.h). This propagates all
27+ * function attributes (malloc, alloc_size, nothrow, etc.) from
28+ * the iso_ symbol to the exported symbol via copy(fun), and
29+ * eliminates the wrapper call entirely.
30+ *
31+ * Functions with differing signatures or custom logic (posix_memalign,
32+ * aligned_alloc, memalign, malloc_size, malloc_good_size) remain
33+ * as wrapper functions. */
1934
20- EXTERNAL_API void * malloc (size_t s ) {
21- return iso_alloc (s );
22- }
35+ EXTERNAL_API void * __libc_malloc (size_t s ) ISO_FORWARD1 (iso_alloc , s )
36+ EXTERNAL_API void * malloc (size_t s ) ISO_FORWARD1 (iso_alloc , s )
2337
24- EXTERNAL_API void __libc_free (void * p ) {
25- iso_free (p );
26- }
38+ EXTERNAL_API void __libc_free (void * p ) ISO_FORWARD0 (iso_free , p )
39+ EXTERNAL_API void free (void * p ) ISO_FORWARD0 (iso_free , p )
2740
28- EXTERNAL_API void free (void * p ) {
29- iso_free (p );
30- }
41+ EXTERNAL_API void * __libc_calloc (size_t n , size_t s ) ISO_FORWARD2 (iso_calloc , n , s )
42+ EXTERNAL_API void * calloc (size_t n , size_t s ) ISO_FORWARD2 (iso_calloc , n , s )
3143
32- EXTERNAL_API void * __libc_calloc (size_t n , size_t s ) {
33- return iso_calloc (n , s );
34- }
44+ EXTERNAL_API void * __libc_realloc (void * p , size_t s ) ISO_FORWARD2 (iso_realloc , p , s )
45+ EXTERNAL_API void * realloc (void * p , size_t s ) ISO_FORWARD2 (iso_realloc , p , s )
3546
36- EXTERNAL_API void * calloc (size_t n , size_t s ) {
37- return iso_calloc (n , s );
38- }
39-
40- EXTERNAL_API void * __libc_realloc (void * p , size_t s ) {
41- return iso_realloc (p , s );
42- }
43-
44- EXTERNAL_API void * realloc (void * p , size_t s ) {
45- return iso_realloc (p , s );
46- }
47-
48- EXTERNAL_API void * __libc_reallocarray (void * p , size_t n , size_t s ) {
49- return iso_reallocarray (p , n , s );
50- }
51-
52- EXTERNAL_API void * reallocarray (void * p , size_t n , size_t s ) {
53- return iso_reallocarray (p , n , s );
54- }
47+ EXTERNAL_API void * __libc_reallocarray (void * p , size_t n , size_t s ) ISO_FORWARD3 (iso_reallocarray , p , n , s )
48+ EXTERNAL_API void * reallocarray (void * p , size_t n , size_t s ) ISO_FORWARD3 (iso_reallocarray , p , n , s )
5549
5650EXTERNAL_API int __posix_memalign (void * * r , size_t a , size_t s ) {
5751 if (is_pow2 (a ) == false) {
@@ -104,9 +98,8 @@ EXTERNAL_API size_t malloc_good_size(size_t size) {
10498 return ALIGN_SZ_UP (size );
10599}
106100#else
107- EXTERNAL_API size_t malloc_usable_size (void * ptr ) {
108- return iso_chunksz (ptr );
109- }
101+ /* On Linux (non-Android) malloc_usable_size takes void* matching iso_chunksz */
102+ EXTERNAL_API size_t malloc_usable_size (void * ptr ) ISO_FORWARD1 (iso_chunksz , ptr )
110103#endif
111104
112105static void * libc_malloc (size_t s , const void * caller ) {
@@ -129,3 +122,4 @@ void (*__free_hook)(void *, const void *) = &libc_free;
129122void * (* __memalign_hook )(size_t , size_t , const void * ) = & libc_memalign ;
130123#endif
131124#endif
125+ // clang-format on
0 commit comments