[2/2] malloc: aarch64: Add ifuncs for malloc functions

Message ID 20260728161215.1512331-3-yury.khrustalev@arm.com (mailing list archive)
State Superseded
Headers
Series aarch64: Re-apply malloc ifuncs |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed

Commit Message

Yury Khrustalev July 28, 2026, 4:12 p.m. UTC
  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 point 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                  |  1 +
 malloc/malloc.c                           | 11 ++-
 sysdeps/aarch64/multiarch/Makefile        |  6 ++
 sysdeps/aarch64/multiarch/malloc-ifuncs.c | 82 +++++++++++++++++++++++
 sysdeps/aarch64/multiarch/malloc-ifuncs.h | 25 +++++++
 sysdeps/generic/malloc-ifuncs.h           | 36 ++++++++++
 6 files changed, 159 insertions(+), 2 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
  

Comments

Yury Khrustalev July 29, 2026, 1:21 p.m. UTC | #1
On Tue, Jul 28, 2026 at 05:12:15PM +0100, Yury Khrustalev wrote:
> 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 point 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                  |  1 +
>  malloc/malloc.c                           | 11 ++-
>  sysdeps/aarch64/multiarch/Makefile        |  6 ++
>  sysdeps/aarch64/multiarch/malloc-ifuncs.c | 82 +++++++++++++++++++++++
>  sysdeps/aarch64/multiarch/malloc-ifuncs.h | 25 +++++++
>  sysdeps/generic/malloc-ifuncs.h           | 36 ++++++++++
>  6 files changed, 159 insertions(+), 2 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

To work around this bug in GDB [1], it is possible to apply this GDB
patch from Muhammad [2]. It cleanly applies to GDB master as of now and
provides a fix that resolves the issue with malloc being ifunc.

Although, [2] is not a final fix, it resolves the immediate problem and
is stable (passes regression). This might be useful after malloc ifuncs
are merged to Glibc master and before GDB is fixed.

[1]: https://sourceware.org/bugzilla/show_bug.cgi?id=34330
[2]: https://inbox.sourceware.org/gdb-patches/20260630110443.12900-1-muhammad.kamran@arm.com/

Thanks,
Yury
  
Adhemerval Zanella July 29, 2026, 6:59 p.m. UTC | #2
On 29/07/26 10:21, Yury Khrustalev wrote:
> On Tue, Jul 28, 2026 at 05:12:15PM +0100, Yury Khrustalev wrote:
>> 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 point 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                  |  1 +
>>  malloc/malloc.c                           | 11 ++-
>>  sysdeps/aarch64/multiarch/Makefile        |  6 ++
>>  sysdeps/aarch64/multiarch/malloc-ifuncs.c | 82 +++++++++++++++++++++++
>>  sysdeps/aarch64/multiarch/malloc-ifuncs.h | 25 +++++++
>>  sysdeps/generic/malloc-ifuncs.h           | 36 ++++++++++
>>  6 files changed, 159 insertions(+), 2 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
> 
> To work around this bug in GDB [1], it is possible to apply this GDB
> patch from Muhammad [2]. It cleanly applies to GDB master as of now and
> provides a fix that resolves the issue with malloc being ifunc.
> 
> Although, [2] is not a final fix, it resolves the immediate problem and
> is stable (passes regression). This might be useful after malloc ifuncs
> are merged to Glibc master and before GDB is fixed.

The change looks ok and I think it would be good to have it at the start of
the development to have a lot of time for testing.

And what is missing from [2] to be considered a final fix? Are Muhammad aimed
to change how gdb allocates process memory to make the function call (like
using mmap or something else like stack allocation to avoid interfere with
malloc metadata)?

> 
> [1]: https://sourceware.org/bugzilla/show_bug.cgi?id=34330
> [2]: https://inbox.sourceware.org/gdb-patches/20260630110443.12900-1-muhammad.kamran@arm.com/
> 
> Thanks,
> Yury
>
  
Yury Khrustalev July 30, 2026, 2:06 p.m. UTC | #3
On Wed, Jul 29, 2026 at 03:59:32PM -0300, Adhemerval Zanella Netto wrote:
> 
> On 29/07/26 10:21, Yury Khrustalev wrote:
> > On Tue, Jul 28, 2026 at 05:12:15PM +0100, Yury Khrustalev wrote:
> > 
> > ...
> >
> > To work around this bug in GDB [1], it is possible to apply this GDB
> > patch from Muhammad [2]. It cleanly applies to GDB master as of now and
> > provides a fix that resolves the issue with malloc being ifunc.
> > 
> > Although, [2] is not a final fix, it resolves the immediate problem and
> > is stable (passes regression). This might be useful after malloc ifuncs
> > are merged to Glibc master and before GDB is fixed.
> 
> The change looks ok and I think it would be good to have it at the start of
> the development to have a lot of time for testing.
> 
> And what is missing from [2] to be considered a final fix? Are Muhammad aimed
> to change how gdb allocates process memory to make the function call (like
> using mmap or something else like stack allocation to avoid interfere with
> malloc metadata)?

