projects/linux·blob master · refs

194 lines · 4.9 KiB

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