0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _S390_STRING_H_
0009 #define _S390_STRING_H_
0010
0011 #ifndef _LINUX_TYPES_H
0012 #include <linux/types.h>
0013 #endif
0014
0015 #define __HAVE_ARCH_MEMCPY
0016 #define __HAVE_ARCH_MEMMOVE
0017 #define __HAVE_ARCH_MEMSET
0018 #define __HAVE_ARCH_MEMSET16
0019 #define __HAVE_ARCH_MEMSET32
0020 #define __HAVE_ARCH_MEMSET64
0021
0022 void *memcpy(void *dest, const void *src, size_t n);
0023 void *memset(void *s, int c, size_t n);
0024 void *memmove(void *dest, const void *src, size_t n);
0025
0026 #ifndef CONFIG_KASAN
0027 #define __HAVE_ARCH_MEMCHR
0028 #define __HAVE_ARCH_MEMCMP
0029 #define __HAVE_ARCH_MEMSCAN
0030 #define __HAVE_ARCH_STRCAT
0031 #define __HAVE_ARCH_STRCMP
0032 #define __HAVE_ARCH_STRCPY
0033 #define __HAVE_ARCH_STRLCAT
0034 #define __HAVE_ARCH_STRLEN
0035 #define __HAVE_ARCH_STRNCAT
0036 #define __HAVE_ARCH_STRNCPY
0037 #define __HAVE_ARCH_STRNLEN
0038 #define __HAVE_ARCH_STRSTR
0039
0040
0041 int memcmp(const void *s1, const void *s2, size_t n);
0042 int strcmp(const char *s1, const char *s2);
0043 size_t strlcat(char *dest, const char *src, size_t n);
0044 char *strncat(char *dest, const char *src, size_t n);
0045 char *strncpy(char *dest, const char *src, size_t n);
0046 char *strstr(const char *s1, const char *s2);
0047 #endif
0048
0049 #undef __HAVE_ARCH_STRCHR
0050 #undef __HAVE_ARCH_STRNCHR
0051 #undef __HAVE_ARCH_STRNCMP
0052 #undef __HAVE_ARCH_STRPBRK
0053 #undef __HAVE_ARCH_STRSEP
0054 #undef __HAVE_ARCH_STRSPN
0055
0056 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
0057
0058 extern void *__memcpy(void *dest, const void *src, size_t n);
0059 extern void *__memset(void *s, int c, size_t n);
0060 extern void *__memmove(void *dest, const void *src, size_t n);
0061
0062
0063
0064
0065
0066
0067 #define memcpy(dst, src, len) __memcpy(dst, src, len)
0068 #define memmove(dst, src, len) __memmove(dst, src, len)
0069 #define memset(s, c, n) __memset(s, c, n)
0070 #define strlen(s) __strlen(s)
0071
0072 #define __no_sanitize_prefix_strfunc(x) __##x
0073
0074 #ifndef __NO_FORTIFY
0075 #define __NO_FORTIFY
0076 #endif
0077
0078 #else
0079 #define __no_sanitize_prefix_strfunc(x) x
0080 #endif
0081
0082 void *__memset16(uint16_t *s, uint16_t v, size_t count);
0083 void *__memset32(uint32_t *s, uint32_t v, size_t count);
0084 void *__memset64(uint64_t *s, uint64_t v, size_t count);
0085
0086 static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
0087 {
0088 return __memset16(s, v, count * sizeof(v));
0089 }
0090
0091 static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
0092 {
0093 return __memset32(s, v, count * sizeof(v));
0094 }
0095
0096 static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
0097 {
0098 return __memset64(s, v, count * sizeof(v));
0099 }
0100
0101 #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
0102
0103 #ifdef __HAVE_ARCH_MEMCHR
0104 static inline void *memchr(const void * s, int c, size_t n)
0105 {
0106 const void *ret = s + n;
0107
0108 asm volatile(
0109 " lgr 0,%[c]\n"
0110 "0: srst %[ret],%[s]\n"
0111 " jo 0b\n"
0112 " jl 1f\n"
0113 " la %[ret],0\n"
0114 "1:"
0115 : [ret] "+&a" (ret), [s] "+&a" (s)
0116 : [c] "d" (c)
0117 : "cc", "memory", "0");
0118 return (void *) ret;
0119 }
0120 #endif
0121
0122 #ifdef __HAVE_ARCH_MEMSCAN
0123 static inline void *memscan(void *s, int c, size_t n)
0124 {
0125 const void *ret = s + n;
0126
0127 asm volatile(
0128 " lgr 0,%[c]\n"
0129 "0: srst %[ret],%[s]\n"
0130 " jo 0b\n"
0131 : [ret] "+&a" (ret), [s] "+&a" (s)
0132 : [c] "d" (c)
0133 : "cc", "memory", "0");
0134 return (void *) ret;
0135 }
0136 #endif
0137
0138 #ifdef __HAVE_ARCH_STRCAT
0139 static inline char *strcat(char *dst, const char *src)
0140 {
0141 unsigned long dummy = 0;
0142 char *ret = dst;
0143
0144 asm volatile(
0145 " lghi 0,0\n"
0146 "0: srst %[dummy],%[dst]\n"
0147 " jo 0b\n"
0148 "1: mvst %[dummy],%[src]\n"
0149 " jo 1b"
0150 : [dummy] "+&a" (dummy), [dst] "+&a" (dst), [src] "+&a" (src)
0151 :
0152 : "cc", "memory", "0");
0153 return ret;
0154 }
0155 #endif
0156
0157 #ifdef __HAVE_ARCH_STRCPY
0158 static inline char *strcpy(char *dst, const char *src)
0159 {
0160 char *ret = dst;
0161
0162 asm volatile(
0163 " lghi 0,0\n"
0164 "0: mvst %[dst],%[src]\n"
0165 " jo 0b"
0166 : [dst] "+&a" (dst), [src] "+&a" (src)
0167 :
0168 : "cc", "memory", "0");
0169 return ret;
0170 }
0171 #endif
0172
0173 #if defined(__HAVE_ARCH_STRLEN) || (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__))
0174 static inline size_t __no_sanitize_prefix_strfunc(strlen)(const char *s)
0175 {
0176 unsigned long end = 0;
0177 const char *tmp = s;
0178
0179 asm volatile(
0180 " lghi 0,0\n"
0181 "0: srst %[end],%[tmp]\n"
0182 " jo 0b"
0183 : [end] "+&a" (end), [tmp] "+&a" (tmp)
0184 :
0185 : "cc", "memory", "0");
0186 return end - (unsigned long)s;
0187 }
0188 #endif
0189
0190 #ifdef __HAVE_ARCH_STRNLEN
0191 static inline size_t strnlen(const char * s, size_t n)
0192 {
0193 const char *tmp = s;
0194 const char *end = s + n;
0195
0196 asm volatile(
0197 " lghi 0,0\n"
0198 "0: srst %[end],%[tmp]\n"
0199 " jo 0b"
0200 : [end] "+&a" (end), [tmp] "+&a" (tmp)
0201 :
0202 : "cc", "memory", "0");
0203 return end - s;
0204 }
0205 #endif
0206 #else
0207 void *memchr(const void * s, int c, size_t n);
0208 void *memscan(void *s, int c, size_t n);
0209 char *strcat(char *dst, const char *src);
0210 char *strcpy(char *dst, const char *src);
0211 size_t strlen(const char *s);
0212 size_t strnlen(const char * s, size_t n);
0213 #endif
0214
0215 #endif