1/* 2 * strnlen test. 3 * 4 * Copyright (c) 2019-2020, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 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 23static 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 44static char *sbuf; 45 46static void * 47alignup (void *p) 48{ 49 return (void *) (((uintptr_t) p + ALIGN - 1) & -ALIGN); 50} 51 52static void 53test (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 88int 89main (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