1 /* This test program is part of GDB, the GNU debugger.
3 Copyright 2021-2024 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* Exercise AArch64's Memory Tagging Extension with tagged pointers. */
20 /* This test was based on the documentation for the AArch64 Memory Tagging
21 Extension from the Linux Kernel, found in the sources in
22 Documentation/arm64/memory-tagging-extension.rst. */
30 #include <sys/prctl.h>
32 /* From arch/arm64/include/uapi/asm/hwcap.h */
34 #define HWCAP2_MTE (1 << 18)
37 /* From arch/arm64/include/uapi/asm/mman.h */
42 #ifndef PR_SET_TAGGED_ADDR_CTRL
43 #define PR_SET_TAGGED_ADDR_CTRL 55
44 #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
47 /* From include/uapi/linux/prctl.h */
48 #ifndef PR_MTE_TCF_SHIFT
49 #define PR_MTE_TCF_SHIFT 1
50 #define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
51 #define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
52 #define PR_MTE_TAG_SHIFT 3
56 access_memory (unsigned char *tagged_ptr
, unsigned char *untagged_ptr
)
62 main (int argc
, char **argv
)
64 unsigned char *tagged_ptr
;
65 unsigned char *untagged_ptr
;
66 unsigned long page_sz
= sysconf (_SC_PAGESIZE
);
67 unsigned long hwcap2
= getauxval(AT_HWCAP2
);
69 /* Bail out if MTE is not supported. */
70 if (!(hwcap2
& HWCAP2_MTE
))
73 /* Enable the tagged address ABI, synchronous MTE tag check faults and
74 allow all non-zero tags in the randomly generated set. */
75 if (prctl (PR_SET_TAGGED_ADDR_CTRL
,
76 PR_TAGGED_ADDR_ENABLE
| PR_MTE_TCF_SYNC
77 | (0xfffe << PR_MTE_TAG_SHIFT
),
80 perror ("prctl () failed");
84 /* Create a mapping that will have PROT_MTE set. */
85 tagged_ptr
= mmap (0, page_sz
, PROT_READ
| PROT_WRITE
,
86 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
87 if (tagged_ptr
== MAP_FAILED
)
89 perror ("mmap () failed");
93 /* Create another mapping that won't have PROT_MTE set. */
94 untagged_ptr
= mmap (0, page_sz
, PROT_READ
| PROT_WRITE
,
95 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
96 if (untagged_ptr
== MAP_FAILED
)
98 perror ("mmap () failed");
102 /* Enable MTE on the above anonymous mmap. */
103 if (mprotect (tagged_ptr
, page_sz
, PROT_READ
| PROT_WRITE
| PROT_MTE
))
105 perror ("mprotect () failed");
109 access_memory (tagged_ptr
, untagged_ptr
);