[2/2] aarch64: Add workaround for GDB bug handling string literals
Checks
| Context |
Check |
Description |
| redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
| redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
| linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
fail
|
Test failed
|
Commit Message
When GDB evaluates an expression in the inferior, it first
creates a copy of the string using malloc. For this malloc
call, GDB was not tracking properly if the malloc symbol is
actually an IFUNC resolver. This means that the IFUNC
resolver gets called like the real malloc function.
This change adds a kludge to detect this, which prevents GDB
from overwriting the __libc_malloc code with the user-supplied
string literal.
---
sysdeps/aarch64/multiarch/malloc-ifuncs.c | 60 +++++++++++++++++------
1 file changed, 46 insertions(+), 14 deletions(-)
Comments
* Florian
On Mon, Jun 29, 2026 at 11:07:13PM +0200, Florian Weimer wrote:
> When GDB evaluates an expression in the inferior, it first
> creates a copy of the string using malloc. For this malloc
> call, GDB was not tracking properly if the malloc symbol is
> actually an IFUNC resolver. This means that the IFUNC
> resolver gets called like the real malloc function.
>
> This change adds a kludge to detect this, which prevents GDB
> from overwriting the __libc_malloc code with the user-supplied
> string literal.
>
> ...
>
> diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.c b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
> index 648fb617de..3552168ecd 100644
>
> ...
>
> +/* Return true if the resolver function has been called through GDB.
> + This used below to determine if GDB incorrectly calls the malloc
> + IFUNC resolver instead of the resolver result. The trampoline
> + address is either on the stack, or the kernel-provided entry point,
> + depending on architecture.
> +
> + A fixed GDB will get the malloc address from the GOT. Calling
> + malloc before relocation processing is complete should use the
> + ld.so malloc, which does not involve an IFUNC. */
> +static inline bool
> +called_from_gdb (uintptr_t return_address, uintptr_t stack_frame)
> +{
> +#ifdef SHARED
> + /* Assume that the stack grows downwards. */
> + if (stack_frame <= return_address && return_address <= stack_frame + 128)
> + return true;
> +
> + /* GDB uses the kernel-provided entry point on some architectures
> + for the trampoline. */
> + if (return_address == GLRO(dl_entry))
> + return true;
> +#endif
> + return false;
> +}
Although this does fix the regressions in GDB testsuite, I think this is
a wrong approach and we should not do this.
Thanks,
Yury
On 30/06/26 06:47, Yury Khrustalev wrote:
> * Florian
>
> On Mon, Jun 29, 2026 at 11:07:13PM +0200, Florian Weimer wrote:
>> When GDB evaluates an expression in the inferior, it first
>> creates a copy of the string using malloc. For this malloc
>> call, GDB was not tracking properly if the malloc symbol is
>> actually an IFUNC resolver. This means that the IFUNC
>> resolver gets called like the real malloc function.
>>
>> This change adds a kludge to detect this, which prevents GDB
>> from overwriting the __libc_malloc code with the user-supplied
>> string literal.
>>
>> ...
>>
>> diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.c b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
>> index 648fb617de..3552168ecd 100644
>>
>> ...
>>
>> +/* Return true if the resolver function has been called through GDB.
>> + This used below to determine if GDB incorrectly calls the malloc
>> + IFUNC resolver instead of the resolver result. The trampoline
>> + address is either on the stack, or the kernel-provided entry point,
>> + depending on architecture.
>> +
>> + A fixed GDB will get the malloc address from the GOT. Calling
>> + malloc before relocation processing is complete should use the
>> + ld.so malloc, which does not involve an IFUNC. */
>> +static inline bool
>> +called_from_gdb (uintptr_t return_address, uintptr_t stack_frame)
>> +{
>> +#ifdef SHARED
>> + /* Assume that the stack grows downwards. */
>> + if (stack_frame <= return_address && return_address <= stack_frame + 128)
>> + return true;
>> +
>> + /* GDB uses the kernel-provided entry point on some architectures
>> + for the trampoline. */
>> + if (return_address == GLRO(dl_entry))
>> + return true;
>> +#endif
>> + return false;
>> +}
>
> Although this does fix the regressions in GDB testsuite, I think this is
> a wrong approach and we should not do this.
>
I don't like it either, but I don't see a better alternative to keep some
compatibility with old gdb.
But I also think this approach is fragile: it require some assumptions on how
gdb implements this and adds some magic number. I think a better alternative
is invert the assumption: the only exactly legitimate caller of an IFUNC
resolver is the the dynamic loader's relocation machinery
(elf_ifunc_invoke / _dl_fixup):
static inline bool
called_from_gdb (uintptr_t return_address)
{
#ifdef SHARED
/* The only legitimate caller of an IFUNC resolver is the dynamic
loader's relocation code, whose return address lies within ld.so's
own load segments. Anything else — notably GDB invoking the
resolver as if it were malloc — falls outside that range. */
return !(_dl_rtld_map.l_map_start <= return_address
&& return_address < _dl_rtld_map.l_map_end);
#else
return false;
#endif
}
Since it is only enable for SHARED now, and with this is no need to keep
GLRO(dl_entry), nor adding extra outside machinery on the code. It should
work on all supported scenarios as well:
Resolution mode Function that runs the resolver
Eager IRELATIVE (defining object's own GOT) elf_irel
Eager JUMP_SLOT/reloc to an ifunc elf_machine_rela
Lazy PLT, first call _dl_fixup — dl-runtime.c
Lazy PLT + audit/profile _dl_profile_fixup
All cases are done by ld.so. And I think this kludge should be generic,
afaik this gdb issue is neither aarch64 or malloc specific, so we might need
to extend this for other functions.
Hi,
> I don't like it either, but I don't see a better alternative to keep some
> compatibility with old gdb.
>
> But I also think this approach is fragile: it require some assumptions on how
> gdb implements this and adds some magic number. I think a better alternative
> is invert the assumption: the only exactly legitimate caller of an IFUNC
> resolver is the the dynamic loader's relocation machinery
> (elf_ifunc_invoke / _dl_fixup):
On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
targets.
I'd suggest to give an error since it is a bug in GDB and you only get it in some
scenarios (hence hard to justify risky hacks in GLIBC to make some cases work).
Btw is it possible for GDB to call malloc before initialization? Malloc no longer does
auto-init, so we rely on initialization to be called first. There are lots of issues with
an external agent inserting calls besides killing the repeatable debug experience...
Cheers,
Wilco
On 30/06/26 11:15, Wilco Dijkstra wrote:
> Hi,
>
>> I don't like it either, but I don't see a better alternative to keep some
>> compatibility with old gdb.
>>
>> But I also think this approach is fragile: it require some assumptions on how
>> gdb implements this and adds some magic number. I think a better alternative
>> is invert the assumption: the only exactly legitimate caller of an IFUNC
>> resolver is the the dynamic loader's relocation machinery
>> (elf_ifunc_invoke / _dl_fixup):
>
> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
> targets.
This adds extra complexity for debuggers to have arch-specific knowledge of
how ifunc works when called directly. Doable, but it is essentially another
undocumented semantic.
But this workaround already would require debuggers to parse whether the ifunc
return code is the resolver or an ifunc selection anyway; so this might not be
a problem anyway.
And I think this might add another subtle issue where it might not be safe to
call glibc functions mixing memory allocated with different allocators.
>
> I'd suggest to give an error since it is a bug in GDB and you only get it in some
> scenarios (hence hard to justify risky hacks in GLIBC to make some cases work).
>
> Btw is it possible for GDB to call malloc before initialization? Malloc no longer does
> auto-init, so we rely on initialization to be called first. There are lots of issues with
> an external agent inserting calls besides killing the repeatable debug experience...
Afaik there is no constraint after libc being mapped, but the runtime not yet
initialized. There is still the window where it can be called *before* TLS /
thread point initialization, where even with this workaround the inferior
will most likely crash. The _dl_rtld_map way at least make the crash more
reliable (compare to GLRO(dl_entry) check).
On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
>
> On 30/06/26 11:15, Wilco Dijkstra wrote:
> > Hi,
> >
> >> I don't like it either, but I don't see a better alternative to keep some
> >> compatibility with old gdb.
> >>
> >> But I also think this approach is fragile: it require some assumptions on how
> >> gdb implements this and adds some magic number.� I think a better alternative
> >> is invert the assumption: the only exactly legitimate caller of an IFUNC
> >> resolver is the the dynamic loader's relocation machinery
> >> (elf_ifunc_invoke / _dl_fixup):
> >
> > On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
> > invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
> > ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
> > targets.
Yes, we should do this, I'll make a patch.
>
> This adds extra complexity for debuggers to have arch-specific knowledge of
> how ifunc works when called directly. Doable, but it is essentially another
> undocumented semantic.
The idea is to abort if !(arg0 & IFUNC_ARG_HWCAP) is true with a clear
error message. This is not to work-around the issue in GDB but to make
the error explicit and clear. No complexity, no arch-specific knowledge.
Thanks,
Yury
On 30/06/26 12:29, Yury Khrustalev wrote:
> On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
>>
>> On 30/06/26 11:15, Wilco Dijkstra wrote:
>>> Hi,
>>>
>>>> I don't like it either, but I don't see a better alternative to keep some
>>>> compatibility with old gdb.
>>>>
>>>> But I also think this approach is fragile: it require some assumptions on how
>>>> gdb implements this and adds some magic number.� I think a better alternative
>>>> is invert the assumption: the only exactly legitimate caller of an IFUNC
>>>> resolver is the the dynamic loader's relocation machinery
>>>> (elf_ifunc_invoke / _dl_fixup):
>>>
>>> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
>>> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
>>> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
>>> targets.
>
> Yes, we should do this, I'll make a patch.
I think if we want to add this workaround, doing in a platform neutral is better
than adding arch-specific knobs.
>
>>
>> This adds extra complexity for debuggers to have arch-specific knowledge of
>> how ifunc works when called directly. Doable, but it is essentially another
>> undocumented semantic.
>
> The idea is to abort if !(arg0 & IFUNC_ARG_HWCAP) is true with a clear
> error message. This is not to work-around the issue in GDB but to make
> the error explicit and clear. No complexity, no arch-specific knowledge.
>
> Thanks,
> Yury
On Tue, Jun 30, 2026 at 01:15:04PM -0300, Adhemerval Zanella Netto wrote:
>
> On 30/06/26 12:29, Yury Khrustalev wrote:
> > On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
> >>
> >> On 30/06/26 11:15, Wilco Dijkstra wrote:
> >>> Hi,
> >>>
> >>>> I don't like it either, but I don't see a better alternative to keep some
> >>>> compatibility with old gdb.
> >>>>
> >>>> But I also think this approach is fragile: it require some assumptions on how
> >>>> gdb implements this and adds some magic number.� I think a better alternative
> >>>> is invert the assumption: the only exactly legitimate caller of an IFUNC
> >>>> resolver is the the dynamic loader's relocation machinery
> >>>> (elf_ifunc_invoke / _dl_fixup):
> >>>
> >>> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
> >>> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
> >>> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
> >>> targets.
> >
> > Yes, we should do this, I'll make a patch.
>
> I think if we want to add this workaround, doing in a platform neutral is better
> than adding arch-specific knobs.
You probably missed second part of my reply. The idea is not to provide
a work-around for the problem in GDB. The idea is to fail early with a
clear error message when resolver is called incorrectly.
The patch series at the start of this thread *is* "arch-specific knobs".
Also, we're talking about code under sysdeps/aarch64 so I don't see
anything wrong with it being arch-specific.
As machine maintainer for AArch64 I'm against the Florian's patch and I
think the right way ahead is to implement Wilco's suggestion.
Thanks,
Yury
* Yury Khrustalev:
> Also, we're talking about code under sysdeps/aarch64 so I don't see
> anything wrong with it being arch-specific.
The goal is to move all IFUNC-enabled architectures to malloc IFUNCs, so
that the we can use specialized code for the __libc_initial case (main
libc.so.6, not secondary namespace) that stores per-thread data directly
in the TCB.
(The !__libc_initial variant probably wouldn't use tcache or multiple
arenas.)
Thanks,
Florian
Hi Florian,
>> Also, we're talking about code under sysdeps/aarch64 so I don't see
>> anything wrong with it being arch-specific.
>
> The goal is to move all IFUNC-enabled architectures to malloc IFUNCs, so
> that the we can use specialized code for the __libc_initial case (main
> libc.so.6, not secondary namespace) that stores per-thread data directly
> in the TCB.
Or seamlessly add more checks or switch to a more performance optimized
malloc etc. There is no doubt ifuncs are useful in general.
However I think the question is whether it is possible to solve this in a target
independent way. The check I proposed triggers in valgrind too (looks like the
same bug as GDB). There are 2 cases that need fixing:
1. Application doesn't understand ifuncs and just calls an ifunc resolver assuming
it is a normal function. Always wrong.
2. Application understands ifuncs and calls the resolver directly (likely passing
only HWCAP, possibly selecting the wrong ifunc).
Could any check detect the difference between (1) and (2) or whether the right
HWCAP values are passed for each target?
Should we, given ifunc ABIs are target specific, disallow directly calling ifunc
resolvers in all cases?
Cheers,
Wilco
* Wilco Dijkstra:
> Btw is it possible for GDB to call malloc before initialization?
> Malloc no longer does auto-init, so we rely on initialization to be
> called first. There are lots of issues with an external agent
> inserting calls besides killing the repeatable debug experience...
We call __ptmalloc_init from __libc_early_init. It's currently non
possible to single-step through that because we haven't signaled
RT_CONSISTENT at this stage. GDB doesn't see the libc link map yet, so
malloc is still the ld.so minimal malloc.
Thanks,
Florian
* Wilco Dijkstra:
> Should we, given ifunc ABIs are target specific, disallow directly
> calling ifunc resolvers in all cases?
Maybe we should do that. We could expose an __invoke_ifunc symbol that
performs the ABI-appropriate call at the same time.
However, malloc is probably a special case because of the GDB string
literal bug.
Thanks,
Florian
Hi Florian,
>> Should we, given ifunc ABIs are target specific, disallow directly
>> calling ifunc resolvers in all cases?
>
> Maybe we should do that. We could expose an __invoke_ifunc symbol that
> performs the ABI-appropriate call at the same time.
Is it not possible to use dlsym()? The issue is more that applications just call
symbols without realizing it is an ifunc...
> However, malloc is probably a special case because of the GDB string
> literal bug.
Valgrind has the same issue. If we commit Muhammad's workaround in GDB,
this patch will result in GDB calling a malloc block...
Or are you proposing that we explicitly define (and guarantee) that the malloc/free/...
ifunc resolvers behave like malloc/free when NOT called from GLIBC?
Cheers,
Wilco
On 01/07/26 05:39, Yury Khrustalev wrote:
> On Tue, Jun 30, 2026 at 01:15:04PM -0300, Adhemerval Zanella Netto wrote:
>>
>> On 30/06/26 12:29, Yury Khrustalev wrote:
>>> On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
>>>>
>>>> On 30/06/26 11:15, Wilco Dijkstra wrote:
>>>>> Hi,
>>>>>
>>>>>> I don't like it either, but I don't see a better alternative to keep some
>>>>>> compatibility with old gdb.
>>>>>>
>>>>>> But I also think this approach is fragile: it require some assumptions on how
>>>>>> gdb implements this and adds some magic number.� I think a better alternative
>>>>>> is invert the assumption: the only exactly legitimate caller of an IFUNC
>>>>>> resolver is the the dynamic loader's relocation machinery
>>>>>> (elf_ifunc_invoke / _dl_fixup):
>>>>>
>>>>> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
>>>>> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
>>>>> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
>>>>> targets.
>>>
>>> Yes, we should do this, I'll make a patch.
>>
>> I think if we want to add this workaround, doing in a platform neutral is better
>> than adding arch-specific knobs.
>
> You probably missed second part of my reply. The idea is not to provide
> a work-around for the problem in GDB. The idea is to fail early with a
> clear error message when resolver is called incorrectly.
>
> The patch series at the start of this thread *is* "arch-specific knobs".
I got that and my suggestion is doing exactly what you suggested [1],
but in the generic way (enforce all ifunc alls originate inside ld.so,
so __builtin_return_address(0) lies within _dl_rtld_map's [l_map_start, l
_map_end).
This will allow other ABIs to enable malloc ifunc without the need to come
up with arch-specific heuristics.
And I think we should *decouple* the 1. stop the corruption goal from 2.
make GDB's string-literal path work.
[1] https://sourceware.org/pipermail/libc-alpha/2026-July/178497.html
>
> Also, we're talking about code under sysdeps/aarch64 so I don't see
> anything wrong with it being arch-specific.
>
> As machine maintainer for AArch64 I'm against the Florian's patch and I
> think the right way ahead is to implement Wilco's suggestion.
>
> Thanks,
> Yury
>
On Wed, Jul 01, 2026 at 10:25:59AM -0300, Adhemerval Zanella Netto wrote:
>
> On 01/07/26 05:39, Yury Khrustalev wrote:
> > On Tue, Jun 30, 2026 at 01:15:04PM -0300, Adhemerval Zanella Netto wrote:
> >>
> >> On 30/06/26 12:29, Yury Khrustalev wrote:
> >>> On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
> >>>>
> >>>> On 30/06/26 11:15, Wilco Dijkstra wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> I don't like it either, but I don't see a better alternative to keep some
> >>>>>> compatibility with old gdb.
> >>>>>>
> >>>>>> But I also think this approach is fragile: it require some assumptions on how
> >>>>>> gdb implements this and adds some magic number.� I think a better alternative
> >>>>>> is invert the assumption: the only exactly legitimate caller of an IFUNC
> >>>>>> resolver is the the dynamic loader's relocation machinery
> >>>>>> (elf_ifunc_invoke / _dl_fixup):
> >>>>>
> >>>>> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
> >>>>> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
> >>>>> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
> >>>>> targets.
> >>>
> >>> Yes, we should do this, I'll make a patch.
> >>
> >> I think if we want to add this workaround, doing in a platform neutral is better
> >> than adding arch-specific knobs.
> >
> > You probably missed second part of my reply. The idea is not to provide
> > a work-around for the problem in GDB. The idea is to fail early with a
> > clear error message when resolver is called incorrectly.
> >
> > The patch series at the start of this thread *is* "arch-specific knobs".
>
> I got that and my suggestion is doing exactly what you suggested [1],
> but in the generic way (enforce all ifunc alls originate inside ld.so,
> so __builtin_return_address(0) lies within _dl_rtld_map's [l_map_start, l
> _map_end).
OK, I see. Well, resolvers should be as simple as possible, so I'd
rather do the check in the arch-specific way if it makes it smaller.
However, a resolver can be correctly called from other places. For
example, many binary instrumentation frameworks substitute dynamic
loader and try to implement everything that a usual dynamic loader
would do. With Wilco's approach, these use cases will work provided
that the arguments for the resolver are compliant with the ABI, but
a check based on the return address will fail rendering many valid
use cases incorrect.
> This will allow other ABIs to enable malloc ifunc without the need to come
> up with arch-specific heuristics.
>
> And I think we should *decouple* the 1. stop the corruption goal from 2.
> make GDB's string-literal path work.
>
> [1] https://sourceware.org/pipermail/libc-alpha/2026-July/178497.html
Well, it's not just GDB, Valgrind does it as well:
https://bugs.kde.org/show_bug.cgi?id=522497
Thanks,
Yury
On 01/07/26 10:56, Yury Khrustalev wrote:
> On Wed, Jul 01, 2026 at 10:25:59AM -0300, Adhemerval Zanella Netto wrote:
>>
>> On 01/07/26 05:39, Yury Khrustalev wrote:
>>> On Tue, Jun 30, 2026 at 01:15:04PM -0300, Adhemerval Zanella Netto wrote:
>>>>
>>>> On 30/06/26 12:29, Yury Khrustalev wrote:
>>>>> On Tue, Jun 30, 2026 at 12:17:37PM -0300, Adhemerval Zanella Netto wrote:
>>>>>>
>>>>>> On 30/06/26 11:15, Wilco Dijkstra wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>>> I don't like it either, but I don't see a better alternative to keep some
>>>>>>>> compatibility with old gdb.
>>>>>>>>
>>>>>>>> But I also think this approach is fragile: it require some assumptions on how
>>>>>>>> gdb implements this and adds some magic number.� I think a better alternative
>>>>>>>> is invert the assumption: the only exactly legitimate caller of an IFUNC
>>>>>>>> resolver is the the dynamic loader's relocation machinery
>>>>>>>> (elf_ifunc_invoke / _dl_fixup):
>>>>>>>
>>>>>>> On AArch64 we can just check for !(arg0 & IFUNC_ARG_HWCAP) since we always
>>>>>>> invoke ifuncs with that bit set from GLIBC (obviously the value is way too large to
>>>>>>> ever be a valid allocation). You could also check arg0 == GLRO (dl_hwcap) for other
>>>>>>> targets.
>>>>>
>>>>> Yes, we should do this, I'll make a patch.
>>>>
>>>> I think if we want to add this workaround, doing in a platform neutral is better
>>>> than adding arch-specific knobs.
>>>
>>> You probably missed second part of my reply. The idea is not to provide
>>> a work-around for the problem in GDB. The idea is to fail early with a
>>> clear error message when resolver is called incorrectly.
>>>
>>> The patch series at the start of this thread *is* "arch-specific knobs".
>>
>> I got that and my suggestion is doing exactly what you suggested [1],
>> but in the generic way (enforce all ifunc alls originate inside ld.so,
>> so __builtin_return_address(0) lies within _dl_rtld_map's [l_map_start, l
>> _map_end).
>
> OK, I see. Well, resolvers should be as simple as possible, so I'd
> rather do the check in the arch-specific way if it makes it smaller.
>
> However, a resolver can be correctly called from other places. For
> example, many binary instrumentation frameworks substitute dynamic
> loader and try to implement everything that a usual dynamic loader
> would do. With Wilco's approach, these use cases will work provided
> that the arguments for the resolver are compliant with the ABI, but
> a check based on the return address will fail rendering many valid
> use cases incorrect.
But for ifunc resolver entered with ambiguous register state, we cannot satisfy
both:
* Caller wants the resolver to behave like the function call (i.e - malloc
do the allocation).
* Caller wants the resolver to return the resolved address.
The on-entry state doesn't reliably encode intent across targets and ABI
versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
1. that only separates new-ABI resolver call from everything else, it doesn't
rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
2. there's no in-band way to validate that a passed HWCAP is correct
(garbage HWCAP just silently selects some implementation).
That's why I think we should decouple both target.
>
>> This will allow other ABIs to enable malloc ifunc without the need to come
>> up with arch-specific heuristics.
>>
>> And I think we should *decouple* the 1. stop the corruption goal from 2.
>> make GDB's string-literal path work.
>>
>> [1] https://sourceware.org/pipermail/libc-alpha/2026-July/178497.html
>
> Well, it's not just GDB, Valgrind does it as well:
> https://bugs.kde.org/show_bug.cgi?id=522497
>
> Thanks,
> Yury
>
On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
> >
> > ...
> >
> > OK, I see. Well, resolvers should be as simple as possible, so I'd
> > rather do the check in the arch-specific way if it makes it smaller.
> >
> > However, a resolver can be correctly called from other places. For
> > example, many binary instrumentation frameworks substitute dynamic
> > loader and try to implement everything that a usual dynamic loader
> > would do. With Wilco's approach, these use cases will work provided
> > that the arguments for the resolver are compliant with the ABI, but
> > a check based on the return address will fail rendering many valid
> > use cases incorrect.
>
> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
> both:
>
> * Caller wants the resolver to behave like the function call (i.e - malloc
> do the allocation).
I don't think we should even discuss this.
> * Caller wants the resolver to return the resolved address.
If caller wants something else from an ifunc resolver, it is an error
and we should abort.
>
> The on-entry state doesn't reliably encode intent across targets and ABI
> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
>
> 1. that only separates new-ABI resolver call from everything else, it doesn't
> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
Yep, as Wilco suggested we can use
(arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
>
> 2. there's no in-band way to validate that a passed HWCAP is correct
> (garbage HWCAP just silently selects some implementation).
>
> That's why I think we should decouple both target.
On 01/07/26 12:53, Yury Khrustalev wrote:
> On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
>>>
>>> ...
>>>
>>> OK, I see. Well, resolvers should be as simple as possible, so I'd
>>> rather do the check in the arch-specific way if it makes it smaller.
>>>
>>> However, a resolver can be correctly called from other places. For
>>> example, many binary instrumentation frameworks substitute dynamic
>>> loader and try to implement everything that a usual dynamic loader
>>> would do. With Wilco's approach, these use cases will work provided
>>> that the arguments for the resolver are compliant with the ABI, but
>>> a check based on the return address will fail rendering many valid
>>> use cases incorrect.
>>
>> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
>> both:
>>
>> * Caller wants the resolver to behave like the function call (i.e - malloc
>> do the allocation).
>
> I don't think we should even discuss this.
>
>> * Caller wants the resolver to return the resolved address.
>
> If caller wants something else from an ifunc resolver, it is an error
> and we should abort.
>
>>
>> The on-entry state doesn't reliably encode intent across targets and ABI
>> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
>>
>> 1. that only separates new-ABI resolver call from everything else, it doesn't
>> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
>
> Yep, as Wilco suggested we can use
>
> (arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
It still has a hole, any resolver(n) where (n~_IFUNC_ARG_HWCAP) == dl_hwcap
passes the check. It might not a problem for malloc, but maybe for
environments that manipulate hwcap (valgrind, etc.) that calls other ifunc
besides malloc we might hit it eventually.
Maybe the arg0 maybe be added as a complementary arch-specific check after
the _dl_rtld_map bounds check. The bound check still has the advantage of
being platform-neutral and generic enough to not require any extra arch
handling if some maintainer wants to enable malloc ifunc.
On Wed, Jul 01, 2026 at 01:25:14PM -0300, Adhemerval Zanella Netto wrote:
>
> On 01/07/26 12:53, Yury Khrustalev wrote:
> > On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
> >>>
> >>> ...
> >>>
> >>> OK, I see. Well, resolvers should be as simple as possible, so I'd
> >>> rather do the check in the arch-specific way if it makes it smaller.
> >>>
> >>> However, a resolver can be correctly called from other places. For
> >>> example, many binary instrumentation frameworks substitute dynamic
> >>> loader and try to implement everything that a usual dynamic loader
> >>> would do. With Wilco's approach, these use cases will work provided
> >>> that the arguments for the resolver are compliant with the ABI, but
> >>> a check based on the return address will fail rendering many valid
> >>> use cases incorrect.
> >>
> >> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
> >> both:
> >>
> >> * Caller wants the resolver to behave like the function call (i.e - malloc
> >> do the allocation).
> >
> > I don't think we should even discuss this.
> >
> >> * Caller wants the resolver to return the resolved address.
> >
> > If caller wants something else from an ifunc resolver, it is an error
> > and we should abort.
> >
> >>
> >> The on-entry state doesn't reliably encode intent across targets and ABI
> >> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
> >>
> >> 1. that only separates new-ABI resolver call from everything else, it doesn't
> >> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
> >
> > Yep, as Wilco suggested we can use
> >
> > (arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
> It still has a hole, any resolver(n) where (n~_IFUNC_ARG_HWCAP) == dl_hwcap
> passes the check. It might not a problem for malloc, but maybe for
> environments that manipulate hwcap (valgrind, etc.) that calls other ifunc
> besides malloc we might hit it eventually.
>
> Maybe the arg0 maybe be added as a complementary arch-specific check after
> the _dl_rtld_map bounds check. The bound check still has the advantage of
> being platform-neutral and generic enough to not require any extra arch
> handling if some maintainer wants to enable malloc ifunc.
Adhemerval, I already explained that bounds check will render some use
cases not working. Here is another example to demonstrate this problem.
GDB can call 'malloc' in different ways, e.g.
a) internally to facilitate expression evaluation (this is where we're
having a problem right now, and this is what Florian's patch fixes)
b) when 'malloc' is called as part of the expression.
Observe:
(gdb) br main
(gdb) r
Breakpoint 1, main (...) at ...
(gdb) call printf("%s\n", "hello")
hello
$1 = 6
(gdb) p malloc(23)
Program received signal SIGSEGV, Segmentation fault.
0x0000ffff0828f010 in ?? ()
The program being debugged was signaled while in a function called from GDB.
This is with Florian's patch. Once again, this is not the only problem
you have to solve. I suppose your suggestion above in this thread may
work, however, like I already said, allowing resolvers to be only called
from libc itself will make other runtimes stop working.
I think we've wasted enough time on try to find a "bug-compatible"
implementation. I don't think we should be doing this at all. Bugs
should be fixed. Complying software should not be the victim of bugs
in other tools.
Thanks,
Yury
On 02/07/26 05:10, Yury Khrustalev wrote:
> On Wed, Jul 01, 2026 at 01:25:14PM -0300, Adhemerval Zanella Netto wrote:
>>
>> On 01/07/26 12:53, Yury Khrustalev wrote:
>>> On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
>>>>>
>>>>> ...
>>>>>
>>>>> OK, I see. Well, resolvers should be as simple as possible, so I'd
>>>>> rather do the check in the arch-specific way if it makes it smaller.
>>>>>
>>>>> However, a resolver can be correctly called from other places. For
>>>>> example, many binary instrumentation frameworks substitute dynamic
>>>>> loader and try to implement everything that a usual dynamic loader
>>>>> would do. With Wilco's approach, these use cases will work provided
>>>>> that the arguments for the resolver are compliant with the ABI, but
>>>>> a check based on the return address will fail rendering many valid
>>>>> use cases incorrect.
>>>>
>>>> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
>>>> both:
>>>>
>>>> * Caller wants the resolver to behave like the function call (i.e - malloc
>>>> do the allocation).
>>>
>>> I don't think we should even discuss this.
>>>
>>>> * Caller wants the resolver to return the resolved address.
>>>
>>> If caller wants something else from an ifunc resolver, it is an error
>>> and we should abort.
>>>
>>>>
>>>> The on-entry state doesn't reliably encode intent across targets and ABI
>>>> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
>>>>
>>>> 1. that only separates new-ABI resolver call from everything else, it doesn't
>>>> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
>>>
>>> Yep, as Wilco suggested we can use
>>>
>>> (arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
>> It still has a hole, any resolver(n) where (n~_IFUNC_ARG_HWCAP) == dl_hwcap
>> passes the check. It might not a problem for malloc, but maybe for
>> environments that manipulate hwcap (valgrind, etc.) that calls other ifunc
>> besides malloc we might hit it eventually.
>>
>> Maybe the arg0 maybe be added as a complementary arch-specific check after
>> the _dl_rtld_map bounds check. The bound check still has the advantage of
>> being platform-neutral and generic enough to not require any extra arch
>> handling if some maintainer wants to enable malloc ifunc.
>
> Adhemerval, I already explained that bounds check will render some use
> cases not working. Here is another example to demonstrate this problem.
>
> GDB can call 'malloc' in different ways, e.g.
>
> a) internally to facilitate expression evaluation (this is where we're
> having a problem right now, and this is what Florian's patch fixes)
>
> b) when 'malloc' is called as part of the expression.
>
> Observe:
>
> (gdb) br main
> (gdb) r
> Breakpoint 1, main (...) at ...
> (gdb) call printf("%s\n", "hello")
> hello
> $1 = 6
> (gdb) p malloc(23)
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000ffff0828f010 in ?? ()
> The program being debugged was signaled while in a function called from GDB.
>
> This is with Florian's patch. Once again, this is not the only problem
> you have to solve. I suppose your suggestion above in this thread may
> work, however, like I already said, allowing resolvers to be only called
> from libc itself will make other runtimes stop working.
>
> I think we've wasted enough time on try to find a "bug-compatible"
> implementation. I don't think we should be doing this at all. Bugs
> should be fixed. Complying software should not be the victim of bugs
> in other tools.
I think we are talking past each other since we have multiple divergent
ideas on how to approach this issue.
My point is *if* we decide to push a workaround in glibc to handle direct
malloc calls in gdb, I think we should do some as below. With this patch
applied:
$ gdb -q -batch -ex "b main" -ex "run" -ex "p malloc(23)" --args malloc/tst-valloc-mcheck --direct
Breakpoint 1 at 0x24c0: file ../support/test-driver.c, line 112.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Breakpoint 1, main (argc=2, argv=0xffffffffede8) at ../support/test-driver.c:112
112 {
malloc called in wrong context
[Inferior 1 (process 530903) exited with code 0177]
The program being debugged exited while in a function called from GDB.
Evaluation of the expression containing the function
(__libc_malloc_redirect_ifunc) will be abandoned.
So no crypt SIGSEGV triggered, platform agnostic, and with a clear indication
that this is not supported. The gdb will need to proper call the function
through the GOT, which then will either trigger the lazy resolution (and thus
make ld.so call the ifunc resolver) or issue the resolved implementation directly
- thus mimic what the process itself is expected to do.
But I am not really proposing we go for this route, and I tend to agree that
fixing gdb and other tools is a better alternative.
As far as I understand there is no easy way solely in the malloc ifunc
resolver context to make it bug compatible (which is not something I am *not*
advocating by the way) *and* make malloc 'work'. We need to pick a poison:
provide malloc as ifunc and disable this usercase by these tools; or work
toward fixing the tools to proper handle it.
diff --git a/elf/Versions b/elf/Versions
index 1591031da99..5fe481d676e 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -79,5 +79,7 @@ ld {
# Set value of a tunable.
__tunable_is_initialized;
__tunable_get_val;
+
+ _dl_rtld_map;
}
}
diff --git a/elf/rtld.c b/elf/rtld.c
index e5ba71fef18..02ba23e67ef 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -377,6 +377,7 @@ extern struct rtld_global_ro _rtld_local_ro
__attribute__ ((alias ("_rtld_global_ro"), visibility ("hidden")));
struct link_map _dl_rtld_map;
+rtld_hidden_def (_dl_rtld_map)
struct auditstate _dl_rtld_auditstate[DL_NNS];
static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
diff --git a/sysdeps/aarch64/multiarch/malloc-ifuncs.c b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
index 648fb617de7..e0bc9843795 100644
--- a/sysdeps/aarch64/multiarch/malloc-ifuncs.c
+++ b/sysdeps/aarch64/multiarch/malloc-ifuncs.c
@@ -22,8 +22,22 @@
#include <malloc-api.h>
#include <shlib-compat.h>
-libc_ifunc_hidden (__libc_malloc, __libc_malloc_redirect,
- __libc_malloc)
+#include <sys/ifunc.h>
+
+static __typeof (__libc_malloc) *
+malloc_ifunc_call (uintptr_t return_address)
+{
+#ifdef SHARED
+ if (!(_dl_rtld_map.l_map_start <= return_address
+ && return_address < _dl_rtld_map.l_map_end))
+ _dl_fatal_printf ("malloc called in wrong context\n");
+#endif
+ return __libc_malloc;
+}
+
+__ifunc_hidden (__libc_malloc, __libc_malloc_redirect,
+ malloc_ifunc_call ((uintptr_t) __builtin_return_address (0)),
+ size_t size, INIT_ARCH)
strong_alias (__libc_malloc_redirect, malloc)
libc_ifunc_hidden (__libc_calloc, __libc_calloc_redirect,
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index f94247ad9fb..774f3c0f911 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1357,7 +1357,8 @@ rtld_active (void)
}
/* Pre-allocated link map for the dynamic linker itself. */
-extern struct link_map _dl_rtld_map attribute_hidden;
+extern struct link_map _dl_rtld_map /*attribute_hidden*/;
+rtld_hidden_proto (_dl_rtld_map)
/* Used to store the audit information for the link map of the
dynamic loader. */
On 02/07/26 09:59, Adhemerval Zanella Netto wrote:
>
>
> On 02/07/26 05:10, Yury Khrustalev wrote:
>> On Wed, Jul 01, 2026 at 01:25:14PM -0300, Adhemerval Zanella Netto wrote:
>>>
>>> On 01/07/26 12:53, Yury Khrustalev wrote:
>>>> On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
>>>>>>
>>>>>> ...
>>>>>>
>>>>>> OK, I see. Well, resolvers should be as simple as possible, so I'd
>>>>>> rather do the check in the arch-specific way if it makes it smaller.
>>>>>>
>>>>>> However, a resolver can be correctly called from other places. For
>>>>>> example, many binary instrumentation frameworks substitute dynamic
>>>>>> loader and try to implement everything that a usual dynamic loader
>>>>>> would do. With Wilco's approach, these use cases will work provided
>>>>>> that the arguments for the resolver are compliant with the ABI, but
>>>>>> a check based on the return address will fail rendering many valid
>>>>>> use cases incorrect.
>>>>>
>>>>> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
>>>>> both:
>>>>>
>>>>> * Caller wants the resolver to behave like the function call (i.e - malloc
>>>>> do the allocation).
>>>>
>>>> I don't think we should even discuss this.
>>>>
>>>>> * Caller wants the resolver to return the resolved address.
>>>>
>>>> If caller wants something else from an ifunc resolver, it is an error
>>>> and we should abort.
>>>>
>>>>>
>>>>> The on-entry state doesn't reliably encode intent across targets and ABI
>>>>> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
>>>>>
>>>>> 1. that only separates new-ABI resolver call from everything else, it doesn't
>>>>> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
>>>>
>>>> Yep, as Wilco suggested we can use
>>>>
>>>> (arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
>>> It still has a hole, any resolver(n) where (n~_IFUNC_ARG_HWCAP) == dl_hwcap
>>> passes the check. It might not a problem for malloc, but maybe for
>>> environments that manipulate hwcap (valgrind, etc.) that calls other ifunc
>>> besides malloc we might hit it eventually.
>>>
>>> Maybe the arg0 maybe be added as a complementary arch-specific check after
>>> the _dl_rtld_map bounds check. The bound check still has the advantage of
>>> being platform-neutral and generic enough to not require any extra arch
>>> handling if some maintainer wants to enable malloc ifunc.
>>
>> Adhemerval, I already explained that bounds check will render some use
>> cases not working. Here is another example to demonstrate this problem.
>>
>> GDB can call 'malloc' in different ways, e.g.
>>
>> a) internally to facilitate expression evaluation (this is where we're
>> having a problem right now, and this is what Florian's patch fixes)
>>
>> b) when 'malloc' is called as part of the expression.
>>
>> Observe:
>>
>> (gdb) br main
>> (gdb) r
>> Breakpoint 1, main (...) at ...
>> (gdb) call printf("%s\n", "hello")
>> hello
>> $1 = 6
>> (gdb) p malloc(23)
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x0000ffff0828f010 in ?? ()
>> The program being debugged was signaled while in a function called from GDB.
>>
>> This is with Florian's patch. Once again, this is not the only problem
>> you have to solve. I suppose your suggestion above in this thread may
>> work, however, like I already said, allowing resolvers to be only called
>> from libc itself will make other runtimes stop working.
>>
>> I think we've wasted enough time on try to find a "bug-compatible"
>> implementation. I don't think we should be doing this at all. Bugs
>> should be fixed. Complying software should not be the victim of bugs
>> in other tools.
>
> I think we are talking past each other since we have multiple divergent
> ideas on how to approach this issue.
>
> My point is *if* we decide to push a workaround in glibc to handle direct
> malloc calls in gdb, I think we should do some as below. With this patch
> applied:
>
> $ gdb -q -batch -ex "b main" -ex "run" -ex "p malloc(23)" --args malloc/tst-valloc-mcheck --direct
> Breakpoint 1 at 0x24c0: file ../support/test-driver.c, line 112.
> warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
>
> Breakpoint 1, main (argc=2, argv=0xffffffffede8) at ../support/test-driver.c:112
> 112 {
> malloc called in wrong context
> [Inferior 1 (process 530903) exited with code 0177]
> The program being debugged exited while in a function called from GDB.
> Evaluation of the expression containing the function
> (__libc_malloc_redirect_ifunc) will be abandoned.
So I tried to implement this check and I had my assumptions wrong [1]: the
ifunc resolution can also be called from libc (dlsym), there is the
extra complication of static dlopen and dlmopen, and there also the
valgrind case (elf/tst-valgrind-smoke regress).
This heuristic cannot tell between "bad" issuing (gdb evaluating a call) from
"good" (valgrind resolving for redirection), since valgrind dynamic translation
regenerates ld.so/libc.so and thus with a different mappings.
So I agree that we should focus on fixing gdb instead of adding extra hacks
on glibc. I am not sure about reverting changes, it would be safer for this release.
>
> So no crypt SIGSEGV triggered, platform agnostic, and with a clear indication
> that this is not supported. The gdb will need to proper call the function
> through the GOT, which then will either trigger the lazy resolution (and thus
> make ld.so call the ifunc resolver) or issue the resolved implementation directly
> - thus mimic what the process itself is expected to do.
>
> But I am not really proposing we go for this route, and I tend to agree that
> fixing gdb and other tools is a better alternative.
>
> As far as I understand there is no easy way solely in the malloc ifunc
> resolver context to make it bug compatible (which is not something I am *not*
> advocating by the way) *and* make malloc 'work'. We need to pick a poison:
> provide malloc as ifunc and disable this usercase by these tools; or work
> toward fixing the tools to proper handle it.
[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ifunc-malloc-reject
Hi Adhemerval,
> So I tried to implement this check and I had my assumptions wrong [1]: the
> ifunc resolution can also be called from libc (dlsym), there is the
> extra complication of static dlopen and dlmopen, and there also the
> valgrind case (elf/tst-valgrind-smoke regress).
>
> This heuristic cannot tell between "bad" issuing (gdb evaluating a call) from
> "good" (valgrind resolving for redirection), since valgrind dynamic translation
> regenerates ld.so/libc.so and thus with a different mappings.
>
> So I agree that we should focus on fixing gdb instead of adding extra hacks
> on glibc. I am not sure about reverting changes, it would be safer for this release.
Yes that's why I came up with a check that only looks at the given hwcap argument.
I think you suggested setting a boolean when resolving ifuncs. That would be a
simpler and safer approach IF we decide that no user application should ever call
a resolver directly.
Cheers,
Wilco
@@ -19,55 +19,87 @@
#if IS_IN (libc)
#include <init-arch.h>
+#include <ldsodefs.h>
#include <malloc-api.h>
#include <shlib-compat.h>
-
-libc_ifunc_hidden (__libc_malloc, __libc_malloc_redirect,
- __libc_malloc)
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Return true if the resolver function has been called through GDB.
+ This used below to determine if GDB incorrectly calls the malloc
+ IFUNC resolver instead of the resolver result. The trampoline
+ address is either on the stack, or the kernel-provided entry point,
+ depending on architecture.
+
+ A fixed GDB will get the malloc address from the GOT. Calling
+ malloc before relocation processing is complete should use the
+ ld.so malloc, which does not involve an IFUNC. */
+static inline bool
+called_from_gdb (uintptr_t return_address, uintptr_t stack_frame)
+{
+#ifdef SHARED
+ /* Assume that the stack grows downwards. */
+ if (stack_frame <= return_address && return_address <= stack_frame + 128)
+ return true;
+
+ /* GDB uses the kernel-provided entry point on some architectures
+ for the trampoline. */
+ if (return_address == GLRO(dl_entry))
+ return true;
+#endif
+ return false;
+}
+
+__ifunc_hidden (__libc_malloc, __libc_malloc_redirect,
+ called_from_gdb ((uintptr_t) __builtin_return_address (0),
+ (uintptr_t) __builtin_frame_address (0))
+ ? __libc_malloc (size) : (void *) __libc_malloc,
+ size_t size, INIT_ARCH)
strong_alias (__libc_malloc_redirect, malloc)
libc_ifunc_hidden (__libc_calloc, __libc_calloc_redirect,
- __libc_calloc)
+ __libc_calloc)
weak_alias (__libc_calloc_redirect, calloc)
libc_ifunc_hidden (__libc_memalign, __libc_memalign_redirect,
- __libc_memalign)
+ __libc_memalign)
weak_alias (__libc_memalign_redirect, memalign)
libc_ifunc_hidden (__libc_valloc, __libc_valloc_redirect,
- __libc_valloc)
+ __libc_valloc)
weak_alias (__libc_valloc_redirect, valloc)
libc_ifunc_hidden (__libc_pvalloc, __libc_pvalloc_redirect,
- __libc_pvalloc)
+ __libc_pvalloc)
weak_alias (__libc_pvalloc_redirect, pvalloc)
libc_ifunc_hidden (__libc_realloc, __libc_realloc_redirect,
- __libc_realloc)
+ __libc_realloc)
strong_alias (__libc_realloc_redirect, realloc)
libc_ifunc_hidden (__libc_free, __libc_free_redirect,
- __libc_free)
+ __libc_free)
strong_alias (__libc_free_redirect, free)
libc_ifunc_hidden (__malloc_usable_size, __malloc_usable_size_redirect,
- __malloc_usable_size)
+ __malloc_usable_size)
weak_alias (__malloc_usable_size_redirect, malloc_usable_size)
libc_ifunc_hidden (__posix_memalign, __posix_memalign_redirect,
- __posix_memalign)
+ __posix_memalign)
weak_alias (__posix_memalign_redirect, posix_memalign)
libc_ifunc_hidden (__aligned_alloc, __aligned_alloc_redirect,
- __aligned_alloc)
+ __aligned_alloc)
weak_alias (__aligned_alloc_redirect, aligned_alloc)
libc_ifunc_hidden (__free_sized, __free_sized_redirect,
- __free_sized)
+ __free_sized)
weak_alias (__free_sized_redirect, free_sized)
libc_ifunc_hidden (__free_aligned_sized, __free_aligned_sized_redirect,
- __free_aligned_sized)
+ __free_aligned_sized)
weak_alias (__free_aligned_sized_redirect, free_aligned_sized)
#endif /* IS_IN (libc) */