1#include <arm_acle.h>
2#include <asm/hwcap.h>
3#include <linux/mman.h>
4#include <stdio.h>
5#include <sys/auxv.h>
6#include <sys/mman.h>
7#include <sys/prctl.h>
8#include <unistd.h>
9
10int print_result(char *ptr) {
11 // Page size allows the test to try reading off of the end of the page
12 printf(format: "buffer: %p page_size: 0x%x\n", ptr, sysconf(_SC_PAGESIZE));
13
14 // Exit after some time, so we don't leave a zombie process
15 // if the test framework lost track of us.
16 sleep(seconds: 60);
17 return 0;
18}
19
20int main(int argc, char const *argv[]) {
21 if (prctl(PR_SET_TAGGED_ADDR_CTRL,
22 PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
23 // Allow all tags to be generated by the addg
24 // instruction __arm_mte_increment_tag produces.
25 (0xffff << PR_MTE_TAG_SHIFT),
26 0, 0, 0)) {
27 return print_result(NULL);
28 }
29
30 size_t page_size = sysconf(_SC_PAGESIZE);
31 char *buf = mmap(addr: 0, len: page_size, PROT_READ | PROT_WRITE | PROT_MTE,
32 MAP_PRIVATE | MAP_ANONYMOUS, fd: -1, offset: 0);
33 if (buf == MAP_FAILED)
34 return print_result(NULL);
35
36 // Set incrementing tags until end of the page
37 char *tagged_ptr = buf;
38 // This intrinsic treats the addresses as if they were untagged
39 while (__arm_mte_ptrdiff(tagged_ptr, buf) < page_size) {
40 // This sets the allocation tag
41 __arm_mte_set_tag(tagged_ptr);
42 // Set the tag of the next granule (hence +16) to the next
43 // tag value. Returns a new pointer with the new logical tag.
44 // Tag values wrap at 0xF so it'll cycle.
45 tagged_ptr = __arm_mte_increment_tag(tagged_ptr + 16, 1);
46 }
47
48 // lldb-server should be removing the top byte from addresses passed
49 // to ptrace. So put some random bits in there.
50 // ptrace expects you to remove them but it can still succeed if you
51 // don't. So this isn't proof that we're removing them, it's just a
52 // smoke test in case something didn't account for them.
53 buf = (char *)((size_t)buf | ((size_t)0xAA << 56));
54 return print_result(ptr: buf);
55}
56

source code of lldb/test/API/tools/lldb-server/memory-tagging/main.c