[PATCH v3 1/1] malloc: aarch64: Add ifuncs for malloc functions

Yury Khrustalev yury.khrustalev@arm.com
Sun May 31 16:13:22 GMT 2026


Introduce ifuncs and resolvers for functions pertinent to the
malloc interface on the AArch64 target: malloc, calloc, free,
realloc, memalign, valloc, pvalloc, posix_memalign, aligned_alloc,
free_sized, free_aligned_sized, malloc_usable_size.

A target can define the USE_MULTIARCH_MALLOC macro. In this case
it must provide alternative aliases for the malloc functions that
point to the ifuncs.

This implementation respects the --disable-multi-arch configure
flag. If multi-arch support is disabled, the generic aliases
are used on aarch64.

This patch contains aarch64-specific resolvers. At this moment they
return core implementations but in the future they can be changed
to support for features, e.g. to handle memory tagging.
---
 malloc/malloc-internal.h                  |   3 +
 malloc/malloc.c                           |  42 ++++++--
 sysdeps/aarch64/multiarch/Makefile        |  10 +-
 sysdeps/aarch64/multiarch/malloc-ifuncs.c | 119 ++++++++++++++++++++++
 sysdeps/aarch64/multiarch/malloc-ifuncs.h |  61 +++++++++++
 sysdeps/generic/malloc-ifuncs.h           |  37 +++++++
 6 files changed, 264 insertions(+), 8 deletions(-)
 create mode 100644 sysdeps/aarch64/multiarch/malloc-ifuncs.c
 create mode 100644 sysdeps/aarch64/multiarch/malloc-ifuncs.h
 create mode 100644 sysdeps/generic/malloc-ifuncs.h

diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h
index a6340bfd88..04ebe93ad8 100644
--- a/malloc/malloc-internal.h
+++ b/malloc/malloc-internal.h
@@ -24,6 +24,9 @@
 #include <malloc-size.h>
 #include <hugepages.h>
 #include <calloc-clear-memory.h>
+#if defined(USE_MULTIARCH)
+# include <malloc-ifuncs.h>
+#endif
 
 /* Called in the parent process before a fork.  */
 void __malloc_fork_lock_parent (void) attribute_hidden;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 18fe48e001..674daa1dd5 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -499,6 +499,7 @@ libc_hidden_proto (__libc_free)
   set to zero.
 */
 void*  __libc_calloc(size_t, size_t);
+libc_hidden_proto (__libc_calloc)
 
 /*
   realloc(void* p, size_t n)
@@ -551,6 +552,7 @@ libc_hidden_proto (__libc_memalign)
   size of the system. If the pagesize is unknown, 4096 is used.
 */
 void*  __libc_valloc(size_t);
+libc_hidden_proto (__libc_valloc)
 
 
 
@@ -585,6 +587,7 @@ struct mallinfo __libc_mallinfo(void);
   round up n to nearest pagesize.
  */
 void*  __libc_pvalloc(size_t);
+libc_hidden_proto (__libc_pvalloc)
 
 /*
   malloc_trim(size_t pad);
@@ -628,6 +631,7 @@ int      __malloc_trim(size_t);
 
 */
 size_t   __malloc_usable_size(void*);
+libc_hidden_proto (__malloc_usable_size)
 
 /*
   malloc_stats();
@@ -657,6 +661,7 @@ void     __malloc_stats(void);
   POSIX wrapper like memalign(), checking for validity of size.
 */
 int      __posix_memalign(void **, size_t, size_t);
+libc_hidden_proto (__posix_memalign)
 #endif /* IS_IN (libc) */
 
 /*
@@ -3320,8 +3325,11 @@ libc_hidden_def (__libc_memalign)
 
 /* For ISO C17.  */
 void *
