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