1139825Simp/* 286230Stmm * __mtag_tag_region test. 386230Stmm * 486230Stmm * Copyright (c) 2021, Arm Limited. 586230Stmm * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 686230Stmm */ 786230Stmm 886230Stmm#if __ARM_FEATURE_MEMORY_TAGGING && WANT_MTE_TEST 986230Stmm#include <stdint.h> 1086230Stmm#include <stdio.h> 1186230Stmm#include <stdlib.h> 1286230Stmm#include <string.h> 1386230Stmm#include "mte.h" 1486230Stmm#include "stringlib.h" 1586230Stmm#include "stringtest.h" 1686230Stmm 1786230Stmmstatic void 1886230Stmmmtag_quoteat (const char *prefix, void *p, int len, int at) 1986230Stmm{ 2086230Stmm /* Print tag, untag and quote the context. */ 2186230Stmm printf ("location: %p\n", __arm_mte_get_tag ((char *) p + at)); 2286230Stmm untag_buffer (p, len, 1); 2386230Stmm p = untag_pointer (p); 2486230Stmm quoteat (prefix, p, len, at); 2586230Stmm} 2686230Stmm 2786230Stmm#define F(x) {#x, x}, 2886230Stmm 2986230Stmmstatic const struct fun 3086230Stmm{ 3186230Stmm const char *name; 3286230Stmm void *(*fun) (void *s, size_t n); 3386230Stmm} funtab[] = { 3486230Stmm// clang-format off 3586230Stmm#if __aarch64__ 3686230Stmm F(__mtag_tag_region) 3786230Stmm#endif 3886230Stmm {0, 0} 3986230Stmm // clang-format on 40200922Smarius}; 4186230Stmm#undef F 4286230Stmm 43167308Smarius#define A 64 4486230Stmm#define LEN 250000 4586230Stmmstatic unsigned char *sbuf; 4686230Stmm 47200923Smariusstatic void * 4890705Stmmalignup (void *p) 4990705Stmm{ 5090705Stmm return (void *) (((uintptr_t) p + A - 1) & -A); 51200923Smarius} 52200923Smarius 53200923Smariusstatic void 5486230Stmmtest (const struct fun *fun, int salign, int len) 5586230Stmm{ 5690705Stmm unsigned char *src = alignup (sbuf); 5790705Stmm unsigned char *s = src + salign; 5890705Stmm void *p; 5986230Stmm int i; 60185008Smarius 6190705Stmm if (err_count >= ERR_LIMIT) 6290705Stmm return; 6390705Stmm if (len > LEN || salign >= A) 6490705Stmm abort (); 6590705Stmm for (i = 0; i < len + 2 * A; i++) 6686230Stmm src[i] = '?'; 67200922Smarius for (i = 0; i < len; i++) 68200922Smarius s[i] = 'a'; 69200922Smarius 7086230Stmm src = tag_buffer (src, len + 2 * A, 1); 71171730Smarius s = src + salign; 7286230Stmm /* Use different tag. */ 7386230Stmm s = __arm_mte_increment_tag (s, 1); 7486230Stmm p = fun->fun (s, len); 7586230Stmm 76200923Smarius if (p != s) 77200923Smarius ERR ("%s(%p,..) returned %p\n", fun->name, s, p); 7890705Stmm 79200923Smarius for (i = 0; i < salign; i++) 80200923Smarius { 81200923Smarius if (src[i] != '?') 82200923Smarius { 83200923Smarius ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 84200923Smarius mtag_quoteat ("got head", src, len + 2 * A, i); 85200923Smarius return; 86200923Smarius } 87200922Smarius } 88200922Smarius 89200923Smarius for (; i < salign + len; i++) 90200923Smarius { 91200923Smarius if (s[i - salign] != 'a') 92200922Smarius { 93200923Smarius ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 94200922Smarius mtag_quoteat ("got body", src, len + 2 * A, i); 9586230Stmm return; 9686230Stmm } 97200923Smarius } 98200923Smarius 99200923Smarius for (; i < len + 2 * A; i++) 100200923Smarius { 101200923Smarius if (src[i] != '?') 102200923Smarius { 103200923Smarius ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 104200923Smarius mtag_quoteat ("got tail", src, len + 2 * A, i); 105200923Smarius return; 106200923Smarius } 107200923Smarius } 108200923Smarius 109200923Smarius untag_buffer (src, len + 2 * A, 1); 110200923Smarius} 111200923Smarius 112200923Smariusint 113200923Smariusmain () 114200923Smarius{ 115200923Smarius if (!mte_enabled ()) 116200923Smarius return 0; 117200923Smarius 118200923Smarius sbuf = mte_mmap (LEN + 3 * A); 119200923Smarius int r = 0; 120200923Smarius for (int i = 0; funtab[i].name; i++) 121200923Smarius { 122200923Smarius err_count = 0; 123200923Smarius for (int s = 0; s < A; s += 16) 124200923Smarius { 125200923Smarius int n; 126200923Smarius for (n = 0; n < 200; n += 16) 127185008Smarius { 128108802Stmm test (funtab + i, s, n); 129108802Stmm } 130108802Stmm for (; n < LEN; n *= 2) 131108802Stmm { 132200922Smarius test (funtab + i, s, n); 133108802Stmm } 134200922Smarius } 135108802Stmm printf ("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); 136108802Stmm if (err_count) 137108802Stmm r = -1; 138108802Stmm } 139108802Stmm return r; 140108802Stmm} 141108802Stmm#else 142108802Stmmint 143108802Stmmmain () 14486230Stmm{ 14586230Stmm return 0; 14686230Stmm} 14786230Stmm#endif 148200923Smarius