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