string.c (2971B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * arch/arm/boot/compressed/string.c 4 * 5 * Small subset of simple string routines 6 */ 7 8#define __NO_FORTIFY 9#include <linux/string.h> 10 11/* 12 * The decompressor is built without KASan but uses the same redirects as the 13 * rest of the kernel when CONFIG_KASAN is enabled, defining e.g. memcpy() 14 * to __memcpy() but since we are not linking with the main kernel string 15 * library in the decompressor, that will lead to link failures. 16 * 17 * Undefine KASan's versions, define the wrapped functions and alias them to 18 * the right names so that when e.g. __memcpy() appear in the code, it will 19 * still be linked to this local version of memcpy(). 20 */ 21#ifdef CONFIG_KASAN 22#undef memcpy 23#undef memmove 24#undef memset 25void *__memcpy(void *__dest, __const void *__src, size_t __n) __alias(memcpy); 26void *__memmove(void *__dest, __const void *__src, size_t count) __alias(memmove); 27void *__memset(void *s, int c, size_t count) __alias(memset); 28#endif 29 30void *memcpy(void *__dest, __const void *__src, size_t __n) 31{ 32 int i = 0; 33 unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; 34 35 for (i = __n >> 3; i > 0; i--) { 36 *d++ = *s++; 37 *d++ = *s++; 38 *d++ = *s++; 39 *d++ = *s++; 40 *d++ = *s++; 41 *d++ = *s++; 42 *d++ = *s++; 43 *d++ = *s++; 44 } 45 46 if (__n & 1 << 2) { 47 *d++ = *s++; 48 *d++ = *s++; 49 *d++ = *s++; 50 *d++ = *s++; 51 } 52 53 if (__n & 1 << 1) { 54 *d++ = *s++; 55 *d++ = *s++; 56 } 57 58 if (__n & 1) 59 *d++ = *s++; 60 61 return __dest; 62} 63 64void *memmove(void *__dest, __const void *__src, size_t count) 65{ 66 unsigned char *d = __dest; 67 const unsigned char *s = __src; 68 69 if (__dest == __src) 70 return __dest; 71 72 if (__dest < __src) 73 return memcpy(__dest, __src, count); 74 75 while (count--) 76 d[count] = s[count]; 77 return __dest; 78} 79 80size_t strlen(const char *s) 81{ 82 const char *sc = s; 83 84 while (*sc != '\0') 85 sc++; 86 return sc - s; 87} 88 89size_t strnlen(const char *s, size_t count) 90{ 91 const char *sc; 92 93 for (sc = s; count-- && *sc != '\0'; ++sc) 94 /* nothing */; 95 return sc - s; 96} 97 98int memcmp(const void *cs, const void *ct, size_t count) 99{ 100 const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; 101 int res = 0; 102 103 while (su1 < end) { 104 res = *su1++ - *su2++; 105 if (res) 106 break; 107 } 108 return res; 109} 110 111int strcmp(const char *cs, const char *ct) 112{ 113 unsigned char c1, c2; 114 int res = 0; 115 116 do { 117 c1 = *cs++; 118 c2 = *ct++; 119 res = c1 - c2; 120 if (res) 121 break; 122 } while (c1); 123 return res; 124} 125 126void *memchr(const void *s, int c, size_t count) 127{ 128 const unsigned char *p = s; 129 130 while (count--) 131 if ((unsigned char)c == *p++) 132 return (void *)(p - 1); 133 return NULL; 134} 135 136char *strchr(const char *s, int c) 137{ 138 while (*s != (char)c) 139 if (*s++ == '\0') 140 return NULL; 141 return (char *)s; 142} 143 144char *strrchr(const char *s, int c) 145{ 146 const char *last = NULL; 147 do { 148 if (*s == (char)c) 149 last = s; 150 } while (*s++); 151 return (char *)last; 152} 153 154#undef memset 155 156void *memset(void *s, int c, size_t count) 157{ 158 char *xs = s; 159 while (count--) 160 *xs++ = c; 161 return s; 162}