Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2223861/?format=api
{ "id": 2223861, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2223861/?format=api", "web_url": "http://patchwork.ozlabs.org/project/glibc/patch/20260416092751.11653-3-yury.khrustalev@arm.com/", "project": { "id": 41, "url": "http://patchwork.ozlabs.org/api/1.1/projects/41/?format=api", "name": "GNU C Library", "link_name": "glibc", "list_id": "libc-alpha.sourceware.org", "list_email": "libc-alpha@sourceware.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260416092751.11653-3-yury.khrustalev@arm.com>", "date": "2026-04-16T09:27:51", "name": "[2/2] malloc: introduce ifuncs for malloc functions", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "37a828a298e004533d974b68638406bc1c5ca18d", "submitter": { "id": 88214, "url": "http://patchwork.ozlabs.org/api/1.1/people/88214/?format=api", "name": "Yury Khrustalev", "email": "yury.khrustalev@arm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/glibc/patch/20260416092751.11653-3-yury.khrustalev@arm.com/mbox/", "series": [ { "id": 500124, "url": "http://patchwork.ozlabs.org/api/1.1/series/500124/?format=api", "web_url": "http://patchwork.ozlabs.org/project/glibc/list/?series=500124", "date": "2026-04-16T09:27:49", "name": "malloc: introduce ifuncs for malloc functions", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/500124/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2223861/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2223861/checks/", "tags": {}, "headers": { "Return-Path": "<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "libc-alpha@sourceware.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "libc-alpha@sourceware.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=RYNnBTwS;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key,\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=RYNnBTwS", "sourceware.org;\n dmarc=pass (p=none dis=none) header.from=arm.com", "sourceware.org; spf=pass smtp.mailfrom=arm.com", "server2.sourceware.org;\n arc=none smtp.remote-ip=217.140.110.172" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxCQT5wSpz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 16 Apr 2026 19:29:37 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id ECD444BA2E3E\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 16 Apr 2026 09:29:35 +0000 (GMT)", "from foss.arm.com (foss.arm.com [217.140.110.172])\n by sourceware.org (Postfix) with ESMTP id B53374BA2E26\n for <libc-alpha@sourceware.org>; Thu, 16 Apr 2026 09:28:01 +0000 (GMT)", "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BD8AA25E9;\n Thu, 16 Apr 2026 02:27:55 -0700 (PDT)", "from fdebian.localdomain (unknown [10.57.19.142])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5392F3F641;\n Thu, 16 Apr 2026 02:28:00 -0700 (PDT)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org ECD444BA2E3E", "OpenDKIM Filter v2.11.0 sourceware.org B53374BA2E26" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org B53374BA2E26", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org B53374BA2E26", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776331681; cv=none;\n b=oxB/qiavtlwqOyaEN34a6gdnsyGk1jZp1mmzQ/kaiTAoIt0iM+mMeFIkc+HBTtlC9nQamq5GH5p8pqTNhlzEUV/ydMj6I9EVqL9DE6URka3+jbZ7UZoQptW/wpzgqW7mzt8Wv3UT5yvNAPG3NOaOq80won3FSrhRrRPhugwFs2A=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776331681; c=relaxed/simple;\n bh=Jz3/WWaHZItKsG+9fbaqwOEKeazsX0ORq3PzH8K1FHk=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=FXe7yV0nJgU7uhylqFAAIfVumpN9DKzk4ou27S43/t2JFuEjBqtvU5Mrnu/U2p65u237lm6ZkmGJxl+4b0jmGj0KghHwc+HcPMpDyDS0jvkgZ3tYS597ZaIwYN2+riJx76oZSL1LneQ3w5VYETiWXfyKPF2hP3G+2XwJihHaP4I=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss;\n t=1776331681; bh=Jz3/WWaHZItKsG+9fbaqwOEKeazsX0ORq3PzH8K1FHk=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=RYNnBTwSxjTJKQdydXOqNXn5Bu0F5yGGcjHtK4+6nM+rV+kSaFOuLjxfdFSNc4Ok4\n jfGEFFsYP3qyU+4Q3dsBJux8ZhdDJRCerPB529dPpTuKRI+oAjVHLv9+wT2qfXvMs0\n NRC+aTtiNs8ZdC0yH/WA4xfPRKuRKLr0jc6dk8t0=", "From": "Yury Khrustalev <yury.khrustalev@arm.com>", "To": "libc-alpha@sourceware.org", "Cc": "DJ Delorie <dj@redhat.com>, Florian Weimer <fweimer@redhat.com>,\n \"H . J . Lu\" <hjl.tools@gmail.com>, Carlos O'Donell <carlos@redhat.com>,\n Wilco Dijkstra <wilco.dijkstra@arm.com>", "Subject": "[PATCH 2/2] malloc: introduce ifuncs for malloc functions", "Date": "Thu, 16 Apr 2026 10:27:51 +0100", "Message-ID": "<20260416092751.11653-3-yury.khrustalev@arm.com>", "X-Mailer": "git-send-email 2.47.3", "In-Reply-To": "<20260416092751.11653-1-yury.khrustalev@arm.com>", "References": "<20260416092751.11653-1-yury.khrustalev@arm.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libc-alpha@sourceware.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Libc-alpha mailing list <libc-alpha.sourceware.org>", "List-Unsubscribe": "<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>", "List-Archive": "<https://sourceware.org/pipermail/libc-alpha/>", "List-Post": "<mailto:libc-alpha@sourceware.org>", "List-Help": "<mailto:libc-alpha-request@sourceware.org?subject=help>", "List-Subscribe": "<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>", "Errors-To": "libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org" }, "content": "Introduce ifuncs and resolvers for functions pertinent to the\nmalloc interface.\n\nIn order to do this, we first rename all core implementations by\nadding the '_core' suffix. These functions are supposed to be strictly\ninternal and must not be used beyond the malloc code. For example, the\n__libc_malloc() function becomes __libc_malloc_core() and instead\n__libc_malloc() becomes an ifunc with a corresponding resolver that\nmay return '__libc_malloc_core' as the implementation.\n\nEach ifunc comes with a generic resolver that will be used unless a\ntarget overrides the resolvers in its sysdeps directory. All resolvers\nare supposed to be overridden together, and the logic of the generic\nresolvers should be replicated by the target-specific ones.\n\nThis patch contains, as an example, aarch64-specific resolvers. At this\nmoment they are identical to the generic ones but in the future they can\nbe changed to support for features, e.g. to handle memory tagging.\n\nCorresponding aliases are moved next to the ifuncs as well.\n\nOn targets that do not support ifuncs we alias externally visible\nfunctions as well as the __libc_* functions to their respective\n*_core symbols.\n---\n malloc/malloc.c | 119 ++++++++++++++++++--------------\n sysdeps/aarch64/Makefile | 3 +\n sysdeps/aarch64/malloc-ifuncs.c | 85 +++++++++++++++++++++++\n sysdeps/generic/Makefile | 3 +\n sysdeps/generic/malloc-ifuncs.c | 94 +++++++++++++++++++++++++\n sysdeps/generic/malloc-ifuncs.h | 62 +++++++++++++++++\n 6 files changed, 316 insertions(+), 50 deletions(-)\n create mode 100644 sysdeps/aarch64/malloc-ifuncs.c\n create mode 100644 sysdeps/generic/malloc-ifuncs.c\n create mode 100644 sysdeps/generic/malloc-ifuncs.h", "diff": "diff --git a/malloc/malloc.c b/malloc/malloc.c\nindex 57b58382b1..215feeebb0 100644\n--- a/malloc/malloc.c\n+++ b/malloc/malloc.c\n@@ -216,8 +216,6 @@\n #include <assert.h>\n #include <intprops.h>\n \n-#include <shlib-compat.h>\n-\n /* For uintptr_t. */\n #include <stdint.h>\n \n@@ -566,8 +564,8 @@ tag_at (void *ptr)\n differs across systems, but is in all cases less than the maximum\n representable value of a size_t.\n */\n-void *__libc_malloc (size_t);\n-libc_hidden_proto (__libc_malloc)\n+void *__libc_malloc_core (size_t);\n+libc_hidden_proto (__libc_malloc_core)\n \n static void *__libc_calloc2 (size_t);\n static void *__libc_malloc2 (size_t);\n@@ -583,15 +581,16 @@ static void *__libc_malloc2 (size_t);\n when possible, automatically trigger operations that give\n back unused memory to the system, thus reducing program footprint.\n */\n-void __libc_free(void*);\n-libc_hidden_proto (__libc_free)\n+void __libc_free_core (void *);\n+libc_hidden_proto (__libc_free_core)\n \n /*\n calloc(size_t n_elements, size_t element_size);\n Returns a pointer to n_elements * element_size bytes, with all locations\n set to zero.\n */\n-void* __libc_calloc(size_t, size_t);\n+void * __libc_calloc_core (size_t, size_t);\n+libc_hidden_proto (__libc_calloc_core)\n \n /*\n realloc(void* p, size_t n)\n@@ -620,8 +619,8 @@ void* __libc_calloc(size_t, size_t);\n The old unix realloc convention of allowing the last-free'd chunk\n to be used as an argument to realloc is not supported.\n */\n-void* __libc_realloc(void*, size_t);\n-libc_hidden_proto (__libc_realloc)\n+void *__libc_realloc_core (void *, size_t);\n+libc_hidden_proto (__libc_realloc_core)\n \n /*\n memalign(size_t alignment, size_t n);\n@@ -635,16 +634,16 @@ libc_hidden_proto (__libc_realloc)\n \n Overreliance on memalign is a sure way to fragment space.\n */\n-void* __libc_memalign(size_t, size_t);\n-libc_hidden_proto (__libc_memalign)\n+void *__libc_memalign_core (size_t, size_t);\n+libc_hidden_proto (__libc_memalign_core)\n \n /*\n valloc(size_t n);\n Equivalent to memalign(pagesize, n), where pagesize is the page\n size of the system. If the pagesize is unknown, 4096 is used.\n */\n-void* __libc_valloc(size_t);\n-\n+void *__libc_valloc_core (size_t);\n+libc_hidden_proto (__libc_valloc_core)\n \n \n /*\n@@ -677,7 +676,8 @@ struct mallinfo __libc_mallinfo(void);\n Equivalent to valloc(minimum-page-that-holds(n)), that is,\n round up n to nearest pagesize.\n */\n-void* __libc_pvalloc(size_t);\n+void *__libc_pvalloc_core (size_t);\n+libc_hidden_proto (__libc_pvalloc_core)\n \n /*\n malloc_trim(size_t pad);\n@@ -720,7 +720,8 @@ int __malloc_trim(size_t);\n assert(malloc_usable_size(p) >= 256);\n \n */\n-size_t __malloc_usable_size(void*);\n+size_t __malloc_usable_size_core (void *);\n+libc_hidden_proto (__malloc_usable_size_core)\n \n /*\n malloc_stats();\n@@ -2951,7 +2952,7 @@ tcache_key_initialize (void)\n \n /* We need tcache_key to be non-zero (otherwise tcache_double_free_verify's\n clearing of e->key would go unnoticed and it would loop getting called\n- through __libc_free), and we want tcache_key not to be a\n+ through __libc_free_core), and we want tcache_key not to be a\n commonly-occurring value in memory, so ensure a minimum amount of one and\n zero bits. */\n int minimum_bits = __WORDSIZE / 4;\n@@ -2983,7 +2984,7 @@ tcache_put_n (mchunkptr chunk, size_t tc_idx, tcache_entry **ep, bool mangled)\n {\n tcache_entry *e = (tcache_entry *) chunk2mem (chunk);\n \n- /* Mark this chunk as \"in the tcache\" so the test in __libc_free will\n+ /* Mark this chunk as \"in the tcache\" so the test in __libc_free_core will\n detect a double free. */\n e->key = tcache_key;\n \n@@ -3142,7 +3143,7 @@ tcache_double_free_verify (tcache_entry *e)\n or user data that happens to match the key. Since we are not sure,\n clear the key and retry freeing it. */\n e->key = 0;\n- __libc_free (e);\n+ __libc_free_core (e);\n }\n \n static void\n@@ -3258,7 +3259,7 @@ __libc_malloc2 (size_t bytes)\n }\n \n void *\n-__libc_malloc (size_t bytes)\n+__libc_malloc_core (size_t bytes)\n {\n #if USE_TCACHE\n size_t nb = checked_request2size (bytes);\n@@ -3284,17 +3285,17 @@ __libc_malloc (size_t bytes)\n \n return __libc_malloc2 (bytes);\n }\n-libc_hidden_def (__libc_malloc)\n+libc_hidden_def (__libc_malloc_core)\n \n static void __attribute_noinline__\n tcache_free_init (void *mem)\n {\n tcache_init (NULL);\n- __libc_free (mem);\n+ __libc_free_core (mem);\n }\n \n void\n-__libc_free (void *mem)\n+__libc_free_core (void *mem)\n {\n mchunkptr p; /* chunk corresponding to mem */\n \n@@ -3352,10 +3353,10 @@ __libc_free (void *mem)\n \n _int_free_chunk (arena_for_chunk (p), p, size, 0);\n }\n-libc_hidden_def (__libc_free)\n+libc_hidden_def (__libc_free_core)\n \n void *\n-__libc_realloc (void *oldmem, size_t bytes)\n+__libc_realloc_core (void *oldmem, size_t bytes)\n {\n mstate ar_ptr;\n INTERNAL_SIZE_T nb; /* padded request size */\n@@ -3364,12 +3365,12 @@ __libc_realloc (void *oldmem, size_t bytes)\n \n /* realloc of null is supposed to be same as malloc */\n if (oldmem == NULL)\n- return __libc_malloc (bytes);\n+ return __libc_malloc_core (bytes);\n \n #if REALLOC_ZERO_BYTES_FREES\n if (bytes == 0)\n {\n- __libc_free (oldmem); return NULL;\n+ __libc_free_core (oldmem); return NULL;\n }\n #endif\n \n@@ -3434,7 +3435,7 @@ __libc_realloc (void *oldmem, size_t bytes)\n \treturn oldmem;\n \n /* Must alloc, copy, free. */\n- newmem = __libc_malloc (bytes);\n+ newmem = __libc_malloc_core (bytes);\n if (newmem == NULL)\n return NULL; /* propagate failure */\n \n@@ -3466,7 +3467,7 @@ __libc_realloc (void *oldmem, size_t bytes)\n {\n /* Try harder to allocate memory in other arenas. */\n LIBC_PROBE (memory_realloc_retry, 2, bytes, oldmem);\n- newp = __libc_malloc (bytes);\n+ newp = __libc_malloc_core (bytes);\n if (newp != NULL)\n {\n \t size_t sz = memsize (oldp);\n@@ -3478,10 +3479,10 @@ __libc_realloc (void *oldmem, size_t bytes)\n \n return newp;\n }\n-libc_hidden_def (__libc_realloc)\n+libc_hidden_def (__libc_realloc_core)\n \n void *\n-__libc_memalign (size_t alignment, size_t bytes)\n+__libc_memalign_core (size_t alignment, size_t bytes)\n {\n /* Round the alignment up to a power of 2. Reject alignments that overflow\n when rounded up. Zero alignment is handled by _mid_memalign. */\n@@ -3498,7 +3499,7 @@ __libc_memalign (size_t alignment, size_t bytes)\n \n return _mid_memalign (alignment, bytes);\n }\n-libc_hidden_def (__libc_memalign)\n+libc_hidden_def (__libc_memalign_core)\n \n /* For ISO C17. */\n void *\n@@ -3551,7 +3552,7 @@ _mid_memalign (size_t alignment, size_t bytes)\n \n /* If we need less alignment than we give anyway, just relay to malloc. */\n if (alignment <= MALLOC_ALIGNMENT)\n- return __libc_malloc (bytes);\n+ return __libc_malloc_core (bytes);\n \n #if USE_TCACHE\n void *victim = tcache_get_align (checked_request2size (bytes), alignment);\n@@ -3586,13 +3587,14 @@ _mid_memalign (size_t alignment, size_t bytes)\n }\n \n void *\n-__libc_valloc (size_t bytes)\n+__libc_valloc_core (size_t bytes)\n {\n return _mid_memalign (GLRO (dl_pagesize), bytes);\n }\n+libc_hidden_def (__libc_valloc_core)\n \n void *\n-__libc_pvalloc (size_t bytes)\n+__libc_pvalloc_core (size_t bytes)\n {\n size_t pagesize = GLRO (dl_pagesize);\n size_t rounded_bytes;\n@@ -3607,6 +3609,7 @@ __libc_pvalloc (size_t bytes)\n \n return _mid_memalign (pagesize, rounded_bytes & -pagesize);\n }\n+libc_hidden_def (__libc_pvalloc_core)\n \n static void * __attribute_noinline__\n __libc_calloc2 (size_t sz)\n@@ -3703,7 +3706,7 @@ __libc_calloc2 (size_t sz)\n }\n \n void *\n-__libc_calloc (size_t n, size_t elem_size)\n+__libc_calloc_core (size_t n, size_t elem_size)\n {\n size_t bytes;\n \n@@ -3747,6 +3750,7 @@ __libc_calloc (size_t n, size_t elem_size)\n #endif\n return __libc_calloc2 (bytes);\n }\n+libc_hidden_def (__libc_calloc_core)\n #endif /* IS_IN (libc) */\n \n /*\n@@ -4754,12 +4758,13 @@ musable (void *mem)\n \n #if IS_IN (libc)\n size_t\n-__malloc_usable_size (void *m)\n+__malloc_usable_size_core (void *m)\n {\n if (m == NULL)\n return 0;\n return musable (m);\n }\n+libc_hidden_def (__malloc_usable_size_core)\n #endif\n \n /*\n@@ -5458,26 +5463,40 @@ __malloc_info (int options, FILE *fp)\n }\n #if IS_IN (libc)\n weak_alias (__malloc_info, malloc_info)\n-\n-weak_alias (__libc_calloc, calloc)\n-strong_alias (__libc_free, free)\n-strong_alias (__libc_malloc, malloc)\n-weak_alias (__libc_memalign, memalign)\n-strong_alias (__libc_realloc, realloc)\n-weak_alias (__libc_valloc, valloc)\n-weak_alias (__libc_pvalloc, pvalloc)\n weak_alias (__libc_mallinfo, mallinfo)\n weak_alias (__libc_mallinfo2, mallinfo2)\n weak_alias (__libc_mallopt, mallopt)\n-\n weak_alias (__malloc_stats, malloc_stats)\n-weak_alias (__malloc_usable_size, malloc_usable_size)\n weak_alias (__malloc_trim, malloc_trim)\n-#endif\n \n-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)\n-compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);\n-#endif\n+/* On targets that do not support ifuncs we alias externally visible\n+ functions as well as the __libc_* functions to their respective\n+ *_core symbols.\n+\n+ For ifunc prototypes and resolvers see sysdeps/generic/malloc-ifuncs.h.\n+ */\n+# if !HAVE_IFUNC\n+strong_alias (__libc_malloc_core, malloc)\n+strong_alias (__libc_malloc_core, __libc_malloc)\n+weak_alias (__libc_calloc_core, calloc)\n+strong_alias (__libc_calloc_core, __libc_calloc)\n+weak_alias (__libc_memalign_core, memalign)\n+strong_alias (__libc_memalign_core, __libc_memalign)\n+weak_alias (__libc_valloc_core, valloc)\n+strong_alias (__libc_valloc_core, __libc_valloc)\n+weak_alias (__libc_pvalloc_core, pvalloc)\n+strong_alias (__libc_pvalloc_core, __libc_pvalloc)\n+strong_alias (__libc_realloc_core, realloc)\n+strong_alias (__libc_realloc_core, __libc_realloc)\n+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)\n+compat_symbol (libc, __libc_free_core, cfree, GLIBC_2_0);\n+# endif\n+strong_alias (__libc_free_core, free)\n+strong_alias (__libc_free_core, __libc_free)\n+weak_alias (__malloc_usable_size_core, malloc_usable_size)\n+# endif /* !HAVE_IFUNC */\n+\n+#endif /* IS_IN (libc) */\n \n /* ------------------------------------------------------------\n History:\ndiff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile\nindex eecc4ad445..9c31e16d52 100644\n--- a/sysdeps/aarch64/Makefile\n+++ b/sysdeps/aarch64/Makefile\n@@ -102,6 +102,9 @@ $(objpfx)tst-sme-clone3: $(objpfx)clone3.o $(objpfx)__arm_za_disable.o\n endif\n \n ifeq ($(subdir),malloc)\n+sysdep_routines += \\\n+ malloc-ifuncs \\\n+ # sysdep_routines\n sysdep_malloc_debug_routines += \\\n __mtag_tag_region \\\n __mtag_tag_zero_region \\\ndiff --git a/sysdeps/aarch64/malloc-ifuncs.c b/sysdeps/aarch64/malloc-ifuncs.c\nnew file mode 100644\nindex 0000000000..b6adb36937\n--- /dev/null\n+++ b/sysdeps/aarch64/malloc-ifuncs.c\n@@ -0,0 +1,85 @@\n+/* Code for ifunc resolvers for malloc: aarch64 version.\n+ Copyright (C) 2026 Free Software Foundation, Inc.\n+ This file is part of the GNU C Library.\n+\n+ The GNU C Library is free software; you can redistribute it and/or\n+ modify it under the terms of the GNU Lesser General Public\n+ License as published by the Free Software Foundation; either\n+ version 2.1 of the License, or (at your option) any later version.\n+\n+ The GNU C Library is distributed in the hope that it will be useful,\n+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ Lesser General Public License for more details.\n+\n+ You should have received a copy of the GNU Lesser General Public\n+ License along with the GNU C Library; if not, see\n+ <https://www.gnu.org/licenses/>. */\n+\n+#if IS_IN (libc)\n+\n+#include <malloc/malloc-internal.h>\n+#include <malloc-ifuncs.h>\n+\n+/* AArch64-specific resolvers for malloc ifuncs. */\n+\n+IFUNC_PROTO (__libc_malloc);\n+IFUNC_RESOLVER (__libc_malloc, arg0, arg1)\n+{\n+ return __libc_malloc_core;\n+}\n+strong_alias (__libc_malloc, malloc)\n+\n+IFUNC_PROTO (__libc_calloc);\n+IFUNC_RESOLVER (__libc_calloc, arg0, arg1)\n+{\n+ return __libc_calloc_core;\n+}\n+weak_alias (__libc_calloc, calloc)\n+\n+IFUNC_PROTO (__libc_memalign);\n+IFUNC_RESOLVER (__libc_memalign, arg0, arg1)\n+{\n+ return __libc_memalign_core;\n+}\n+weak_alias (__libc_memalign, memalign)\n+\n+IFUNC_PROTO (__libc_valloc);\n+IFUNC_RESOLVER (__libc_valloc, arg0, arg1)\n+{\n+ return __libc_valloc_core;\n+}\n+weak_alias (__libc_valloc, valloc)\n+\n+IFUNC_PROTO (__libc_pvalloc);\n+IFUNC_RESOLVER (__libc_pvalloc, arg0, arg1)\n+{\n+ return __libc_pvalloc_core;\n+}\n+weak_alias (__libc_pvalloc, pvalloc)\n+\n+IFUNC_PROTO (__libc_realloc);\n+IFUNC_RESOLVER (__libc_realloc, arg0, arg1)\n+{\n+ return __libc_realloc_core;\n+}\n+strong_alias (__libc_realloc, realloc)\n+\n+IFUNC_PROTO (__libc_free);\n+IFUNC_RESOLVER (__libc_free, arg0, arg1)\n+{\n+ return __libc_free_core;\n+}\n+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)\n+compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);\n+# endif\n+strong_alias (__libc_free, free)\n+\n+IFUNC_PROTO (__malloc_usable_size);\n+IFUNC_RESOLVER (__malloc_usable_size, arg0, arg1)\n+{\n+ return __malloc_usable_size_core;\n+}\n+weak_alias (__malloc_usable_size, malloc_usable_size)\n+\n+#endif /* IS_IN (libc) */\ndiff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile\nindex c34b113e61..4f89941452 100644\n--- a/sysdeps/generic/Makefile\n+++ b/sysdeps/generic/Makefile\n@@ -40,6 +40,9 @@ endif\n endif\n \n ifeq ($(subdir),malloc)\n+sysdep_routines += \\\n+ malloc-ifuncs \\\n+ # sysdep_routines\n sysdep_malloc_debug_routines += \\\n hugepages \\\n # sysdep_malloc_debug_routines\ndiff --git a/sysdeps/generic/malloc-ifuncs.c b/sysdeps/generic/malloc-ifuncs.c\nnew file mode 100644\nindex 0000000000..08a29f0bf6\n--- /dev/null\n+++ b/sysdeps/generic/malloc-ifuncs.c\n@@ -0,0 +1,94 @@\n+/* Code for ifunc resolvers for malloc: generic version.\n+ Copyright (C) 2026 Free Software Foundation, Inc.\n+ This file is part of the GNU C Library.\n+\n+ The GNU C Library is free software; you can redistribute it and/or\n+ modify it under the terms of the GNU Lesser General Public\n+ License as published by the Free Software Foundation; either\n+ version 2.1 of the License, or (at your option) any later version.\n+\n+ The GNU C Library is distributed in the hope that it will be useful,\n+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ Lesser General Public License for more details.\n+\n+ You should have received a copy of the GNU Lesser General Public\n+ License along with the GNU C Library; if not, see\n+ <https://www.gnu.org/licenses/>. */\n+\n+#if IS_IN (libc)\n+\n+#include <malloc/malloc-internal.h>\n+#include <malloc-ifuncs.h>\n+\n+# if HAVE_IFUNC\n+\n+/* These resolvers are used by default unless overridden by a target.\n+ The target-specific resolvers must respect this logic if the default\n+ resolvers replicating it where appropriate.\n+\n+ Any aliases for mallo API functions must be defined here as well\n+ and re-defined along with the target-specific resolvers. */\n+\n+IFUNC_PROTO (__libc_malloc);\n+IFUNC_RESOLVER (__libc_malloc, arg0, arg1)\n+{\n+ return __libc_malloc_core;\n+}\n+strong_alias (__libc_malloc, malloc)\n+\n+IFUNC_PROTO (__libc_calloc);\n+IFUNC_RESOLVER (__libc_calloc, arg0, arg1)\n+{\n+ return __libc_calloc_core;\n+}\n+weak_alias (__libc_calloc, calloc)\n+\n+IFUNC_PROTO (__libc_memalign);\n+IFUNC_RESOLVER (__libc_memalign, arg0, arg1)\n+{\n+ return __libc_memalign_core;\n+}\n+weak_alias (__libc_memalign, memalign)\n+\n+IFUNC_PROTO (__libc_valloc);\n+IFUNC_RESOLVER (__libc_valloc, arg0, arg1)\n+{\n+ return __libc_valloc_core;\n+}\n+weak_alias (__libc_valloc, valloc)\n+\n+IFUNC_PROTO (__libc_pvalloc);\n+IFUNC_RESOLVER (__libc_pvalloc, arg0, arg1)\n+{\n+ return __libc_pvalloc_core;\n+}\n+weak_alias (__libc_pvalloc, pvalloc)\n+\n+IFUNC_PROTO (__libc_realloc);\n+IFUNC_RESOLVER (__libc_realloc, arg0, arg1)\n+{\n+ return __libc_realloc_core;\n+}\n+strong_alias (__libc_realloc, realloc)\n+\n+IFUNC_PROTO (__libc_free);\n+IFUNC_RESOLVER (__libc_free, arg0, arg1)\n+{\n+ return __libc_free_core;\n+}\n+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)\n+compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);\n+# endif\n+strong_alias (__libc_free, free)\n+\n+IFUNC_PROTO (__malloc_usable_size);\n+IFUNC_RESOLVER (__malloc_usable_size, arg0, arg1)\n+{\n+ return __malloc_usable_size_core;\n+}\n+weak_alias (__malloc_usable_size, malloc_usable_size)\n+\n+# endif /* HAVE_IFUNC */\n+\n+#endif /* IS_IN (libc) */\ndiff --git a/sysdeps/generic/malloc-ifuncs.h b/sysdeps/generic/malloc-ifuncs.h\nnew file mode 100644\nindex 0000000000..1b1f3fdd2e\n--- /dev/null\n+++ b/sysdeps/generic/malloc-ifuncs.h\n@@ -0,0 +1,62 @@\n+/* Definitions for ifunc resolvers for malloc: generic version.\n+ Copyright (C) 2026 Free Software Foundation, Inc.\n+ This file is part of the GNU C Library.\n+\n+ The GNU C Library is free software; you can redistribute it and/or\n+ modify it under the terms of the GNU Lesser General Public\n+ License as published by the Free Software Foundation; either\n+ version 2.1 of the License, or (at your option) any later version.\n+\n+ The GNU C Library is distributed in the hope that it will be useful,\n+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ Lesser General Public License for more details.\n+\n+ You should have received a copy of the GNU Lesser General Public\n+ License along with the GNU C Library; if not, see\n+ <https://www.gnu.org/licenses/>. */\n+\n+#ifndef _GENERIC_MALLOC_IFUNCS_H\n+#define _GENERIC_MALLOC_IFUNCS_H\n+\n+#if HAVE_IFUNC\n+\n+#include <stddef.h>\n+#include <sys/cdefs.h>\n+#include <shlib-compat.h>\n+\n+/* Core implementations of malloc functions. An ifunc resolver must\n+ use this implementations as a fallback option. Other implementations\n+ may internally call these core function. */\n+void *__libc_malloc_core (size_t);\n+libc_hidden_proto (__libc_malloc_core)\n+void *__libc_calloc_core (size_t, size_t);\n+libc_hidden_proto (__libc_calloc_core)\n+void *__libc_memalign_core (size_t, size_t);\n+libc_hidden_proto (__libc_memalign_core)\n+void *__libc_valloc_core (size_t);\n+libc_hidden_proto (__libc_valloc_core)\n+void *__libc_pvalloc_core (size_t);\n+libc_hidden_proto (__libc_pvalloc_core)\n+void *__libc_realloc_core (void *, size_t);\n+libc_hidden_proto (__libc_realloc_core)\n+void __libc_free_core (void *);\n+libc_hidden_proto (__libc_free_core)\n+size_t __malloc_usable_size_core (void *);\n+libc_hidden_proto (__malloc_usable_size_core)\n+\n+/* Macros for defining ifunc resolvers for malloc functions. */\n+#define IFUNC_RESOLVER_NAME(fn) fn ## _resolver\n+#define STR(x) #x\n+#define XSTR(x) STR(x)\n+#define IFUNC_PROTO(fn) \\\n+ __typeof (fn ## _core) fn \\\n+ __attribute__ ((ifunc (XSTR(IFUNC_RESOLVER_NAME(fn)))))\n+#define IFUNC_RESOLVER(fn, a0, a1) \\\n+ static __attribute_used__ \\\n+ __typeof (fn ## _core) *IFUNC_RESOLVER_NAME(fn) \\\n+ (uint64_t a0, const uint64_t a1[])\n+\n+#endif /* HAVE_IFUNC */\n+\n+#endif /* _GENERIC_MALLOC_IFUNCS_H */\n", "prefixes": [ "2/2" ] }