162 lines · 2.9 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * arch/arm/boot/compressed/string.c * * Small subset of simple string routines */ #define __NO_FORTIFY#include <linux/string.h> /* * The decompressor is built without KASan but uses the same redirects as the * rest of the kernel when CONFIG_KASAN is enabled, defining e.g. memcpy() * to __memcpy() but since we are not linking with the main kernel string * library in the decompressor, that will lead to link failures. * * Undefine KASan's versions, define the wrapped functions and alias them to * the right names so that when e.g. __memcpy() appear in the code, it will * still be linked to this local version of memcpy(). */#ifdef CONFIG_KASAN#undef memcpy#undef memmove#undef memsetvoid *__memcpy(void *__dest, __const void *__src, size_t __n) __alias(memcpy);void *__memmove(void *__dest, __const void *__src, size_t count) __alias(memmove);void *__memset(void *s, int c, size_t count) __alias(memset);#endif void *memcpy(void *__dest, __const void *__src, size_t __n){	int i = 0;	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; 	for (i = __n >> 3; i > 0; i--) {		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;	} 	if (__n & 1 << 2) {		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;	} 	if (__n & 1 << 1) {		*d++ = *s++;		*d++ = *s++;	} 	if (__n & 1)		*d++ = *s++; 	return __dest;} void *memmove(void *__dest, __const void *__src, size_t count){	unsigned char *d = __dest;	const unsigned char *s = __src; 	if (__dest == __src)		return __dest; 	if (__dest < __src)		return memcpy(__dest, __src, count); 	while (count--)		d[count] = s[count];	return __dest;} size_t strlen(const char *s){	const char *sc = s; 	while (*sc != '\0')		sc++;	return sc - s;} size_t strnlen(const char *s, size_t count){	const char *sc; 	for (sc = s; count-- && *sc != '\0'; ++sc)		/* nothing */;	return sc - s;} int memcmp(const void *cs, const void *ct, size_t count){	const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;	int res = 0; 	while (su1 < end) {		res = *su1++ - *su2++;		if (res)			break;	}	return res;} int strcmp(const char *cs, const char *ct){	unsigned char c1, c2;	int res = 0; 	do {		c1 = *cs++;		c2 = *ct++;		res = c1 - c2;		if (res)			break;	} while (c1);	return res;} void *memchr(const void *s, int c, size_t count){	const unsigned char *p = s; 	while (count--)		if ((unsigned char)c == *p++)			return (void *)(p - 1);	return NULL;} char *strchr(const char *s, int c){	while (*s != (char)c)		if (*s++ == '\0')			return NULL;	return (char *)s;} char *strrchr(const char *s, int c){	const char *last = NULL;	do {		if (*s == (char)c)			last = s;	} while (*s++);	return (char *)last;} #undef memset void *memset(void *s, int c, size_t count){	char *xs = s;	while (count--)		*xs++ = c;	return s;}