1 /* 2 * __mtag_tag_region test. 3 * 4 * Copyright (c) 2021, Arm Limited. 5 * SPDX-License-Identifier: MIT 6 */ 7 8 #if __ARM_FEATURE_MEMORY_TAGGING && WANT_MTE_TEST 9 #include <stdint.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include "mte.h" 14 #include "stringlib.h" 15 #include "stringtest.h" 16 17 static void 18 mtag_quoteat (const char *prefix, void *p, int len, int at) 19 { 20 /* Print tag, untag and quote the context. */ 21 printf ("location: %p\n", __arm_mte_get_tag ((char *) p + at)); 22 untag_buffer (p, len, 1); 23 p = untag_pointer (p); 24 quoteat (prefix, p, len, at); 25 } 26 27 #define F(x) {#x, x}, 28 29 static const struct fun 30 { 31 const char *name; 32 void *(*fun) (void *s, size_t n); 33 } funtab[] = { 34 // clang-format off 35 #if __aarch64__ 36 F(__mtag_tag_region) 37 #endif 38 {0, 0} 39 // clang-format on 40 }; 41 #undef F 42 43 #define A 64 44 #define LEN 250000 45 static unsigned char *sbuf; 46 47 static void * 48 alignup (void *p) 49 { 50 return (void *) (((uintptr_t) p + A - 1) & -A); 51 } 52 53 static void 54 test (const struct fun *fun, int salign, int len) 55 { 56 unsigned char *src = alignup (sbuf); 57 unsigned char *s = src + salign; 58 void *p; 59 int i; 60 61 if (err_count >= ERR_LIMIT) 62 return; 63 if (len > LEN || salign >= A) 64 abort (); 65 for (i = 0; i < len + 2 * A; i++) 66 src[i] = '?'; 67 for (i = 0; i < len; i++) 68 s[i] = 'a'; 69 70 src = tag_buffer (src, len + 2 * A, 1); 71 s = src + salign; 72 /* Use different tag. */ 73 s = __arm_mte_increment_tag (s, 1); 74 p = fun->fun (s, len); 75 76 if (p != s) 77 ERR ("%s(%p,..) returned %p\n", fun->name, s, p); 78 79 for (i = 0; i < salign; i++) 80 { 81 if (src[i] != '?') 82 { 83 ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 84 mtag_quoteat ("got head", src, len + 2 * A, i); 85 return; 86 } 87 } 88 89 for (; i < salign + len; i++) 90 { 91 if (s[i - salign] != 'a') 92 { 93 ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 94 mtag_quoteat ("got body", src, len + 2 * A, i); 95 return; 96 } 97 } 98 99 for (; i < len + 2 * A; i++) 100 { 101 if (src[i] != '?') 102 { 103 ERR ("%s(align %d, %d) failed\n", fun->name, salign, len); 104 mtag_quoteat ("got tail", src, len + 2 * A, i); 105 return; 106 } 107 } 108 109 untag_buffer (src, len + 2 * A, 1); 110 } 111 112 int 113 main () 114 { 115 if (!mte_enabled ()) 116 return 0; 117 118 sbuf = mte_mmap (LEN + 3 * A); 119 int r = 0; 120 for (int i = 0; funtab[i].name; i++) 121 { 122 err_count = 0; 123 for (int s = 0; s < A; s += 16) 124 { 125 int n; 126 for (n = 0; n < 200; n += 16) 127 { 128 test (funtab + i, s, n); 129 } 130 for (; n < LEN; n *= 2) 131 { 132 test (funtab + i, s, n); 133 } 134 } 135 printf ("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); 136 if (err_count) 137 r = -1; 138 } 139 return r; 140 } 141 #else 142 int 143 main () 144 { 145 return 0; 146 } 147 #endif 148