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