1*31914882SAlex Richardson /* 2*31914882SAlex Richardson * strchrnul 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 char *(*fun) (const char *s, int c); 27*31914882SAlex Richardson int test_mte; 28*31914882SAlex Richardson } funtab[] = { 29*31914882SAlex Richardson // clang-format off 30*31914882SAlex Richardson F(strchrnul, 0) 31*31914882SAlex Richardson #if __aarch64__ 32*31914882SAlex Richardson F(__strchrnul_aarch64, 0) 33*31914882SAlex Richardson F(__strchrnul_aarch64_mte, 1) 34*31914882SAlex Richardson # if __ARM_FEATURE_SVE 35*31914882SAlex Richardson F(__strchrnul_aarch64_sve, 1) 36*31914882SAlex Richardson # endif 37*31914882SAlex Richardson #endif 38*31914882SAlex Richardson {0, 0, 0} 39*31914882SAlex Richardson // clang-format on 40*31914882SAlex Richardson }; 41*31914882SAlex Richardson #undef F 42*31914882SAlex Richardson 43*31914882SAlex Richardson #define ALIGN 32 44*31914882SAlex Richardson #define LEN 512 45*31914882SAlex Richardson static char *sbuf; 46*31914882SAlex Richardson 47*31914882SAlex Richardson static void * 48*31914882SAlex Richardson alignup (void *p) 49*31914882SAlex Richardson { 50*31914882SAlex Richardson return (void *) (((uintptr_t) p + ALIGN - 1) & -ALIGN); 51*31914882SAlex Richardson } 52*31914882SAlex Richardson 53*31914882SAlex Richardson static void 54*31914882SAlex Richardson test (const struct fun *fun, int align, int seekpos, int len) 55*31914882SAlex Richardson { 56*31914882SAlex Richardson char *src = alignup (sbuf); 57*31914882SAlex Richardson char *s = src + align; 58*31914882SAlex Richardson char *f = seekpos != -1 ? s + seekpos : s + len; 59*31914882SAlex Richardson int seekchar = 0x1; 60*31914882SAlex Richardson void *p; 61*31914882SAlex Richardson 62*31914882SAlex Richardson if (err_count >= ERR_LIMIT) 63*31914882SAlex Richardson return; 64*31914882SAlex Richardson if (len > LEN || seekpos >= len || align >= ALIGN) 65*31914882SAlex Richardson abort (); 66*31914882SAlex Richardson 67*31914882SAlex Richardson for (int i = 0; src + i < s; i++) 68*31914882SAlex Richardson src[i] = (i + len) & 1 ? seekchar : 0; 69*31914882SAlex Richardson for (int i = 1; i <= ALIGN; i++) 70*31914882SAlex Richardson s[len + i] = (i + len) & 1 ? seekchar : 0; 71*31914882SAlex Richardson for (int i = 0; i < len; i++) 72*31914882SAlex Richardson s[i] = 'a' + (i & 31); 73*31914882SAlex Richardson if (seekpos != -1) 74*31914882SAlex Richardson s[seekpos] = seekchar; 75*31914882SAlex Richardson if (seekpos != -1 && (len + align) & 1) 76*31914882SAlex Richardson s[seekpos + 1] = seekchar; 77*31914882SAlex Richardson s[len] = '\0'; 78*31914882SAlex Richardson 79*31914882SAlex Richardson int mte_len = seekpos != -1 ? seekpos + 1 : len + 1; 80*31914882SAlex Richardson s = tag_buffer (s, mte_len, fun->test_mte); 81*31914882SAlex Richardson p = fun->fun (s, seekchar); 82*31914882SAlex Richardson untag_buffer (s, mte_len, fun->test_mte); 83*31914882SAlex Richardson p = untag_pointer (p); 84*31914882SAlex Richardson 85*31914882SAlex Richardson if (p != f) 86*31914882SAlex Richardson { 87*31914882SAlex Richardson ERR ("%s (%p, 0x%02x) len %d returned %p, expected %p pos %d\n", 88*31914882SAlex Richardson fun->name, s, seekchar, len, p, f, seekpos); 89*31914882SAlex Richardson quote ("input", s, len); 90*31914882SAlex Richardson } 91*31914882SAlex Richardson 92*31914882SAlex Richardson s = tag_buffer (s, len + 1, fun->test_mte); 93*31914882SAlex Richardson p = fun->fun (s, 0); 94*31914882SAlex Richardson untag_buffer (s, len + 1, fun->test_mte); 95*31914882SAlex Richardson 96*31914882SAlex Richardson if (p != s + len) 97*31914882SAlex Richardson { 98*31914882SAlex Richardson ERR ("%s (%p, 0x%02x) len %d returned %p, expected %p pos %d\n", 99*31914882SAlex Richardson fun->name, s, 0, len, p, f, len); 100*31914882SAlex Richardson quote ("input", s, len); 101*31914882SAlex Richardson } 102*31914882SAlex Richardson } 103*31914882SAlex Richardson 104*31914882SAlex Richardson int 105*31914882SAlex Richardson main (void) 106*31914882SAlex Richardson { 107*31914882SAlex Richardson sbuf = mte_mmap (LEN + 3 * ALIGN); 108*31914882SAlex Richardson int r = 0; 109*31914882SAlex Richardson for (int i = 0; funtab[i].name; i++) 110*31914882SAlex Richardson { 111*31914882SAlex Richardson err_count = 0; 112*31914882SAlex Richardson for (int a = 0; a < ALIGN; a++) 113*31914882SAlex Richardson for (int n = 0; n < LEN; n++) 114*31914882SAlex Richardson { 115*31914882SAlex Richardson for (int sp = 0; sp < n; sp++) 116*31914882SAlex Richardson test (funtab + i, a, sp, n); 117*31914882SAlex Richardson test (funtab + i, a, -1, n); 118*31914882SAlex Richardson } 119*31914882SAlex Richardson 120*31914882SAlex Richardson char *pass = funtab[i].test_mte && mte_enabled () ? "MTE PASS" : "PASS"; 121*31914882SAlex Richardson printf ("%s %s\n", err_count ? "FAIL" : pass, funtab[i].name); 122*31914882SAlex Richardson if (err_count) 123*31914882SAlex Richardson r = -1; 124*31914882SAlex Richardson } 125*31914882SAlex Richardson return r; 126*31914882SAlex Richardson } 127