^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * S390 version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright IBM Corp. 1999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef _S390_STRING_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define _S390_STRING_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #ifndef _LINUX_TYPES_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define __HAVE_ARCH_MEMSET16 /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define __HAVE_ARCH_MEMSET32 /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define __HAVE_ARCH_MEMSET64 /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void *memcpy(void *dest, const void *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void *memset(void *s, int c, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) void *memmove(void *dest, const void *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifndef CONFIG_KASAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define __HAVE_ARCH_MEMCHR /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define __HAVE_ARCH_MEMCMP /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define __HAVE_ARCH_MEMSCAN /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define __HAVE_ARCH_STRCAT /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define __HAVE_ARCH_STRCMP /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define __HAVE_ARCH_STRCPY /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define __HAVE_ARCH_STRLCAT /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define __HAVE_ARCH_STRLCPY /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define __HAVE_ARCH_STRLEN /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define __HAVE_ARCH_STRNCAT /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define __HAVE_ARCH_STRNCPY /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define __HAVE_ARCH_STRNLEN /* inline & arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define __HAVE_ARCH_STRRCHR /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define __HAVE_ARCH_STRSTR /* arch function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Prototypes for non-inlined arch strings functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int memcmp(const void *s1, const void *s2, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int strcmp(const char *s1, const char *s2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) size_t strlcat(char *dest, const char *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) size_t strlcpy(char *dest, const char *src, size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) char *strncat(char *dest, const char *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char *strncpy(char *dest, const char *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) char *strrchr(const char *s, int c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) char *strstr(const char *s1, const char *s2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #endif /* !CONFIG_KASAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #undef __HAVE_ARCH_STRCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #undef __HAVE_ARCH_STRNCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #undef __HAVE_ARCH_STRNCMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #undef __HAVE_ARCH_STRPBRK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #undef __HAVE_ARCH_STRSEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #undef __HAVE_ARCH_STRSPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) extern void *__memcpy(void *dest, const void *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) extern void *__memset(void *s, int c, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) extern void *__memmove(void *dest, const void *src, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * For files that are not instrumented (e.g. mm/slub.c) we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * should use not instrumented version of mem* functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define memcpy(dst, src, len) __memcpy(dst, src, len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define memmove(dst, src, len) __memmove(dst, src, len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define memset(s, c, n) __memset(s, c, n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define strlen(s) __strlen(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define __no_sanitize_prefix_strfunc(x) __##x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #ifndef __NO_FORTIFY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define __no_sanitize_prefix_strfunc(x) x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void *__memset16(uint16_t *s, uint16_t v, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void *__memset32(uint32_t *s, uint32_t v, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void *__memset64(uint64_t *s, uint64_t v, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return __memset16(s, v, count * sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return __memset32(s, v, count * sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return __memset64(s, v, count * sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef __HAVE_ARCH_MEMCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static inline void *memchr(const void * s, int c, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) register int r0 asm("0") = (char) c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const void *ret = s + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "0: srst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) " jo 0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) " jl 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) " la %0,0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return (void *) ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #ifdef __HAVE_ARCH_MEMSCAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline void *memscan(void *s, int c, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) register int r0 asm("0") = (char) c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const void *ret = s + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "0: srst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) " jo 0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return (void *) ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #ifdef __HAVE_ARCH_STRCAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline char *strcat(char *dst, const char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) register int r0 asm("0") = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned long dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) char *ret = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "0: srst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) " jo 0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "1: mvst %0,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) " jo 1b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) : "=&a" (dummy), "+a" (dst), "+a" (src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) : "d" (r0), "0" (0) : "cc", "memory" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #ifdef __HAVE_ARCH_STRCPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline char *strcpy(char *dst, const char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) register int r0 asm("0") = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) char *ret = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "0: mvst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) " jo 0b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) : "+&a" (dst), "+&a" (src) : "d" (r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #if defined(__HAVE_ARCH_STRLEN) || (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static inline size_t __no_sanitize_prefix_strfunc(strlen)(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) register unsigned long r0 asm("0") = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) const char *tmp = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) "0: srst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) " jo 0b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) : "+d" (r0), "+a" (tmp) : : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return r0 - (unsigned long) s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #ifdef __HAVE_ARCH_STRNLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static inline size_t strnlen(const char * s, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) register int r0 asm("0") = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) const char *tmp = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) const char *end = s + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) "0: srst %0,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) " jo 0b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return end - s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #else /* IN_ARCH_STRING_C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) void *memchr(const void * s, int c, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void *memscan(void *s, int c, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) char *strcat(char *dst, const char *src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) char *strcpy(char *dst, const char *src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) size_t strlen(const char *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) size_t strnlen(const char * s, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #endif /* !IN_ARCH_STRING_C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #endif /* __S390_STRING_H_ */