-weak_function
-aligned_alloc (size_t alignment, size_t bytes)
+__aligned_alloc (size_t alignment, size_t bytes);
+libc_hidden_proto (__aligned_alloc)
+
+void *
+__aligned_alloc (size_t alignment, size_t bytes)
 {
 /* Starting with ISO C17 the standard requires an error for alignments
    that are not supported.  Only integral powers of 2 are valid.  */
@@ -3333,11 +3341,15 @@ aligned_alloc (size_t alignment, size_t bytes)
 
   return _mid_memalign (alignment, bytes);
 }
+libc_hidden_def (__aligned_alloc)
 
 /* For ISO C23.  */
 void
-weak_function
-free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
+__free_sized (void *ptr, __attribute_maybe_unused__ size_t size);
+libc_hidden_proto (__free_sized)
+
+void
+__free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
 {
   /* We do not perform validation that size is the same as the original
      requested size at this time. We leave that to the sanitizers.  We
@@ -3346,11 +3358,16 @@ free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
 
   free (ptr);
 }
+libc_hidden_def (__free_sized)
 
 /* For ISO C23.  */
 void
-weak_function
-free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
+__free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
+                    __attribute_maybe_unused__ size_t size);
+libc_hidden_proto (__free_aligned_sized)
+
+void
+__free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
                     __attribute_maybe_unused__ size_t size)
 {
   /* We do not perform validation that size and alignment is the same as
@@ -3360,6 +3377,7 @@ free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
 
   free (ptr);
 }
+libc_hidden_def (__free_aligned_sized)
 
 static void *
 _mid_memalign (size_t alignment, size_t bytes)
@@ -3408,6 +3426,7 @@ __libc_valloc (size_t bytes)
 {
   return _mid_memalign (GLRO (dl_pagesize), bytes);
 }
+libc_hidden_def (__libc_valloc)
 
 void *
 __libc_pvalloc (size_t bytes)
@@ -3425,6 +3444,7 @@ __libc_pvalloc (size_t bytes)
 
   return _mid_memalign (pagesize, rounded_bytes & -pagesize);
 }
+libc_hidden_def (__libc_pvalloc)
 
 static void * __attribute_noinline__
 __libc_calloc2 (size_t sz)
@@ -3551,6 +3571,7 @@ __libc_calloc (size_t n, size_t elem_size)
 #endif
   return __libc_calloc2 (bytes);
 }
+libc_hidden_def (__libc_calloc)
 #endif /* IS_IN (libc) */
 
 /*
@@ -4547,6 +4568,7 @@ __malloc_usable_size (void *m)
     return 0;
   return musable (m);
 }
+libc_hidden_def (__malloc_usable_size)
 #endif /* IS_IN (libc) */
 
 /*
@@ -5074,6 +5096,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
   *memptr = mem;
   return 0;
 }
+libc_hidden_def (__posix_memalign)
 #endif /* IS_IN (libc) */
 
 
@@ -5236,6 +5259,9 @@ __malloc_info (int options, FILE *fp)
 }
 
 #if IS_IN (libc)
+
+/* See sysdeps/generic/malloc-ifuncs.h for details.  */
+# if !defined (USE_MULTIARCH_MALLOC)
 strong_alias (__libc_malloc, malloc)
 strong_alias (__libc_realloc, realloc)
 strong_alias (__libc_free, free)
@@ -5245,6 +5271,10 @@ weak_alias (__posix_memalign, posix_memalign)
 weak_alias (__libc_valloc, valloc)
 weak_alias (__libc_pvalloc, pvalloc)
 weak_alias (__malloc_usable_size, malloc_usable_size)
+weak_alias (__aligned_alloc, aligned_alloc)
+weak_alias (__free_sized, free_sized)
+weak_alias (__free_aligned_sized, free_aligned_sized)
+#endif /* !USE_MULTIARCH_MALLOC */
 
 weak_alias (__malloc_info, malloc_info)
 weak_alias (__libc_mallinfo, mallinfo)
diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
index 38952655b1..ccb6e2c514 100644
--- a/sysdeps/aarch64/multiarch/Makefile
+++ b/sysdeps/aarch64/multiarch/Makefile
@@ -18,5 +18,11 @@ sysdep_routines += \
   memset_zva64 \
   strlen_asimd \
   strlen_generic \
-# sysdep_routines
-endif
+  # sysdep_routines
+endif # ifeq ($(subdir),string)
+
+ifeq ($(subdir),malloc)
+sysdep_routines += \
+  malloc-ifuncs
+  # sysdep_routines
+endif # ifeq ($(subdir),malloc)
diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.c b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
new file mode 100644
index 0000000000..aa221b04b7
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
@@ -0,0 +1,119 @@
+/* Code for ifunc resolvers for malloc: aarch64 version.
+   Copyright (C) 2026 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/>.  */
+
+#if IS_IN (libc)
+
+#include <stdint.h>
+#include <malloc-ifuncs.h>
+
+/* Macros for defining ifunc resolvers for malloc functions.  */
+#define IFUNC_RESOLVER_NAME(fn) fn ## _resolver
+#define STR(x) #x
+#define XSTR(x) STR(x)
+#define IFUNC_PROTO(fn) \
+  __typeof (fn) fn ## _ifunc \
+  __attribute__ ((ifunc (XSTR(IFUNC_RESOLVER_NAME(fn)))))
+#define IFUNC_RESOLVER(fn, ...) \
+  static __attribute_used__ \
+  __typeof (fn) *IFUNC_RESOLVER_NAME(fn) (__VA_ARGS__)
+
+IFUNC_PROTO (__libc_malloc);
+IFUNC_RESOLVER (__libc_malloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_malloc;
+}
+strong_alias (__libc_malloc_ifunc, malloc)
+
+IFUNC_PROTO (__libc_calloc);
+IFUNC_RESOLVER (__libc_calloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_calloc;
+}
+weak_alias (__libc_calloc_ifunc, calloc)
+
+IFUNC_PROTO (__libc_memalign);
+IFUNC_RESOLVER (__libc_memalign, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_memalign;
+}
+weak_alias (__libc_memalign_ifunc, memalign)
+
+IFUNC_PROTO (__libc_valloc);
+IFUNC_RESOLVER (__libc_valloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_valloc;
+}
+weak_alias (__libc_valloc_ifunc, valloc)
+
+IFUNC_PROTO (__libc_pvalloc);
+IFUNC_RESOLVER (__libc_pvalloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_pvalloc;
+}
+weak_alias (__libc_pvalloc_ifunc, pvalloc)
+
+IFUNC_PROTO (__libc_realloc);
+IFUNC_RESOLVER (__libc_realloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_realloc;
+}
+strong_alias (__libc_realloc_ifunc, realloc)
+
+IFUNC_PROTO (__libc_free);
+IFUNC_RESOLVER (__libc_free, uint64_t arg0, uint64_t arg1[])
+{
+  return __libc_free;
+}
+strong_alias (__libc_free_ifunc, free)
+
+IFUNC_PROTO (__malloc_usable_size);
+IFUNC_RESOLVER (__malloc_usable_size, uint64_t arg0, uint64_t arg1[])
+{
+  return __malloc_usable_size;
+}
+weak_alias (__malloc_usable_size_ifunc, malloc_usable_size)
+
+IFUNC_PROTO (__posix_memalign);
+IFUNC_RESOLVER (__posix_memalign, uint64_t arg0, uint64_t arg1[])
+{
+  return __posix_memalign;
+}
+weak_alias (__posix_memalign_ifunc, posix_memalign)
+
+IFUNC_PROTO (__aligned_alloc);
+IFUNC_RESOLVER (__aligned_alloc, uint64_t arg0, uint64_t arg1[])
+{
+  return __aligned_alloc;
+}
+weak_alias (__aligned_alloc_ifunc, aligned_alloc)
+
+IFUNC_PROTO (__free_sized);
+IFUNC_RESOLVER (__free_sized, uint64_t arg0, uint64_t arg1[])
+{
+  return __free_sized;
+}
+weak_alias (__free_sized_ifunc, free_sized)
+
+IFUNC_PROTO (__free_aligned_sized);
+IFUNC_RESOLVER (__free_aligned_sized, uint64_t arg0, uint64_t arg1[])
+{
+  return __free_aligned_sized;
+}
+weak_alias (__free_aligned_sized_ifunc, free_aligned_sized)
+
+#endif /* IS_IN (libc) */
diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.h b/sysdeps/aarch64/multiarch/malloc-ifuncs.h
new file mode 100644
index 0000000000..98e913d49c
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/malloc-ifuncs.h
@@ -0,0 +1,61 @@
+/* Definitions for ifunc resolvers for malloc: aarch64 version.
+   Copyright (C) 2026 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/>.  */
+
+#ifndef _AARCH64_MALLOC_IFUNCS_H
+#define _AARCH64_MALLOC_IFUNCS_H
+
+#define USE_MULTIARCH_MALLOC 1
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+
+/* Core implementations of malloc functions.  An ifunc resolver must
+   use this implementations as a fallback option.  Other implementations
+   may internally call these core function.  */
+void *__libc_malloc (size_t);
+libc_hidden_proto (__libc_malloc)
+void *__libc_calloc (size_t, size_t);
+libc_hidden_proto (__libc_calloc)
+void *__libc_memalign (size_t, size_t);
+libc_hidden_proto (__libc_memalign)
+void *__libc_valloc (size_t);
+libc_hidden_proto (__libc_valloc)
+void *__libc_pvalloc (size_t);
+libc_hidden_proto (__libc_pvalloc)
+void *__libc_realloc (void *, size_t);
+libc_hidden_proto (__libc_realloc)
+void __libc_free (void *);
+libc_hidden_proto (__libc_free)
+size_t __malloc_usable_size (void *);
+libc_hidden_proto (__malloc_usable_size)
+
+/* For additions of POSIX.  */
+int __posix_memalign (void **, size_t, size_t);
+libc_hidden_proto (__posix_memalign)
+
+/* For ISO C17.  */
+void *__aligned_alloc (size_t, size_t);
+libc_hidden_proto (__aligned_alloc)
+
+/* For ISO C23.  */
+void __free_sized (void *, size_t);
+libc_hidden_proto (__free_sized)
+void __free_aligned_sized (void *, size_t, size_t);
+libc_hidden_proto (__free_aligned_sized)
+
+#endif /* _AARCH64_MALLOC_IFUNCS_H */
diff --git a/sysdeps/generic/malloc-ifuncs.h b/sysdeps/generic/malloc-ifuncs.h
new file mode 100644
index 0000000000..aedc56ae33
--- /dev/null
+++ b/sysdeps/generic/malloc-ifuncs.h
@@ -0,0 +1,37 @@
+/* Definitions for ifunc resolvers for malloc: generic version.
+   Copyright (C) 2026 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/>.  */
+
+#ifndef _GENERIC_MALLOC_IFUNCS_H
+#define _GENERIC_MALLOC_IFUNCS_H
+
+/* Targets should define this macro if they provide ifuncs for
+   malloc functions.  When USE_MULTIARCH_MALLOC is defined, the
+   following functions should be implemented via ifuncs:
+
+     malloc, calloc, free, realloc
+     memalign, valloc, pvalloc
+     posix_memalign
+     malloc_usable_size
+     aligned_alloc, free_sized, free_aligned_sized
+
+*/
+#if defined(USE_MULTIARCH_MALLOC) || !defined(USE_MULTIARCH)
+# undef USE_MULTIARCH_MALLOC
+#endif
+
+#endif /* GENERIC_MALLOC_IFUNCS_H */
-- 
2.47.3



More information about the Libc-alpha mailing list