1 /* 2 * memchr test. 3 * 4 * Copyright (c) 2019-2020, Arm Limited. 5 * SPDX-License-Identifier: MIT 6 */ 7 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <limits.h> 13 #include "mte.h" 14 #include "stringlib.h" 15 #include "stringtest.h" 16 17 #define F(x, mte) {#x, x, mte}, 18 19 static const struct fun 20 { 21 const char *name; 22 void *(*fun) (const void *s, int c, size_t n); 23 int test_mte; 24 } funtab[] = { 25 // clang-format off 26 F(memchr, 0) 27 #if __aarch64__ 28 F(__memchr_aarch64, 0) 29 F(__memchr_aarch64_mte, 1) 30 # if __ARM_FEATURE_SVE 31 F(__memchr_aarch64_sve, 1) 32 # endif 33 #elif __arm__ 34 F(__memchr_arm, 0) 35 #endif 36 {0, 0, 0} 37 // clang-format on 38 }; 39 #undef F 40 41 #define ALIGN 32 42 #define LEN 512 43 static char *sbuf; 44 45 static void * 46 alignup (void *p) 47 { 48 return (void *) (((uintptr_t) p + ALIGN - 1) & -ALIGN); 49 } 50 51 static void 52 test (const struct fun *fun, int align, size_t seekpos, size_t len, 53 size_t maxlen) 54 { 55 char *src = alignup (sbuf); 56 char *s = src + align; 57 char *f = seekpos < maxlen ? s + seekpos : NULL; 58 int seekchar = 1; 59 void *p; 60 61 if (err_count >= ERR_LIMIT) 62 return; 63 if (len > LEN || seekpos > LEN || align > ALIGN) 64 abort (); 65 66 for (int i = 0; src + i < s; i++) 67 src[i] = seekchar; 68 for (int i = 0; i <= ALIGN; i++) 69 s[len + i] = seekchar; 70 for (int i = 0; i < len; i++) 71 s[i] = 'a' + (i & 31); 72 s[seekpos] = seekchar; 73 s[((len ^ align) & 1) ? seekpos + 1 : len] = seekchar; 74 75 int mte_len = seekpos != -1 ? seekpos + 1 : maxlen; 76 s = tag_buffer (s, mte_len, fun->test_mte); 77 p = fun->fun (s, seekchar, maxlen); 78 untag_buffer (s, mte_len, fun->test_mte); 79 p = untag_pointer (p); 80 81 if (p != f) 82 { 83 ERR ("%s (%p, 0x%02x, %zu) returned %p, expected %p\n", fun->name, s, 84 seekchar, maxlen, p, f); 85 quote ("input", s, len); 86 } 87 } 88 89 int 90 main (void) 91 { 92 sbuf = mte_mmap (LEN + 3 * ALIGN); 93 int r = 0; 94 for (int i = 0; funtab[i].name; i++) 95 { 96 err_count = 0; 97 for (int a = 0; a < ALIGN; a++) 98 for (int n = 0; n < LEN; n++) 99 { 100 for (int sp = 0; sp < LEN; sp++) 101 test (funtab + i, a, sp, n, n); 102 test (funtab + i, a, n, n, SIZE_MAX - a); 103 } 104 char *pass = funtab[i].test_mte && mte_enabled () ? "MTE PASS" : "PASS"; 105 printf ("%s %s\n", err_count ? "FAIL" : pass, funtab[i].name); 106 if (err_count) 107 r = -1; 108 } 109 return r; 110 } 111