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