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