Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  *  S390 version
0004  *    Copyright IBM Corp. 1999
0005  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
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  /* gcc builtin & arch function */
0016 #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
0017 #define __HAVE_ARCH_MEMSET  /* gcc builtin & arch function */
0018 #define __HAVE_ARCH_MEMSET16    /* arch function */
0019 #define __HAVE_ARCH_MEMSET32    /* arch function */
0020 #define __HAVE_ARCH_MEMSET64    /* arch function */
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  /* inline & arch function */
0028 #define __HAVE_ARCH_MEMCMP  /* arch function */
0029 #define __HAVE_ARCH_MEMSCAN /* inline & arch function */
0030 #define __HAVE_ARCH_STRCAT  /* inline & arch function */
0031 #define __HAVE_ARCH_STRCMP  /* arch function */
0032 #define __HAVE_ARCH_STRCPY  /* inline & arch function */
0033 #define __HAVE_ARCH_STRLCAT /* arch function */
0034 #define __HAVE_ARCH_STRLEN  /* inline & arch function */
0035 #define __HAVE_ARCH_STRNCAT /* arch function */
0036 #define __HAVE_ARCH_STRNCPY /* arch function */
0037 #define __HAVE_ARCH_STRNLEN /* inline & arch function */
0038 #define __HAVE_ARCH_STRSTR  /* arch function */
0039 
0040 /* Prototypes for non-inlined arch strings functions. */
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 /* !CONFIG_KASAN */
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  * For files that are not instrumented (e.g. mm/slub.c) we
0064  * should use not instrumented version of mem* functions.
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 /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
0076 #endif
0077 
0078 #else
0079 #define __no_sanitize_prefix_strfunc(x) x
0080 #endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */
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 /* IN_ARCH_STRING_C */
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 /* !IN_ARCH_STRING_C */
0214 
0215 #endif /* __S390_STRING_H_ */