diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-12-13 09:53:48 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-01-18 03:34:18 -0500 |
commit | 7e0d92f002460d30bea01fa7157be2f13af370a5 (patch) | |
tree | ef62cb72c7d7683f8e0bc4390d13195afc060afc | |
parent | 32b77252f47ec00c3c9dc4705f0197dd0f5f87d9 (diff) |
s390/kasan: improve string/memory functions checks
Avoid using arch specific implementations of string/memory functions
with KASAN since gcc cannot instrument asm code memory accesses and
many bugs could be missed.
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/boot/string.c | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/string.h | 28 | ||||
-rw-r--r-- | arch/s390/lib/string.c | 28 |
3 files changed, 51 insertions, 6 deletions
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c index 25aca07898ba..b11e8108773a 100644 --- a/arch/s390/boot/string.c +++ b/arch/s390/boot/string.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/ctype.h> | 2 | #include <linux/ctype.h> |
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/errno.h> | 4 | #include <linux/errno.h> |
5 | #undef CONFIG_KASAN | ||
5 | #include "../lib/string.c" | 6 | #include "../lib/string.c" |
6 | 7 | ||
7 | int strncmp(const char *cs, const char *ct, size_t count) | 8 | int strncmp(const char *cs, const char *ct, size_t count) |
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index 116cc15a4b8a..70d87db54e62 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h | |||
@@ -12,15 +12,21 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | #define __HAVE_ARCH_MEMCHR /* inline & arch function */ | ||
16 | #define __HAVE_ARCH_MEMCMP /* arch function */ | ||
17 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ | 15 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ |
18 | #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ | 16 | #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ |
19 | #define __HAVE_ARCH_MEMSCAN /* inline & arch function */ | ||
20 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ | 17 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ |
21 | #define __HAVE_ARCH_MEMSET16 /* arch function */ | 18 | #define __HAVE_ARCH_MEMSET16 /* arch function */ |
22 | #define __HAVE_ARCH_MEMSET32 /* arch function */ | 19 | #define __HAVE_ARCH_MEMSET32 /* arch function */ |
23 | #define __HAVE_ARCH_MEMSET64 /* arch function */ | 20 | #define __HAVE_ARCH_MEMSET64 /* arch function */ |
21 | |||
22 | void *memcpy(void *dest, const void *src, size_t n); | ||
23 | void *memset(void *s, int c, size_t n); | ||
24 | void *memmove(void *dest, const void *src, size_t n); | ||
25 | |||
26 | #ifndef CONFIG_KASAN | ||
27 | #define __HAVE_ARCH_MEMCHR /* inline & arch function */ | ||
28 | #define __HAVE_ARCH_MEMCMP /* arch function */ | ||
29 | #define __HAVE_ARCH_MEMSCAN /* inline & arch function */ | ||
24 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ | 30 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ |
25 | #define __HAVE_ARCH_STRCMP /* arch function */ | 31 | #define __HAVE_ARCH_STRCMP /* arch function */ |
26 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ | 32 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ |
@@ -35,9 +41,6 @@ | |||
35 | 41 | ||
36 | /* Prototypes for non-inlined arch strings functions. */ | 42 | /* Prototypes for non-inlined arch strings functions. */ |
37 | int memcmp(const void *s1, const void *s2, size_t n); | 43 | int memcmp(const void *s1, const void *s2, size_t n); |
38 | void *memcpy(void *dest, const void *src, size_t n); | ||
39 | void *memset(void *s, int c, size_t n); | ||
40 | void *memmove(void *dest, const void *src, size_t n); | ||
41 | int strcmp(const char *s1, const char *s2); | 44 | int strcmp(const char *s1, const char *s2); |
42 | size_t strlcat(char *dest, const char *src, size_t n); | 45 | size_t strlcat(char *dest, const char *src, size_t n); |
43 | size_t strlcpy(char *dest, const char *src, size_t size); | 46 | size_t strlcpy(char *dest, const char *src, size_t size); |
@@ -45,6 +48,7 @@ char *strncat(char *dest, const char *src, size_t n); | |||
45 | char *strncpy(char *dest, const char *src, size_t n); | 48 | char *strncpy(char *dest, const char *src, size_t n); |
46 | char *strrchr(const char *s, int c); | 49 | char *strrchr(const char *s, int c); |
47 | char *strstr(const char *s1, const char *s2); | 50 | char *strstr(const char *s1, const char *s2); |
51 | #endif /* !CONFIG_KASAN */ | ||
48 | 52 | ||
49 | #undef __HAVE_ARCH_STRCHR | 53 | #undef __HAVE_ARCH_STRCHR |
50 | #undef __HAVE_ARCH_STRNCHR | 54 | #undef __HAVE_ARCH_STRNCHR |
@@ -95,6 +99,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t count) | |||
95 | 99 | ||
96 | #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) | 100 | #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) |
97 | 101 | ||
102 | #ifdef __HAVE_ARCH_MEMCHR | ||
98 | static inline void *memchr(const void * s, int c, size_t n) | 103 | static inline void *memchr(const void * s, int c, size_t n) |
99 | { | 104 | { |
100 | register int r0 asm("0") = (char) c; | 105 | register int r0 asm("0") = (char) c; |
@@ -109,7 +114,9 @@ static inline void *memchr(const void * s, int c, size_t n) | |||
109 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); | 114 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
110 | return (void *) ret; | 115 | return (void *) ret; |
111 | } | 116 | } |
117 | #endif | ||
112 | 118 | ||
119 | #ifdef __HAVE_ARCH_MEMSCAN | ||
113 | static inline void *memscan(void *s, int c, size_t n) | 120 | static inline void *memscan(void *s, int c, size_t n) |
114 | { | 121 | { |
115 | register int r0 asm("0") = (char) c; | 122 | register int r0 asm("0") = (char) c; |
@@ -121,7 +128,9 @@ static inline void *memscan(void *s, int c, size_t n) | |||
121 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); | 128 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
122 | return (void *) ret; | 129 | return (void *) ret; |
123 | } | 130 | } |
131 | #endif | ||
124 | 132 | ||
133 | #ifdef __HAVE_ARCH_STRCAT | ||
125 | static inline char *strcat(char *dst, const char *src) | 134 | static inline char *strcat(char *dst, const char *src) |
126 | { | 135 | { |
127 | register int r0 asm("0") = 0; | 136 | register int r0 asm("0") = 0; |
@@ -137,7 +146,9 @@ static inline char *strcat(char *dst, const char *src) | |||
137 | : "d" (r0), "0" (0) : "cc", "memory" ); | 146 | : "d" (r0), "0" (0) : "cc", "memory" ); |
138 | return ret; | 147 | return ret; |
139 | } | 148 | } |
149 | #endif | ||
140 | 150 | ||
151 | #ifdef __HAVE_ARCH_STRCPY | ||
141 | static inline char *strcpy(char *dst, const char *src) | 152 | static inline char *strcpy(char *dst, const char *src) |
142 | { | 153 | { |
143 | register int r0 asm("0") = 0; | 154 | register int r0 asm("0") = 0; |
@@ -150,7 +161,9 @@ static inline char *strcpy(char *dst, const char *src) | |||
150 | : "cc", "memory"); | 161 | : "cc", "memory"); |
151 | return ret; | 162 | return ret; |
152 | } | 163 | } |
164 | #endif | ||
153 | 165 | ||
166 | #ifdef __HAVE_ARCH_STRLEN | ||
154 | static inline size_t strlen(const char *s) | 167 | static inline size_t strlen(const char *s) |
155 | { | 168 | { |
156 | register unsigned long r0 asm("0") = 0; | 169 | register unsigned long r0 asm("0") = 0; |
@@ -162,7 +175,9 @@ static inline size_t strlen(const char *s) | |||
162 | : "+d" (r0), "+a" (tmp) : : "cc", "memory"); | 175 | : "+d" (r0), "+a" (tmp) : : "cc", "memory"); |
163 | return r0 - (unsigned long) s; | 176 | return r0 - (unsigned long) s; |
164 | } | 177 | } |
178 | #endif | ||
165 | 179 | ||
180 | #ifdef __HAVE_ARCH_STRNLEN | ||
166 | static inline size_t strnlen(const char * s, size_t n) | 181 | static inline size_t strnlen(const char * s, size_t n) |
167 | { | 182 | { |
168 | register int r0 asm("0") = 0; | 183 | register int r0 asm("0") = 0; |
@@ -175,6 +190,7 @@ static inline size_t strnlen(const char * s, size_t n) | |||
175 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); | 190 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); |
176 | return end - s; | 191 | return end - s; |
177 | } | 192 | } |
193 | #endif | ||
178 | #else /* IN_ARCH_STRING_C */ | 194 | #else /* IN_ARCH_STRING_C */ |
179 | void *memchr(const void * s, int c, size_t n); | 195 | void *memchr(const void * s, int c, size_t n); |
180 | void *memscan(void *s, int c, size_t n); | 196 | void *memscan(void *s, int c, size_t n); |
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index a10e11f7a5f7..0e30e6e43b0c 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c | |||
@@ -43,11 +43,13 @@ static inline char *__strnend(const char *s, size_t n) | |||
43 | * | 43 | * |
44 | * returns the length of @s | 44 | * returns the length of @s |
45 | */ | 45 | */ |
46 | #ifdef __HAVE_ARCH_STRLEN | ||
46 | size_t strlen(const char *s) | 47 | size_t strlen(const char *s) |
47 | { | 48 | { |
48 | return __strend(s) - s; | 49 | return __strend(s) - s; |
49 | } | 50 | } |
50 | EXPORT_SYMBOL(strlen); | 51 | EXPORT_SYMBOL(strlen); |
52 | #endif | ||
51 | 53 | ||
52 | /** | 54 | /** |
53 | * strnlen - Find the length of a length-limited string | 55 | * strnlen - Find the length of a length-limited string |
@@ -56,11 +58,13 @@ EXPORT_SYMBOL(strlen); | |||
56 | * | 58 | * |
57 | * returns the minimum of the length of @s and @n | 59 | * returns the minimum of the length of @s and @n |
58 | */ | 60 | */ |
61 | #ifdef __HAVE_ARCH_STRNLEN | ||
59 | size_t strnlen(const char *s, size_t n) | 62 | size_t strnlen(const char *s, size_t n) |
60 | { | 63 | { |
61 | return __strnend(s, n) - s; | 64 | return __strnend(s, n) - s; |
62 | } | 65 | } |
63 | EXPORT_SYMBOL(strnlen); | 66 | EXPORT_SYMBOL(strnlen); |
67 | #endif | ||
64 | 68 | ||
65 | /** | 69 | /** |
66 | * strcpy - Copy a %NUL terminated string | 70 | * strcpy - Copy a %NUL terminated string |
@@ -69,6 +73,7 @@ EXPORT_SYMBOL(strnlen); | |||
69 | * | 73 | * |
70 | * returns a pointer to @dest | 74 | * returns a pointer to @dest |
71 | */ | 75 | */ |
76 | #ifdef __HAVE_ARCH_STRCPY | ||
72 | char *strcpy(char *dest, const char *src) | 77 | char *strcpy(char *dest, const char *src) |
73 | { | 78 | { |
74 | register int r0 asm("0") = 0; | 79 | register int r0 asm("0") = 0; |
@@ -81,6 +86,7 @@ char *strcpy(char *dest, const char *src) | |||
81 | return ret; | 86 | return ret; |
82 | } | 87 | } |
83 | EXPORT_SYMBOL(strcpy); | 88 | EXPORT_SYMBOL(strcpy); |
89 | #endif | ||
84 | 90 | ||
85 | /** | 91 | /** |
86 | * strlcpy - Copy a %NUL terminated string into a sized buffer | 92 | * strlcpy - Copy a %NUL terminated string into a sized buffer |
@@ -93,6 +99,7 @@ EXPORT_SYMBOL(strcpy); | |||
93 | * of course, the buffer size is zero). It does not pad | 99 | * of course, the buffer size is zero). It does not pad |
94 | * out the result like strncpy() does. | 100 | * out the result like strncpy() does. |
95 | */ | 101 | */ |
102 | #ifdef __HAVE_ARCH_STRLCPY | ||
96 | size_t strlcpy(char *dest, const char *src, size_t size) | 103 | size_t strlcpy(char *dest, const char *src, size_t size) |
97 | { | 104 | { |
98 | size_t ret = __strend(src) - src; | 105 | size_t ret = __strend(src) - src; |
@@ -105,6 +112,7 @@ size_t strlcpy(char *dest, const char *src, size_t size) | |||
105 | return ret; | 112 | return ret; |
106 | } | 113 | } |
107 | EXPORT_SYMBOL(strlcpy); | 114 | EXPORT_SYMBOL(strlcpy); |
115 | #endif | ||
108 | 116 | ||
109 | /** | 117 | /** |
110 | * strncpy - Copy a length-limited, %NUL-terminated string | 118 | * strncpy - Copy a length-limited, %NUL-terminated string |
@@ -115,6 +123,7 @@ EXPORT_SYMBOL(strlcpy); | |||
115 | * The result is not %NUL-terminated if the source exceeds | 123 | * The result is not %NUL-terminated if the source exceeds |
116 | * @n bytes. | 124 | * @n bytes. |
117 | */ | 125 | */ |
126 | #ifdef __HAVE_ARCH_STRNCPY | ||
118 | char *strncpy(char *dest, const char *src, size_t n) | 127 | char *strncpy(char *dest, const char *src, size_t n) |
119 | { | 128 | { |
120 | size_t len = __strnend(src, n) - src; | 129 | size_t len = __strnend(src, n) - src; |
@@ -123,6 +132,7 @@ char *strncpy(char *dest, const char *src, size_t n) | |||
123 | return dest; | 132 | return dest; |
124 | } | 133 | } |
125 | EXPORT_SYMBOL(strncpy); | 134 | EXPORT_SYMBOL(strncpy); |
135 | #endif | ||
126 | 136 | ||
127 | /** | 137 | /** |
128 | * strcat - Append one %NUL-terminated string to another | 138 | * strcat - Append one %NUL-terminated string to another |
@@ -131,6 +141,7 @@ EXPORT_SYMBOL(strncpy); | |||
131 | * | 141 | * |
132 | * returns a pointer to @dest | 142 | * returns a pointer to @dest |
133 | */ | 143 | */ |
144 | #ifdef __HAVE_ARCH_STRCAT | ||
134 | char *strcat(char *dest, const char *src) | 145 | char *strcat(char *dest, const char *src) |
135 | { | 146 | { |
136 | register int r0 asm("0") = 0; | 147 | register int r0 asm("0") = 0; |
@@ -146,6 +157,7 @@ char *strcat(char *dest, const char *src) | |||
146 | return ret; | 157 | return ret; |
147 | } | 158 | } |
148 | EXPORT_SYMBOL(strcat); | 159 | EXPORT_SYMBOL(strcat); |
160 | #endif | ||
149 | 161 | ||
150 | /** | 162 | /** |
151 | * strlcat - Append a length-limited, %NUL-terminated string to another | 163 | * strlcat - Append a length-limited, %NUL-terminated string to another |
@@ -153,6 +165,7 @@ EXPORT_SYMBOL(strcat); | |||
153 | * @src: The string to append to it | 165 | * @src: The string to append to it |
154 | * @n: The size of the destination buffer. | 166 | * @n: The size of the destination buffer. |
155 | */ | 167 | */ |
168 | #ifdef __HAVE_ARCH_STRLCAT | ||
156 | size_t strlcat(char *dest, const char *src, size_t n) | 169 | size_t strlcat(char *dest, const char *src, size_t n) |
157 | { | 170 | { |
158 | size_t dsize = __strend(dest) - dest; | 171 | size_t dsize = __strend(dest) - dest; |
@@ -170,6 +183,7 @@ size_t strlcat(char *dest, const char *src, size_t n) | |||
170 | return res; | 183 | return res; |
171 | } | 184 | } |
172 | EXPORT_SYMBOL(strlcat); | 185 | EXPORT_SYMBOL(strlcat); |
186 | #endif | ||
173 | 187 | ||
174 | /** | 188 | /** |
175 | * strncat - Append a length-limited, %NUL-terminated string to another | 189 | * strncat - Append a length-limited, %NUL-terminated string to another |
@@ -182,6 +196,7 @@ EXPORT_SYMBOL(strlcat); | |||
182 | * Note that in contrast to strncpy, strncat ensures the result is | 196 | * Note that in contrast to strncpy, strncat ensures the result is |
183 | * terminated. | 197 | * terminated. |
184 | */ | 198 | */ |
199 | #ifdef __HAVE_ARCH_STRNCAT | ||
185 | char *strncat(char *dest, const char *src, size_t n) | 200 | char *strncat(char *dest, const char *src, size_t n) |
186 | { | 201 | { |
187 | size_t len = __strnend(src, n) - src; | 202 | size_t len = __strnend(src, n) - src; |
@@ -192,6 +207,7 @@ char *strncat(char *dest, const char *src, size_t n) | |||
192 | return dest; | 207 | return dest; |
193 | } | 208 | } |
194 | EXPORT_SYMBOL(strncat); | 209 | EXPORT_SYMBOL(strncat); |
210 | #endif | ||
195 | 211 | ||
196 | /** | 212 | /** |
197 | * strcmp - Compare two strings | 213 | * strcmp - Compare two strings |
@@ -202,6 +218,7 @@ EXPORT_SYMBOL(strncat); | |||
202 | * < 0 if @s1 is less than @s2 | 218 | * < 0 if @s1 is less than @s2 |
203 | * > 0 if @s1 is greater than @s2 | 219 | * > 0 if @s1 is greater than @s2 |
204 | */ | 220 | */ |
221 | #ifdef __HAVE_ARCH_STRCMP | ||
205 | int strcmp(const char *s1, const char *s2) | 222 | int strcmp(const char *s1, const char *s2) |
206 | { | 223 | { |
207 | register int r0 asm("0") = 0; | 224 | register int r0 asm("0") = 0; |
@@ -219,12 +236,14 @@ int strcmp(const char *s1, const char *s2) | |||
219 | return ret; | 236 | return ret; |
220 | } | 237 | } |
221 | EXPORT_SYMBOL(strcmp); | 238 | EXPORT_SYMBOL(strcmp); |
239 | #endif | ||
222 | 240 | ||
223 | /** | 241 | /** |
224 | * strrchr - Find the last occurrence of a character in a string | 242 | * strrchr - Find the last occurrence of a character in a string |
225 | * @s: The string to be searched | 243 | * @s: The string to be searched |
226 | * @c: The character to search for | 244 | * @c: The character to search for |
227 | */ | 245 | */ |
246 | #ifdef __HAVE_ARCH_STRRCHR | ||
228 | char *strrchr(const char *s, int c) | 247 | char *strrchr(const char *s, int c) |
229 | { | 248 | { |
230 | size_t len = __strend(s) - s; | 249 | size_t len = __strend(s) - s; |
@@ -237,6 +256,7 @@ char *strrchr(const char *s, int c) | |||
237 | return NULL; | 256 | return NULL; |
238 | } | 257 | } |
239 | EXPORT_SYMBOL(strrchr); | 258 | EXPORT_SYMBOL(strrchr); |
259 | #endif | ||
240 | 260 | ||
241 | static inline int clcle(const char *s1, unsigned long l1, | 261 | static inline int clcle(const char *s1, unsigned long l1, |
242 | const char *s2, unsigned long l2) | 262 | const char *s2, unsigned long l2) |
@@ -261,6 +281,7 @@ static inline int clcle(const char *s1, unsigned long l1, | |||
261 | * @s1: The string to be searched | 281 | * @s1: The string to be searched |
262 | * @s2: The string to search for | 282 | * @s2: The string to search for |
263 | */ | 283 | */ |
284 | #ifdef __HAVE_ARCH_STRSTR | ||
264 | char *strstr(const char *s1, const char *s2) | 285 | char *strstr(const char *s1, const char *s2) |
265 | { | 286 | { |
266 | int l1, l2; | 287 | int l1, l2; |
@@ -280,6 +301,7 @@ char *strstr(const char *s1, const char *s2) | |||
280 | return NULL; | 301 | return NULL; |
281 | } | 302 | } |
282 | EXPORT_SYMBOL(strstr); | 303 | EXPORT_SYMBOL(strstr); |
304 | #endif | ||
283 | 305 | ||
284 | /** | 306 | /** |
285 | * memchr - Find a character in an area of memory. | 307 | * memchr - Find a character in an area of memory. |
@@ -290,6 +312,7 @@ EXPORT_SYMBOL(strstr); | |||
290 | * returns the address of the first occurrence of @c, or %NULL | 312 | * returns the address of the first occurrence of @c, or %NULL |
291 | * if @c is not found | 313 | * if @c is not found |
292 | */ | 314 | */ |
315 | #ifdef __HAVE_ARCH_MEMCHR | ||
293 | void *memchr(const void *s, int c, size_t n) | 316 | void *memchr(const void *s, int c, size_t n) |
294 | { | 317 | { |
295 | register int r0 asm("0") = (char) c; | 318 | register int r0 asm("0") = (char) c; |
@@ -304,6 +327,7 @@ void *memchr(const void *s, int c, size_t n) | |||
304 | return (void *) ret; | 327 | return (void *) ret; |
305 | } | 328 | } |
306 | EXPORT_SYMBOL(memchr); | 329 | EXPORT_SYMBOL(memchr); |
330 | #endif | ||
307 | 331 | ||
308 | /** | 332 | /** |
309 | * memcmp - Compare two areas of memory | 333 | * memcmp - Compare two areas of memory |
@@ -311,6 +335,7 @@ EXPORT_SYMBOL(memchr); | |||
311 | * @s2: Another area of memory | 335 | * @s2: Another area of memory |
312 | * @count: The size of the area. | 336 | * @count: The size of the area. |
313 | */ | 337 | */ |
338 | #ifdef __HAVE_ARCH_MEMCMP | ||
314 | int memcmp(const void *s1, const void *s2, size_t n) | 339 | int memcmp(const void *s1, const void *s2, size_t n) |
315 | { | 340 | { |
316 | int ret; | 341 | int ret; |
@@ -321,6 +346,7 @@ int memcmp(const void *s1, const void *s2, size_t n) | |||
321 | return ret; | 346 | return ret; |
322 | } | 347 | } |
323 | EXPORT_SYMBOL(memcmp); | 348 | EXPORT_SYMBOL(memcmp); |
349 | #endif | ||
324 | 350 | ||
325 | /** | 351 | /** |
326 | * memscan - Find a character in an area of memory. | 352 | * memscan - Find a character in an area of memory. |
@@ -331,6 +357,7 @@ EXPORT_SYMBOL(memcmp); | |||
331 | * returns the address of the first occurrence of @c, or 1 byte past | 357 | * returns the address of the first occurrence of @c, or 1 byte past |
332 | * the area if @c is not found | 358 | * the area if @c is not found |
333 | */ | 359 | */ |
360 | #ifdef __HAVE_ARCH_MEMSCAN | ||
334 | void *memscan(void *s, int c, size_t n) | 361 | void *memscan(void *s, int c, size_t n) |
335 | { | 362 | { |
336 | register int r0 asm("0") = (char) c; | 363 | register int r0 asm("0") = (char) c; |
@@ -342,3 +369,4 @@ void *memscan(void *s, int c, size_t n) | |||
342 | return (void *) ret; | 369 | return (void *) ret; |
343 | } | 370 | } |
344 | EXPORT_SYMBOL(memscan); | 371 | EXPORT_SYMBOL(memscan); |
372 | #endif | ||