From patchwork Tue Jul 28 16:12:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 140108 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 730EA4BB3BC4 for ; Tue, 28 Jul 2026 16:13:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 730EA4BB3BC4 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=foss header.b=Vppx589h X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 15D854BAE7CA for ; Tue, 28 Jul 2026 16:12:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 15D854BAE7CA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 15D854BAE7CA Authentication-Results: sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785255153; cv=none; b=Ie4SyEFScBlgOOSjsFKQxKnWqR+8Zi94mke/iRiSVH+qENQ4UBpCuRzieVd/b6ffJnq7Ci1l75AsZRMj+Rt0EmXLtvK7KiZf9eAgKD9skkGyjjpe3GZICFOViiEBqoYwc129pj5d1fUdFkUk0LrWUt8XG0nrS6fDKfRL+a0ABmg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785255153; c=relaxed/simple; bh=AYXGv7X1lsJsayfWKY0KCenSQ7z1KDYI1svV4s3I+SI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Io79qkWdr41503sWcrCELf+j8tUyHfl3tE6Auqcsd9dHrvGvLAH2KqsAoeTWtpuEmIbN6aoNa3NrsSoBv+oIRQ675bHNUcIMLNH5T0qwOnpSHtAo3zpjW2j8pLOIOTkuVAQRA+gt7+/hdhul6iiokDxugY5y3bMxiP6SZhbCUj8= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=foss header.b=Vppx589h DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 15D854BAE7CA Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 75B6616A3; Tue, 28 Jul 2026 09:12:28 -0700 (PDT) Received: from fdebian.localdomain (unknown [10.57.43.141]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 581283F763; Tue, 28 Jul 2026 09:12:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785255152; bh=AYXGv7X1lsJsayfWKY0KCenSQ7z1KDYI1svV4s3I+SI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vppx589hBSpceTdtjt9NBBLeFQccLfOB4upBmOSOcm368zW4UecMWTbbEMlYgg+7L jU4KDFomxPlWqG4Im27Deq8wbVEuwcKHiWj5lLKxN2KEww7VYIg+ZhO4bTSPOdQaQC Wgv/zULfBssuTQJs+T9ekgtjrTKKGCHhHIj1kFOI= From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: "Andreas K . Huettel" , Wilco Dijkstra , Carlos O'Donell , Adhemerval Zanella , Muhammad Kamran , Florian Weimer Subject: [PATCH 1/2] malloc: Refactor malloc API into a separate header Date: Tue, 28 Jul 2026 17:12:14 +0100 Message-ID: <20260728161215.1512331-2-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260728161215.1512331-1-yury.khrustalev@arm.com> References: <20260728161215.1512331-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org This commit moves declarations for various malloc functions from the malloc.c file to a separate header that can be used to include these declarations in other source files. No functional change intended. --- malloc/malloc-internal.h | 1 + malloc/malloc.c | 148 +++--------------------------- sysdeps/generic/malloc-api.h | 172 +++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 134 deletions(-) create mode 100644 sysdeps/generic/malloc-api.h diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h index a6340bfd88..4b36a76cf8 100644 --- a/malloc/malloc-internal.h +++ b/malloc/malloc-internal.h @@ -24,6 +24,7 @@ #include #include #include +#include /* 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 8fe8b18340..4866c59e65 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -455,105 +455,11 @@ static int extra_mmap_prot = 0; other numbers that might be of interest. */ - -/* ---------- description of public routines ------------ */ - #if IS_IN (libc) -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or null - if no space is available. Additionally, on failure, errno is - set to ENOMEM on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit - systems.) On most systems, size_t is an unsigned type, so calls - with negative arguments are interpreted as requests for huge amounts - of space, which will often fail. The maximum supported value of n - differs across systems, but is in all cases less than the maximum - representable value of a size_t. -*/ -void *__libc_malloc (size_t); -libc_hidden_proto (__libc_malloc) static void *__libc_calloc2 (size_t); static void *__libc_malloc2 (size_t); -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. It can have arbitrary (i.e., bad!) - effects if p has already been freed. - - Unless disabled (using mallopt), freeing very large spaces will - when possible, automatically trigger operations that give - back unused memory to the system, thus reducing program footprint. -*/ -void __libc_free(void*); -libc_hidden_proto (__libc_free) - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* __libc_calloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p when possible, otherwise it employs the - equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. Unless the #define - REALLOC_ZERO_BYTES_FREES is set, realloc with a size argument of - zero (re)allocates a minimum-sized chunk. - - Large chunks that were internally obtained via mmap will always be - grown using malloc-copy-free sequences unless the system supports - MREMAP (currently only linux). - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ -void* __libc_realloc(void*, size_t); -libc_hidden_proto (__libc_realloc) - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* __libc_memalign(size_t, size_t); -libc_hidden_proto (__libc_memalign) - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* __libc_valloc(size_t); - - - /* mallinfo() Returns (by copy) a struct containing various summary statistics: @@ -578,14 +484,6 @@ libc_hidden_proto (__libc_mallinfo2) struct mallinfo __libc_mallinfo(void); - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* __libc_pvalloc(size_t); - /* malloc_trim(size_t pad); @@ -612,23 +510,6 @@ void* __libc_pvalloc(size_t); */ int __malloc_trim(size_t); -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); - -*/ -size_t __malloc_usable_size(void*); - /* malloc_stats(); Prints on stderr the amount of space obtained from the system (both @@ -651,12 +532,6 @@ size_t __malloc_usable_size(void*); */ void __malloc_stats(void); -/* - posix_memalign(void **memptr, size_t alignment, size_t size); - - POSIX wrapper like memalign(), checking for validity of size. -*/ -int __posix_memalign(void **, size_t, size_t); #endif /* IS_IN (libc) */ /* @@ -3316,10 +3191,8 @@ __libc_memalign (size_t alignment, size_t bytes) } libc_hidden_def (__libc_memalign) -/* For ISO C17. */ void * -weak_function -aligned_alloc (size_t alignment, size_t bytes) +__aligned_alloc (size_t alignment, size_t bytes) { /* Starting with ISO C17 the standard requires an error for alignments that are not supported. Only integral powers of 2 are valid. */ @@ -3331,11 +3204,10 @@ aligned_alloc (size_t alignment, size_t bytes) return _mid_memalign (alignment, bytes); } +libc_hidden_def (__aligned_alloc) -/* For ISO C23. */ void -weak_function -free_sized (void *ptr, __attribute_maybe_unused__ size_t size) +__free_sized (void *ptr, __attribute_maybe_unused__ size_t size) { /* We do not perform validation that size is the same as the original requested size at this time. We leave that to the sanitizers. We @@ -3344,11 +3216,10 @@ free_sized (void *ptr, __attribute_maybe_unused__ size_t size) free (ptr); } +libc_hidden_def (__free_sized) -/* For ISO C23. */ void -weak_function -free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment, +__free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment, __attribute_maybe_unused__ size_t size) { /* We do not perform validation that size and alignment is the same as @@ -3358,6 +3229,7 @@ free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment, free (ptr); } +libc_hidden_def (__free_aligned_sized) static void * _mid_memalign (size_t alignment, size_t bytes) @@ -3406,6 +3278,7 @@ __libc_valloc (size_t bytes) { return _mid_memalign (GLRO (dl_pagesize), bytes); } +libc_hidden_def (__libc_valloc) void * __libc_pvalloc (size_t bytes) @@ -3423,6 +3296,7 @@ __libc_pvalloc (size_t bytes) return _mid_memalign (pagesize, rounded_bytes & -pagesize); } +libc_hidden_def (__libc_pvalloc) static void * __attribute_noinline__ __libc_calloc2 (size_t sz) @@ -3544,6 +3418,7 @@ __libc_calloc (size_t n, size_t elem_size) #endif return __libc_calloc2 (bytes); } +libc_hidden_def (__libc_calloc) #endif /* IS_IN (libc) */ /* @@ -4548,6 +4423,7 @@ __malloc_usable_size (void *m) return 0; return musable (m); } +libc_hidden_def (__malloc_usable_size) #endif /* IS_IN (libc) */ /* @@ -5129,6 +5005,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size) *memptr = mem; return 0; } +libc_hidden_def (__posix_memalign) #endif /* IS_IN (libc) */ @@ -5300,6 +5177,9 @@ weak_alias (__posix_memalign, posix_memalign) weak_alias (__libc_valloc, valloc) weak_alias (__libc_pvalloc, pvalloc) weak_alias (__malloc_usable_size, malloc_usable_size) +weak_alias (__aligned_alloc, aligned_alloc) +weak_alias (__free_sized, free_sized) +weak_alias (__free_aligned_sized, free_aligned_sized) weak_alias (__malloc_info, malloc_info) weak_alias (__libc_mallinfo, mallinfo) diff --git a/sysdeps/generic/malloc-api.h b/sysdeps/generic/malloc-api.h new file mode 100644 index 0000000000..6614d89848 --- /dev/null +++ b/sysdeps/generic/malloc-api.h @@ -0,0 +1,172 @@ +/* Description of public routines. + 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; see the file COPYING.LIB. If + not, see . */ + +#ifndef _MALLOC_API_H +#define _MALLOC_API_H + +#include +#include + +#if IS_IN (libc) + +/* + malloc (size_t n) + + Returns a pointer to a newly allocated chunk of at least n bytes, or null + if no space is available. Additionally, on failure, errno is + set to ENOMEM on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit + systems.) On most systems, size_t is an unsigned type, so calls + with negative arguments are interpreted as requests for huge amounts + of space, which will often fail. The maximum supported value of n + differs across systems, but is in all cases less than the maximum + representable value of a size_t. +*/ +void *__libc_malloc (size_t n); +libc_hidden_proto (__libc_malloc) + +/* + calloc (size_t n_elements, size_t element_size) + + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void *__libc_calloc (size_t n, size_t element_size); +libc_hidden_proto (__libc_calloc) + +/* + memalign (size_t alignment, size_t n) + + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void *__libc_memalign (size_t alignment, size_t n); +libc_hidden_proto (__libc_memalign) + +/* + valloc (size_t n) + + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void *__libc_valloc (size_t n); +libc_hidden_proto (__libc_valloc) + +/* + pvalloc (size_t n) + + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void *__libc_pvalloc (size_t n); +libc_hidden_proto (__libc_pvalloc) + +/* + realloc (void* p, size_t n) + + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p when possible, otherwise it employs the + equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + If n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. Unless the #define + REALLOC_ZERO_BYTES_FREES is set, realloc with a size argument of + zero (re)allocates a minimum-sized chunk. + + Large chunks that were internally obtained via mmap will always be + grown using malloc-copy-free sequences unless the system supports + MREMAP (currently only linux). + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ +void *__libc_realloc (void *p, size_t n); +libc_hidden_proto (__libc_realloc) + +/* + free (void* p) + + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. It can have arbitrary (i.e., bad!) + effects if p has already been freed. + + Unless disabled (using mallopt), freeing very large spaces will + when possible, automatically trigger operations that give + back unused memory to the system, thus reducing program footprint. +*/ +void __libc_free (void *p); +libc_hidden_proto (__libc_free) + +/* + malloc_usable_size (void* p) + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); + +*/ +size_t __malloc_usable_size (void *p); +libc_hidden_proto (__malloc_usable_size) + +/* + posix_memalign (void **memptr, size_t alignment, size_t size) + + POSIX wrapper like memalign(), checking for validity of size. +*/ +int __posix_memalign (void **memptr, size_t alignment, size_t size); +libc_hidden_proto (__posix_memalign) + +/* For ISO C17. */ +void *__aligned_alloc (size_t alignment, size_t bytes); +libc_hidden_proto (__aligned_alloc) + +/* For ISO C23. */ +void __free_sized (void *ptr, size_t size); +libc_hidden_proto (__free_sized) +void __free_aligned_sized (void *ptr, size_t alignment, size_t size); +libc_hidden_proto (__free_aligned_sized) + +#endif /* IS_IN (libc) */ + +#endif /* _MALLOC_API_H */ From patchwork Tue Jul 28 16:12:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 140109 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BD15A4B99F74 for ; Tue, 28 Jul 2026 16:14:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BD15A4B99F74 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=foss header.b=DFQ7WO6J X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 525134B9DB71 for ; Tue, 28 Jul 2026 16:12:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 525134B9DB71 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 525134B9DB71 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785255154; cv=none; b=Ovrza/7RpOTuY8839Gptn1YFQGndlwdPWbu3kuyPlYkBVZAhdpuMrkJFfAOxMUJoFURjbqfx0KvoP9Rw2L9TsS52hT7FG7TRKdAIg59j1nppEtsPuSr5AXO/TTQmHLYRTR4wNi4bXaHXsF4VsJLt9ea5JNWciiNWmPjoVPaXhYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785255154; c=relaxed/simple; bh=48e07v6MOPOJ+mTuqs7WHWE26X5ST6JImWY6OP032/4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Z1IVCqJffWJ38Z7pvDldfRaJno2Jd9an4L4gv0rtaicFOU8OqQvh4YDx3lXVn61lkGZAKQMPEaqvh3tC5Wkz7TGECuB50c3YzCDOIz1Md0XPwsSUFuaBzxDPqTMrG822pumaJFW5g2zb0FeQWlusc94UfV31AgdhQYC3KgSmER4= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=foss header.b=DFQ7WO6J DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 525134B9DB71 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DD20716F2; Tue, 28 Jul 2026 09:12:29 -0700 (PDT) Received: from fdebian.localdomain (unknown [10.57.43.141]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E0D543F763; Tue, 28 Jul 2026 09:12:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785255154; bh=48e07v6MOPOJ+mTuqs7WHWE26X5ST6JImWY6OP032/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DFQ7WO6JnNItWQS3+DNJnfuIt5QSIIW009z/NKzG6T+Mrdn0jK5oQCFm3ZZWx/bm7 ryqoKX5kdqRX7aI1QGxXwpLsS58+kz1/HeAtRpOfNHprluo+h2NSn260R8oTXODRJA n9ywcBxN64aFb+e3zzjaQ2TVU64ku0PWTOhzKpX4= From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: "Andreas K . Huettel" , Wilco Dijkstra , Carlos O'Donell , Adhemerval Zanella , Muhammad Kamran , Florian Weimer Subject: [PATCH 2/2] malloc: aarch64: Add ifuncs for malloc functions Date: Tue, 28 Jul 2026 17:12:15 +0100 Message-ID: <20260728161215.1512331-3-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260728161215.1512331-1-yury.khrustalev@arm.com> References: <20260728161215.1512331-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org 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 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 #include #include +#include /* 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 + . */ + +#include "malloc-ifuncs.h" + +#if USE_MULTIARCH_MALLOC +# if IS_IN (libc) + +#include +#include +#include + +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 + . */ + +#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 + . */ + +#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 */