There was a discussion under v2 of Muhammad's patch [1] and we are still
waiting for feedback on v4.

There are several things:

1) When GDB calls an ifunc resolver, it would likely not call it
correctly (i.e. passing both arguments with all the hwcaps and bits
set), so GDB could obtain ifunc implementation that is different from
what the program-under-debug would use.

2) General concern over using program's malloc that will inevitably
change the state of malloc implementation. E.g. what if we are debugging
malloc implementation itself and GDB is changing chunks behind the
scenes?

For 1) it was proposed to use dlsym() which will find correct
implementation of the ifunc however it requires a bit of work (e.g.
allocate memory for dlsym's argument on stack) and not all targets
support dlsym etc. There is work in progress patch for this I think.

For 2) there isn't really a good and easy solution...

[1]: https://inbox.sourceware.org/gdb-patches/20260625152036.6149-1-muhammad.kamran@arm.com/

Thanks,
Yury
  
Wilco Dijkstra July 31, 2026, 11:29 a.m. UTC | #4
Hi Yury,

> 2) General concern over using program's malloc that will inevitably
> change the state of malloc implementation. E.g. what if we are debugging
> malloc implementation itself and GDB is changing chunks behind the
> scenes?

> For 2) there isn't really a good and easy solution...


I'm surprised that it's 2026 and debuggers haven't figured out how not to corrupt
the program they are debugging...

Multiple good solutions have been proposed. Firstly, don't ever implicitly call
malloc() to avoid corrupting user state. By default place strings on the stack and
tell users to use strdup ("string") in the rare case where they want a pointer with
infinite lifetime. This makes it explicit there is an allocation that will affect user
state. One could autoinsert the strdup around strings if a particular setting is enabled.

As mentioned before, GLIBC could provide a special entry point for allocating
small amounts of memory by GDB that doesn't interfere with malloc(). It would
be a reasonable solution for GLIBC, but not all libc's might support it.

Cheers,
Wilco
  
Florian Weimer July 31, 2026, 11:36 a.m. UTC | #5
* Wilco Dijkstra:

> Hi Yury,
>
>> 2) General concern over using program's malloc that will inevitably
>> change the state of malloc implementation. E.g. what if we are debugging
>> malloc implementation itself and GDB is changing chunks behind the
>> scenes?
>
>> For 2) there isn't really a good and easy solution...
>
>
> I'm surprised that it's 2026 and debuggers haven't figured out how not
> to corrupt the program they are debugging...

It's hardly suprising because Linux does not provide a way to make a
system call using the ptrace interface.  I'm pretty sure debuggers
wouldn't bother with calling malloc if they just could make a mmap
system call in the target process to allocate some memory.

Thanks,
Florian
  
Andreas Schwab July 31, 2026, 12:24 p.m. UTC | #6
On Jul 31 2026, Wilco Dijkstra wrote:

> state. One could autoinsert the strdup around strings if a particular setting is enabled.

How is strdup different from malloc?
  
Wilco Dijkstra July 31, 2026, 1:10 p.m. UTC | #7
Hi Andreas,

>> state. One could autoinsert the strdup around strings if a particular setting is enabled.
>
> How is strdup different from malloc?

In that it is both optional and explicit user choice, unlike the malloc
call which can't even be switched off (if it could, the issue with ifuncs
wouldn't be that serious).

Cheers,
Wilco
  
Andreas Schwab July 31, 2026, 1:39 p.m. UTC | #8
On Jul 31 2026, Wilco Dijkstra wrote:

> Hi Andreas,
>
>>> state. One could autoinsert the strdup around strings if a particular setting is enabled.
>>
>> How is strdup different from malloc?
>
> In that it is both optional and explicit user choice, unlike the malloc

Nothing of that makes it is really different.

> call which can't even be switched off (if it could, the issue with ifuncs
> wouldn't be that serious).

The static allocation is required for proper semantics.
  

Patch

diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h
index 4b36a76cf8..29bc3734c6 100644
--- a/malloc/malloc-internal.h
+++ b/malloc/malloc-internal.h
@@ -25,6 +25,7 @@ 
 #include <hugepages.h>
 #include <calloc-clear-memory.h>
 #include <malloc-api.h>
+#include <malloc-ifuncs.h>
 
 /* 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 4866c59e65..5fc35a14f4 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -5168,6 +5168,9 @@  __malloc_info (int options, FILE *fp)
 }
 
 #if IS_IN (libc)
+
+/* See sysdeps/generic/malloc-ifuncs.h for details.  */
+# if !USE_MULTIARCH_MALLOC
 strong_alias (__libc_malloc, malloc)
 strong_alias (__libc_realloc, realloc)
 strong_alias (__libc_free, free)
