[PATCH v2 3/3] malloc: Remove currently broken memory tagging
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed May 20 20:30:13 GMT 2026
On 20/05/26 10:27, Yury Khrustalev wrote:
> Remove AArch64-specific code, that is currently broken, from the
> core malloc implementation.
>
> Code clean-up, no functional change unrelated to memory tagging.
Why keep the MTE code if it is unused now?
> ---
> malloc/malloc-check.c | 30 ++--
> malloc/malloc.c | 163 ++----------------
> sysdeps/aarch64/Makefile | 9 +-
> ...__mtag_tag_region.S => __mte_tag_region.S} | 4 +-
> ..._zero_region.S => __mte_tag_region_zero.S} | 4 +-
> .../aarch64/{libc-mtag.h => aarch64-mte.h} | 70 ++++----
> sysdeps/generic/libc-mtag.h | 73 --------
> 7 files changed, 70 insertions(+), 283 deletions(-)
> rename sysdeps/aarch64/{__mtag_tag_region.S => __mte_tag_region.S} (97%)
> rename sysdeps/aarch64/{__mtag_tag_zero_region.S => __mte_tag_region_zero.S} (97%)
> rename sysdeps/aarch64/{libc-mtag.h => aarch64-mte.h} (57%)
> delete mode 100644 sysdeps/generic/libc-mtag.h
>
> diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
> index ae5025d69a..8ed419c6e9 100644
> --- a/malloc/malloc-check.c
> +++ b/malloc/malloc-check.c
> @@ -19,12 +19,8 @@
> #define __mremap mremap
> #include "malloc.c"
>
> -/* When memory is tagged, the checking data is stored in the user part
> - of the chunk. We can't rely on the user not having modified the
> - tags, so fetch the tag at each location before dereferencing
> - it. */
> -#define SAFE_CHAR_OFFSET(p,offset) \
> - ((unsigned char *) tag_at (((unsigned char *) p) + offset))
> +#define CHAR_OFFSET(p,offset) \
> + ((unsigned char *) (((unsigned char *) p) + offset))
>
> /* A simple, standard set of debugging hooks. Overhead is `only' one
> byte per chunk; still this will catch most cases of double frees or
> @@ -58,7 +54,7 @@ malloc_check_get_size (void *mem)
> unsigned char magic = magicbyte (p);
>
> for (size = CHUNK_HDR_SZ + memsize (p) - 1;
> - (c = *SAFE_CHAR_OFFSET (p, size)) != magic;
> + (c = *CHAR_OFFSET (p, size)) != magic;
> size -= c)
> {
> if (c <= 0 || size < (c + CHUNK_HDR_SZ))
> @@ -95,9 +91,9 @@ mem2mem_check (void *ptr, size_t req_sz)
> if (block_sz == magic)
> --block_sz;
>
> - *SAFE_CHAR_OFFSET (m_ptr, i) = block_sz;
> + *CHAR_OFFSET (m_ptr, i) = block_sz;
> }
> - *SAFE_CHAR_OFFSET (m_ptr, req_sz) = magic;
> + *CHAR_OFFSET (m_ptr, req_sz) = magic;
> return (void *) m_ptr;
> }
>
> @@ -131,7 +127,7 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
> return NULL;
>
> for (sz = CHUNK_HDR_SZ + memsize (p) - 1;
> - (c = *SAFE_CHAR_OFFSET (p, sz)) != magic;
> + (c = *CHAR_OFFSET (p, sz)) != magic;
> sz -= c)
> {
> if (c == 0 || sz < (c + CHUNK_HDR_SZ))
> @@ -156,7 +152,7 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
> return NULL;
>
> for (sz = CHUNK_HDR_SZ + memsize (p) - 1;
> - (c = *SAFE_CHAR_OFFSET (p, sz)) != magic;
> + (c = *CHAR_OFFSET (p, sz)) != magic;
> sz -= c)
> {
> if (c == 0 || sz < (c + CHUNK_HDR_SZ))
> @@ -164,7 +160,7 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
> }
> }
>
> - unsigned char* safe_p = SAFE_CHAR_OFFSET (p, sz);
> + unsigned char* safe_p = CHAR_OFFSET (p, sz);
> *safe_p ^= 0xFF;
> if (magic_p)
> *magic_p = safe_p;
> @@ -204,7 +200,7 @@ malloc_check (size_t sz)
> top_check ();
> victim = _int_malloc (&main_arena, nb);
> __libc_lock_unlock (main_arena.mutex);
> - return mem2mem_check (tag_new_usable (victim), sz);
> + return mem2mem_check (victim, sz);
> }
>
> static void
> @@ -228,8 +224,6 @@ free_check (void *mem)
> }
> else
> {
> - /* Mark the chunk as belonging to the library again. */
> - (void)tag_region (chunk2mem (p), memsize (p));
> _int_free_chunk (&main_arena, p, chunksize (p), 1);
> __libc_lock_unlock (main_arena.mutex);
> }
> @@ -278,7 +272,7 @@ realloc_check (void *oldmem, size_t bytes)
> #if HAVE_MREMAP
> mchunkptr newp = mremap_chunk (oldp, chnb);
> if (newp)
> - newmem = chunk2mem_tag (newp);
> + newmem = chunk2mem (newp);
> else
> #endif
> {
> @@ -313,7 +307,7 @@ invert:
>
> __libc_lock_unlock (main_arena.mutex);
>
> - return mem2mem_check (tag_new_usable (newmem), bytes);
> + return mem2mem_check (newmem, bytes);
> }
>
> static void *
> @@ -355,7 +349,7 @@ memalign_check (size_t alignment, size_t bytes)
> top_check ();
> mem = _int_memalign (&main_arena, alignment, bytes + 1);
> __libc_lock_unlock (main_arena.mutex);
> - return mem2mem_check (tag_new_usable (mem), bytes);
> + return mem2mem_check (mem, bytes);
> }
>
> static void
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index d7224f775c..c1e1a9c659 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -233,9 +233,7 @@
> /* For ALIGN_UP et. al. */
> #include <libc-pointer-arith.h>
>
> -/* For memory tagging. */
> -#include <libc-mtag.h>
> -
> +/* For internal malloc interfaces and declarations. */
> #include <malloc/malloc-internal.h>
>
> /* For SINGLE_THREAD_P. */
> @@ -349,86 +347,8 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2);
> #define MORECORE (*__glibc_morecore)
> #define MORECORE_FAILURE NULL
>
> -/* Memory tagging. */
> -
> -/* Some systems support the concept of tagging (sometimes known as
> - coloring) memory locations on a fine grained basis. Each memory
> - location is given a color (normally allocated randomly) and
> - pointers are also colored. When the pointer is dereferenced, the
> - pointer's color is checked against the memory's color and if they
> - differ the access is faulted (sometimes lazily).
> -
> - We use this in glibc by maintaining a single color for the malloc
> - data structures that are interleaved with the user data and then
> - assigning separate colors for each block allocation handed out. In
> - this way simple buffer overruns will be rapidly detected. When
> - memory is freed, the memory is recolored back to the glibc default
> - so that simple use-after-free errors can also be detected.
> -
> - If memory is reallocated the buffer is recolored even if the
> - address remains the same. This has a performance impact, but
> - guarantees that the old pointer cannot mistakenly be reused (code
> - that compares old against new will see a mismatch and will then
> - need to behave as though realloc moved the data to a new location).
> -
> - Internal API for memory tagging support.
> -
> - The aim is to keep the code for memory tagging support as close to
> - the normal APIs in glibc as possible, so that if tagging is not
> - enabled in the library, or is disabled at runtime then standard
> - operations can continue to be used. Support macros are used to do
> - this:
> -
> - void *tag_new_zero_region (void *ptr, size_t size)
> -
> - Allocates a new tag, colors the memory with that tag, zeros the
> - memory and returns a pointer that is correctly colored for that
> - location. The non-tagging version will simply call memset with 0.
> -
> - void *tag_region (void *ptr, size_t size)
> -
> - Color the region of memory pointed to by PTR and size SIZE with
> - the color of PTR. Returns the original pointer.
> -
> - void *tag_new_usable (void *ptr)
> -
> - Allocate a new random color and use it to color the user region of
> - a chunk; this may include data from the subsequent chunk's header
> - if tagging is sufficiently fine grained. Returns PTR suitably
> - recolored for accessing the memory there.
> -
> - void *tag_at (void *ptr)
> -
> - Read the current color of the memory at the address pointed to by
> - PTR (ignoring it's current color) and return PTR recolored to that
> - color. PTR must be valid address in all other respects. When
> - tagging is not enabled, it simply returns the original pointer.
> -*/
> -
> static int extra_mmap_prot = 0;
>
> -static __always_inline void *
> -tag_region (void *ptr, size_t size)
> -{
> - return ptr;
> -}
> -
> -static __always_inline void *
> -tag_new_zero_region (void *ptr, size_t size)
> -{
> - return memset (ptr, 0, size);
> -}
> -
> -/* Defined later. */
> -static void *
> -tag_new_usable (void *ptr);
> -
> -static __always_inline void *
> -tag_at (void *ptr)
> -{
> - return ptr;
> -}
> -
>
> /*
> MORECORE-related declarations. By default, rely on sbrk
> @@ -1182,38 +1102,15 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> ---------- Size and alignment checks and conversions ----------
> */
>
> -/* Conversion from malloc headers to user pointers, and back. When
> - using memory tagging the user data and the malloc data structure
> - headers have distinct tags. Converting fully from one to the other
> - involves extracting the tag at the other address and creating a
> - suitable pointer using it. That can be quite expensive. There are
> - cases when the pointers are not dereferenced (for example only used
> - for alignment check) so the tags are not relevant, and there are
> - cases when user data is not tagged distinctly from malloc headers
> - (user data is untagged because tagging is done late in malloc and
> - early in free). User memory tagging across internal interfaces:
> -
> - sysmalloc: Returns untagged memory.
> - _int_malloc: Returns untagged memory.
> - _int_memalign: Returns untagged memory.
> - _int_memalign: Returns untagged memory.
> - _mid_memalign: Returns tagged memory.
> - _int_realloc: Takes and returns tagged memory.
> -*/
> -
> /* The chunk header is two SIZE_SZ elements, but this is used widely, so
> we define it here for clarity later. */
> #define CHUNK_HDR_SZ (2 * SIZE_SZ)
>
> -/* Convert a chunk address to a user mem pointer without correcting
> - the tag. */
> +/* Convert a chunk address to a user mem pointer. */
> #define chunk2mem(p) ((void*)((char*)(p) + CHUNK_HDR_SZ))
>
> -/* Convert a chunk address to a user mem pointer and extract the right tag. */
> -#define chunk2mem_tag(p) ((void*)tag_at ((char*)(p) + CHUNK_HDR_SZ))
> -
> -/* Convert a user mem pointer to a chunk address and extract the right tag. */
> -#define mem2chunk(mem) ((mchunkptr)tag_at (((char*)(mem) - CHUNK_HDR_SZ)))
> +/* Convert a user mem pointer to a chunk address. */
> +#define mem2chunk(mem) ((mchunkptr) (((char*)(mem) - CHUNK_HDR_SZ)))
>
> /* The smallest possible chunk */
> #define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize))
> @@ -1350,12 +1247,6 @@ checked_request2size (size_t req) __nonnull (1)
> dumped heap chunks. */
> #define memsize(p) (chunksize (p) - CHUNK_HDR_SZ + SIZE_SZ)
>
> -static __always_inline void *
> -tag_new_usable (void *ptr)
> -{
> - return ptr;
> -}
> -
> /* Huge page used for an mmap chunk. */
> #define MMAP_HP 0x1
>
> @@ -3063,7 +2954,7 @@ tcache_get_align (size_t nb, size_t alignment)
> if (te != NULL
> && csize == nb
> && PTR_IS_ALIGNED (te, alignment))
> - return tag_new_usable (tcache_get_n (tc_idx, tep, mangled));
> + return tcache_get_n (tc_idx, tep, mangled);
> }
> return NULL;
> }
> @@ -3181,7 +3072,7 @@ __libc_malloc2 (size_t bytes)
>
> if (SINGLE_THREAD_P)
> {
> - victim = tag_new_usable (_int_malloc (&main_arena, bytes));
> + victim = _int_malloc (&main_arena, bytes);
> assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
> &main_arena == arena_for_chunk (mem2chunk (victim)));
> return victim;
> @@ -3202,8 +3093,6 @@ __libc_malloc2 (size_t bytes)
> if (ar_ptr != NULL)
> __libc_lock_unlock (ar_ptr->mutex);
>
> - victim = tag_new_usable (victim);
> -
> assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
> ar_ptr == arena_for_chunk (mem2chunk (victim)));
> return victim;
> @@ -3222,14 +3111,14 @@ __libc_malloc (size_t bytes)
> if (__glibc_likely (tc_idx < TCACHE_SMALL_BINS))
> {
> if (tcache->entries[tc_idx] != NULL)
> - return tag_new_usable (tcache_get (tc_idx));
> + return tcache_get (tc_idx);
> }
> else
> {
> tc_idx = large_csize2tidx (nb);
> void *victim = tcache_get_large (tc_idx, nb);
> if (victim != NULL)
> - return tag_new_usable (victim);
> + return victim;
> }
> }
> #endif
> @@ -3255,9 +3144,6 @@ __libc_free (void *mem)
>
> p = mem2chunk (mem);
>
> - /* Mark the chunk as belonging to the library again. */
> - tag_region (chunk2mem (p), memsize (p));
> -
> INTERNAL_SIZE_T size = chunksize (p);
>
> if (__glibc_unlikely (misaligned_chunk (p)))
> @@ -3361,15 +3247,7 @@ __libc_realloc (void *oldmem, size_t bytes)
> #if HAVE_MREMAP
> newp = mremap_chunk (oldp, nb);
> if (newp)
> - {
> - void *newmem = chunk2mem_tag (newp);
> - /* Give the new block a different tag. This helps to ensure
> - that stale handles to the previous mapping are not
> - reused. There's a performance hit for both us and the
> - caller for doing this, so we might want to
> - reconsider. */
> - return tag_new_usable (newmem);
> - }
> + return chunk2mem (newp);
> #endif
> /* Return if shrinking and mremap was unsuccessful. */
> if (bytes <= usable)
> @@ -3411,10 +3289,8 @@ __libc_realloc (void *oldmem, size_t bytes)
> newp = __libc_malloc (bytes);
> if (newp != NULL)
> {
> - size_t sz = memsize (oldp);
> - memcpy (newp, oldmem, sz);
> - (void) tag_region (chunk2mem (oldp), sz);
> - _int_free_chunk (ar_ptr, oldp, chunksize (oldp), 0);
> + memcpy (newp, oldmem, memsize (oldp));
> + _int_free_chunk (ar_ptr, oldp, chunksize (oldp), 0);
> }
> }
>
> @@ -3498,7 +3374,7 @@ _mid_memalign (size_t alignment, size_t bytes)
> #if USE_TCACHE
> void *victim = tcache_get_align (checked_request2size (bytes), alignment);
> if (victim != NULL)
> - return tag_new_usable (victim);
> + return victim;
> #endif
>
> if (SINGLE_THREAD_P)
> @@ -3506,7 +3382,7 @@ _mid_memalign (size_t alignment, size_t bytes)
> p = _int_memalign (&main_arena, alignment, bytes);
> assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
> &main_arena == arena_for_chunk (mem2chunk (p)));
> - return tag_new_usable (p);
> + return p;
> }
>
> arena_get (ar_ptr, bytes + alignment + MINSIZE);
> @@ -3524,7 +3400,7 @@ _mid_memalign (size_t alignment, size_t bytes)
>
> assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
> ar_ptr == arena_for_chunk (mem2chunk (p)));
> - return tag_new_usable (p);
> + return p;
> }
>
> void *
> @@ -4429,7 +4305,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
> av->top = chunk_at_offset (oldp, nb);
> set_head (av->top, (newsize - nb) | PREV_INUSE);
> check_inuse_chunk (av, oldp);
> - return tag_new_usable (chunk2mem (oldp));
> + return chunk2mem (oldp);
> }
>
> /* Try to expand forward into next chunk; split off remainder below */
> @@ -4463,10 +4339,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
> else
> {
> void *oldmem = chunk2mem (oldp);
> - size_t sz = memsize (oldp);
> - (void) tag_region (oldmem, sz);
> - newmem = tag_new_usable (newmem);
> - memcpy (newmem, oldmem, sz);
> + memcpy (newmem, oldmem, memsize (oldp));
> _int_free_chunk (av, oldp, chunksize (oldp), 1);
> check_inuse_chunk (av, newp);
> return newmem;
> @@ -4488,8 +4361,6 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
> else /* split remainder */
> {
> remainder = chunk_at_offset (newp, nb);
> - /* Clear any user-space tags before writing the header. */
> - remainder = tag_region (remainder, remainder_size);
> set_head_size (newp, nb | (av != &main_arena ? NON_MAIN_ARENA : 0));
> set_head (remainder, remainder_size | PREV_INUSE |
> (av != &main_arena ? NON_MAIN_ARENA : 0));
> @@ -4499,7 +4370,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
> }
>
> check_inuse_chunk (av, newp);
> - return tag_new_usable (chunk2mem (newp));
> + return chunk2mem (newp);
> }
>
> /*
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index 2cf2903021..52ac85a75d 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -82,8 +82,8 @@ sysdep_headers += \
> sysdep_routines += \
> __alloc_gcs \
> __arm_za_disable \
> - __mtag_tag_region \
> - __mtag_tag_zero_region \
> + __mte_tag_region \
> + __mte_tag_region_zero \
> # sysdep_routines
>
> tests += \
> @@ -104,10 +104,7 @@ $(objpfx)tst-sme-za-disable-fail: $(objpfx)__arm_za_disable.o
> endif
>
> ifeq ($(subdir),malloc)
> -sysdep_malloc_debug_routines = \
> - __mtag_tag_region \
> - __mtag_tag_zero_region \
> - # sysdep_malloc_debug_routines
> +
> endif # malloc directory
>
> ifeq ($(subdir),support)
> diff --git a/sysdeps/aarch64/__mtag_tag_region.S b/sysdeps/aarch64/__mte_tag_region.S
> similarity index 97%
> rename from sysdeps/aarch64/__mtag_tag_region.S
> rename to sysdeps/aarch64/__mte_tag_region.S
> index 85e330812e..1698489fc2 100644
> --- a/sysdeps/aarch64/__mtag_tag_region.S
> +++ b/sysdeps/aarch64/__mte_tag_region.S
> @@ -37,7 +37,7 @@
> #define tmp x4
> #define zva_val x4
>
> -ENTRY (__libc_mtag_tag_region)
> +ENTRY (__mte_tag_region)
> add dstend, dstin, count
>
> cmp count, 96
> @@ -104,4 +104,4 @@ L(no_zva_loop):
> st2g dstin, [dstend, -32]
> ret
>
> -END (__libc_mtag_tag_region)
> +END (__mte_tag_region)
> diff --git a/sysdeps/aarch64/__mtag_tag_zero_region.S b/sysdeps/aarch64/__mte_tag_region_zero.S
> similarity index 97%
> rename from sysdeps/aarch64/__mtag_tag_zero_region.S
> rename to sysdeps/aarch64/__mte_tag_region_zero.S
> index 1a84b3e4d4..2f506c9ee8 100644
> --- a/sysdeps/aarch64/__mtag_tag_zero_region.S
> +++ b/sysdeps/aarch64/__mte_tag_region_zero.S
> @@ -37,7 +37,7 @@
> #define tmp x4
> #define zva_val x4
>
> -ENTRY (__libc_mtag_tag_zero_region)
> +ENTRY (__mte_tag_region_zero)
> add dstend, dstin, count
>
> cmp count, 96
> @@ -104,4 +104,4 @@ L(no_zva_loop):
> stz2g dstin, [dstend, -32]
> ret
>
> -END (__libc_mtag_tag_zero_region)
> +END (__mte_tag_region_zero)
> diff --git a/sysdeps/aarch64/libc-mtag.h b/sysdeps/aarch64/aarch64-mte.h
> similarity index 57%
> rename from sysdeps/aarch64/libc-mtag.h
> rename to sysdeps/aarch64/aarch64-mte.h
> index 663b866bf8..f42564f528 100644
> --- a/sysdeps/aarch64/libc-mtag.h
> +++ b/sysdeps/aarch64/aarch64-mte.h
> @@ -1,4 +1,4 @@
> -/* libc-internal interface for tagged (colored) memory support.
> +/* AArch64 MTE (Memory Tagging Extension) declarations.
> Copyright (C) 2020-2026 Free Software Foundation, Inc.
> This file is part of the GNU C Library.
>
> @@ -16,51 +16,49 @@
> License along with the GNU C Library; if not, see
> <http://www.gnu.org/licenses/>. */
>
> -#ifndef _AARCH64_LIBC_MTAG_H
> -#define _AARCH64_LIBC_MTAG_H 1
> +#ifndef _AARCH64_MTE_H
> +#define _AARCH64_MTE_H 1
>
> -#if 0
> +#include <stddef.h>
> +#include <stdint.h>
> +#include <sys/cdefs.h>
>
> -/* Used to ensure additional alignment when objects need to have distinct
> - tags. */
> -#define __MTAG_GRANULE_SIZE 16
> -
> -/* Non-zero if memory obtained via morecore (sbrk) is not tagged. */
> -#define __MTAG_SBRK_UNTAGGED 1
> -
> -/* Extra flags to pass to mmap to get tagged pages. */
> -#define __MTAG_MMAP_FLAGS PROT_MTE
> -
> -/* Set the tags for a region of memory, which must have size and alignment
> - that are multiples of __MTAG_GRANULE_SIZE. Size cannot be zero. */
> -void *__libc_mtag_tag_region (void *, size_t);
> -
> -/* Optimized equivalent to __libc_mtag_tag_region followed by memset to 0. */
> -void *__libc_mtag_tag_zero_region (void *, size_t);
> -
> -/* Convert address P to a pointer that is tagged correctly for that
> - location. */
> -static __always_inline void *
> -__libc_mtag_address_get_tag (void *p)
> +/* Assign a new (random) tag to a pointer P (does not adjust the
> + allocation tag on the memory addressed). */
> +static __always_inline __attribute_maybe_unused__ void *
> +__mte_new_tag (void *p)
> {
> register void *x0 asm ("x0") = p;
> - asm (".inst 0xd9600000 /* ldg x0, [x0] */" : "+r" (x0));
> + register uintptr_t x1 asm ("x1");
> + /* Guarantee that the new tag is not the same as now. */
> + asm (".inst 0x9adf1401 /* gmi x1, x0, xzr */\n"
> + ".inst 0x9ac11000 /* irg x0, x0, x1 */" : "+r" (x0), "=r" (x1));
> return x0;
> }
>
> -/* Assign a new (random) tag to a pointer P (does not adjust the tag on
> - the memory addressed). */
> -static __always_inline void *
> -__libc_mtag_new_tag (void *p)
> +/* Clears logical tag in the input pointer. */
> +static __always_inline __attribute_maybe_unused__ void *
> +__mte_clear_tag (void *p)
> +{
> + return (void *)((uintptr_t)p & ~(0xfull << 56ull));
> +}
> +
> +/* Convert address P to a pointer that is tagged correctly for that
> + location (logical tag in the returned pointer will be the same
> + as the allocation tag in the addressed memory). */
> +static __always_inline __attribute_maybe_unused__ void *
> +__mte_get_tag (void *p)
> {
> register void *x0 asm ("x0") = p;
> - register unsigned long x1 asm ("x1");
> - /* Guarantee that the new tag is not the same as now. */
> - asm (".inst 0x9adf1401 /* gmi x1, x0, xzr */\n"
> - ".inst 0x9ac11000 /* irg x0, x0, x1 */" : "+r" (x0), "=r" (x1));
> + asm (".inst 0xd9600000 /* ldg x0, [x0] */" : "+r" (x0));
> return x0;
> }
>
> -#endif /* USE_MTAG */
> +/* Set the tags for a region of memory, which must have size and alignment
> + that are multiples of MTE_GRANULE_SIZE. Size cannot be zero. */
> +void *__mte_tag_region (void *, size_t);
> +
> +/* Optimized equivalent to __mte_tag_region followed by memset to 0. */
> +void *__mte_tag_region_zero (void *, size_t);
>
> -#endif /* _AARCH64_LIBC_MTAG_H */
> +#endif /* _AARCH64_MTE_H */
It is not clear to me why keep these definitions since they are dead code now.
> diff --git a/sysdeps/generic/libc-mtag.h b/sysdeps/generic/libc-mtag.h
> deleted file mode 100644
> index 5477bfa17f..0000000000
> --- a/sysdeps/generic/libc-mtag.h
> +++ /dev/null
> @@ -1,73 +0,0 @@
> -/* libc-internal interface for tagged (colored) memory support.
> - Copyright (C) 2020-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
> - <http://www.gnu.org/licenses/>. */
> -
> -#ifndef _GENERIC_LIBC_MTAG_H
> -#define _GENERIC_LIBC_MTAG_H 1
> -
> -/* Generic bindings for systems that do not support memory tagging. */
> -
> -/* Used to ensure additional alignment when objects need to have distinct
> - tags. */
> -#define __MTAG_GRANULE_SIZE 1
> -
> -/* Non-zero if memory obtained via morecore (sbrk) is not tagged. */
> -#define __MTAG_SBRK_UNTAGGED 0
> -
> -/* Extra flags to pass to mmap() to request a tagged region of memory. */
> -#define __MTAG_MMAP_FLAGS 0
> -
> -/* Memory tagging target hooks are only called when memory tagging is
> - enabled at runtime. The generic definitions here must not be used. */
> -void __libc_mtag_link_error (void);
> -
> -/* Set the tags for a region of memory, which must have size and alignment
> - that are multiples of __MTAG_GRANULE_SIZE. Size cannot be zero. */
> -static inline void *
> -__libc_mtag_tag_region (void *p, size_t n)
> -{
> - __libc_mtag_link_error ();
> - return p;
> -}
> -
> -/* Optimized equivalent to __libc_mtag_tag_region followed by memset to 0. */
> -static inline void *
> -__libc_mtag_tag_zero_region (void *p, size_t n)
> -{
> - __libc_mtag_link_error ();
> - return memset (p, 0, n);
> -}
> -
> -/* Convert address P to a pointer that is tagged correctly for that
> - location. */
> -static inline void *
> -__libc_mtag_address_get_tag (void *p)
> -{
> - __libc_mtag_link_error ();
> - return p;
> -}
> -
> -/* Assign a new (random) tag to a pointer P (does not adjust the tag on
> - the memory addressed). */
> -static inline void *
> -__libc_mtag_new_tag (void *p)
> -{
> - __libc_mtag_link_error ();
> - return p;
> -}
> -
> -#endif /* _GENERIC_LIBC_MTAG_H */
More information about the Libc-alpha
mailing list