162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/boot/compressed/string.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Small subset of simple string routines 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define __NO_FORTIFY 962306a36Sopenharmony_ci#include <linux/string.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * The decompressor is built without KASan but uses the same redirects as the 1362306a36Sopenharmony_ci * rest of the kernel when CONFIG_KASAN is enabled, defining e.g. memcpy() 1462306a36Sopenharmony_ci * to __memcpy() but since we are not linking with the main kernel string 1562306a36Sopenharmony_ci * library in the decompressor, that will lead to link failures. 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * Undefine KASan's versions, define the wrapped functions and alias them to 1862306a36Sopenharmony_ci * the right names so that when e.g. __memcpy() appear in the code, it will 1962306a36Sopenharmony_ci * still be linked to this local version of memcpy(). 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci#ifdef CONFIG_KASAN 2262306a36Sopenharmony_ci#undef memcpy 2362306a36Sopenharmony_ci#undef memmove 2462306a36Sopenharmony_ci#undef memset 2562306a36Sopenharmony_civoid *__memcpy(void *__dest, __const void *__src, size_t __n) __alias(memcpy); 2662306a36Sopenharmony_civoid *__memmove(void *__dest, __const void *__src, size_t count) __alias(memmove); 2762306a36Sopenharmony_civoid *__memset(void *s, int c, size_t count) __alias(memset); 2862306a36Sopenharmony_ci#endif 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_civoid *memcpy(void *__dest, __const void *__src, size_t __n) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci int i = 0; 3362306a36Sopenharmony_ci unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci for (i = __n >> 3; i > 0; i--) { 3662306a36Sopenharmony_ci *d++ = *s++; 3762306a36Sopenharmony_ci *d++ = *s++; 3862306a36Sopenharmony_ci *d++ = *s++; 3962306a36Sopenharmony_ci *d++ = *s++; 4062306a36Sopenharmony_ci *d++ = *s++; 4162306a36Sopenharmony_ci *d++ = *s++; 4262306a36Sopenharmony_ci *d++ = *s++; 4362306a36Sopenharmony_ci *d++ = *s++; 4462306a36Sopenharmony_ci } 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci if (__n & 1 << 2) { 4762306a36Sopenharmony_ci *d++ = *s++; 4862306a36Sopenharmony_ci *d++ = *s++; 4962306a36Sopenharmony_ci *d++ = *s++; 5062306a36Sopenharmony_ci *d++ = *s++; 5162306a36Sopenharmony_ci } 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci if (__n & 1 << 1) { 5462306a36Sopenharmony_ci *d++ = *s++; 5562306a36Sopenharmony_ci *d++ = *s++; 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci if (__n & 1) 5962306a36Sopenharmony_ci *d++ = *s++; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return __dest; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_civoid *memmove(void *__dest, __const void *__src, size_t count) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci unsigned char *d = __dest; 6762306a36Sopenharmony_ci const unsigned char *s = __src; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci if (__dest == __src) 7062306a36Sopenharmony_ci return __dest; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci if (__dest < __src) 7362306a36Sopenharmony_ci return memcpy(__dest, __src, count); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci while (count--) 7662306a36Sopenharmony_ci d[count] = s[count]; 7762306a36Sopenharmony_ci return __dest; 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cisize_t strlen(const char *s) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci const char *sc = s; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci while (*sc != '\0') 8562306a36Sopenharmony_ci sc++; 8662306a36Sopenharmony_ci return sc - s; 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cisize_t strnlen(const char *s, size_t count) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci const char *sc; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci for (sc = s; count-- && *sc != '\0'; ++sc) 9462306a36Sopenharmony_ci /* nothing */; 9562306a36Sopenharmony_ci return sc - s; 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ciint memcmp(const void *cs, const void *ct, size_t count) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; 10162306a36Sopenharmony_ci int res = 0; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci while (su1 < end) { 10462306a36Sopenharmony_ci res = *su1++ - *su2++; 10562306a36Sopenharmony_ci if (res) 10662306a36Sopenharmony_ci break; 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci return res; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciint strcmp(const char *cs, const char *ct) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci unsigned char c1, c2; 11462306a36Sopenharmony_ci int res = 0; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci do { 11762306a36Sopenharmony_ci c1 = *cs++; 11862306a36Sopenharmony_ci c2 = *ct++; 11962306a36Sopenharmony_ci res = c1 - c2; 12062306a36Sopenharmony_ci if (res) 12162306a36Sopenharmony_ci break; 12262306a36Sopenharmony_ci } while (c1); 12362306a36Sopenharmony_ci return res; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_civoid *memchr(const void *s, int c, size_t count) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci const unsigned char *p = s; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci while (count--) 13162306a36Sopenharmony_ci if ((unsigned char)c == *p++) 13262306a36Sopenharmony_ci return (void *)(p - 1); 13362306a36Sopenharmony_ci return NULL; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cichar *strchr(const char *s, int c) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci while (*s != (char)c) 13962306a36Sopenharmony_ci if (*s++ == '\0') 14062306a36Sopenharmony_ci return NULL; 14162306a36Sopenharmony_ci return (char *)s; 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cichar *strrchr(const char *s, int c) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci const char *last = NULL; 14762306a36Sopenharmony_ci do { 14862306a36Sopenharmony_ci if (*s == (char)c) 14962306a36Sopenharmony_ci last = s; 15062306a36Sopenharmony_ci } while (*s++); 15162306a36Sopenharmony_ci return (char *)last; 15262306a36Sopenharmony_ci} 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#undef memset 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_civoid *memset(void *s, int c, size_t count) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci char *xs = s; 15962306a36Sopenharmony_ci while (count--) 16062306a36Sopenharmony_ci *xs++ = c; 16162306a36Sopenharmony_ci return s; 16262306a36Sopenharmony_ci} 163