@@ -5180,6 +5183,7 @@  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)
@@ -5187,11 +5191,14 @@  weak_alias (__libc_mallinfo2, mallinfo2)
 weak_alias (__libc_mallopt, mallopt)
 weak_alias (__malloc_stats, malloc_stats)
 weak_alias (__malloc_trim, malloc_trim)
+
 #endif /* IS_IN (libc) */
 
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
+#if !USE_MULTIARCH_MALLOC
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
 compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);
-#endif
+# endif
+#endif /* !USE_MULTIARCH_MALLOC */
 
 /* ------------------------------------------------------------
    History:
diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
index 6294a70c25..a8a03a0491 100644
--- a/sysdeps/aarch64/multiarch/Makefile
+++ b/sysdeps/aarch64/multiarch/Makefile
@@ -20,3 +20,9 @@  sysdep_routines += \
   strlen_generic \
   # 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..4b5db036ff
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
@@ -0,0 +1,82 @@ 
+/* 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/>.  */
+
+#include "malloc-ifuncs.h"
+
+#if USE_MULTIARCH_MALLOC
+# if IS_IN (libc)
+
+#include <init-arch.h>
+#include <malloc-api.h>
+#include <shlib-compat.h>
+
+libc_ifunc_hidden (__libc_malloc, __libc_malloc_redirect,
+		   __libc_malloc)
+strong_alias (__libc_malloc_redirect, malloc)
+
+libc_ifunc_hidden (__libc_calloc, __libc_calloc_redirect,
+		   __libc_calloc)
+weak_alias (__libc_calloc_redirect, calloc)
+
+libc_ifunc_hidden (__libc_memalign, __libc_memalign_redirect,
+		   __libc_memalign)
+weak_alias (__libc_memalign_redirect, memalign)
+
+libc_ifunc_hidden (__libc_valloc, __libc_valloc_redirect,
+		   __libc_valloc)
+weak_alias (__libc_valloc_redirect, valloc)
+
+libc_ifunc_hidden (__libc_pvalloc, __libc_pvalloc_redirect,
+		   __libc_pvalloc)
+weak_alias (__libc_pvalloc_redirect, pvalloc)
+
+libc_ifunc_hidden (__libc_realloc, __libc_realloc_redirect,
+		   __libc_realloc)
+strong_alias (__libc_realloc_redirect, realloc)
+
+libc_ifunc_hidden (__libc_free, __libc_free_redirect,
+		   __libc_free)
+strong_alias (__libc_free_redirect, free)
+
+libc_ifunc_hidden (__malloc_usable_size, __malloc_usable_size_redirect,
+		   __malloc_usable_size)
+weak_alias (__malloc_usable_size_redirect, malloc_usable_size)
+
+libc_ifunc_hidden (__posix_memalign, __posix_memalign_redirect,
+		   __posix_memalign)
+weak_alias (__posix_memalign_redirect, posix_memalign)
+
+libc_ifunc_hidden (__aligned_alloc, __aligned_alloc_redirect,
+		   __aligned_alloc)
+weak_alias (__aligned_alloc_redirect, aligned_alloc)
+
+libc_ifunc_hidden (__free_sized, __free_sized_redirect,
+		   __free_sized)
+weak_alias (__free_sized_redirect, free_sized)
+
+libc_ifunc_hidden (__free_aligned_sized, __free_aligned_sized_redirect,
+		   __free_aligned_sized)
+weak_alias (__free_aligned_sized_redirect, free_aligned_sized)
+
+# endif /* IS_IN (libc) */
+
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
+compat_symbol (libc, __libc_free_redirect, cfree, GLIBC_2_0);
+# endif
+
+#endif /* #if USE_MULTIARCH_MALLOC */
diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.h b/sysdeps/aarch64/multiarch/malloc-ifuncs.h
new file mode 100644
index 0000000000..abd5d3ef19
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/malloc-ifuncs.h
@@ -0,0 +1,25 @@ 
+/* 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
+
+/* AArch64 target provides ifuncs for malloc functions.  */
+#define USE_MULTIARCH_MALLOC 1
+
+#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..8fe88af95e
--- /dev/null
+++ b/sysdeps/generic/malloc-ifuncs.h
@@ -0,0 +1,36 @@ 
+/* 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 that support GNU ifuncs should define this macro
+   if they provide ifuncs for malloc functions.
+
+   When USE_MULTIARCH_MALLOC is defined as 1, 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
+*/
+#define USE_MULTIARCH_MALLOC 0
+
+#endif /* _GENERIC_MALLOC_IFUNCS_H */