[PATCH v2 3/3] malloc: Remove currently broken memory tagging
Yury Khrustalev
yury.khrustalev@arm.com
Wed May 20 13:27:55 GMT 2026
Remove AArch64-specific code, that is currently broken, from the
core malloc implementation.
Code clean-up, no functional change unrelated to memory tagging.
---
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 */
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 */
--
2.47.3
More information about the Libc-alpha
mailing list