diff options
-rw-r--r-- | payloads/libpayload/libc/memory.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/payloads/libpayload/libc/memory.c b/payloads/libpayload/libc/memory.c index 1adfb3207f..2c44764edb 100644 --- a/payloads/libpayload/libc/memory.c +++ b/payloads/libpayload/libc/memory.c @@ -66,13 +66,17 @@ static void *default_memcpy(void *dst, const void *src, size_t n) size_t i; void *ret = dst; - for(i = 0; i < n / sizeof(unsigned long); i++) - ((unsigned long *)dst)[i] = ((unsigned long *)src)[i]; + if (IS_ALIGNED((uintptr_t)dst, sizeof(unsigned long)) && + IS_ALIGNED((uintptr_t)src, sizeof(unsigned long))) { + for (i = 0; i < n / sizeof(unsigned long); i++) + ((unsigned long *)dst)[i] = ((unsigned long *)src)[i]; - src += i * sizeof(unsigned long); - dst += i * sizeof(unsigned long); + src += i * sizeof(unsigned long); + dst += i * sizeof(unsigned long); + n -= i * sizeof(unsigned long); + } - for(i = 0; i < n % sizeof(unsigned long); i++) + for (i = 0; i < n; i++) ((u8 *)dst)[i] = ((u8 *)src)[i]; return ret; @@ -89,6 +93,13 @@ static void *default_memmove(void *dst, const void *src, size_t n) if (src > dst) return memcpy(dst, src, n); + if (!IS_ALIGNED((uintptr_t)dst, sizeof(unsigned long)) || + !IS_ALIGNED((uintptr_t)src, sizeof(unsigned long))) { + for (i = n - 1; i >= 0; i--) + ((u8 *)dst)[i] = ((u8 *)src)[i]; + return dst; + } + offs = n - (n % sizeof(unsigned long)); for (i = (n % sizeof(unsigned long)) - 1; i >= 0; i--) @@ -116,11 +127,14 @@ void *memmove(void *dst, const void *src, size_t n) static int default_memcmp(const void *s1, const void *s2, size_t n) { - size_t i; - - for (i = 0; i < n / sizeof(unsigned long); i++) - if (((unsigned long *)s1)[i] != ((unsigned long *)s2)[i]) - break; /* fall through to find differing byte */ + size_t i = 0; + const unsigned long *w1 = s1, *w2 = s2; + + if (IS_ALIGNED((uintptr_t)s1, sizeof(unsigned long)) && + IS_ALIGNED((uintptr_t)s2, sizeof(unsigned long))) + for (; i < n / sizeof(unsigned long); i++) + if (w1[i] != w2[i]) + break; /* fall through to find differing byte */ for (i *= sizeof(unsigned long); i < n; i++) if (((u8 *)s1)[i] != ((u8 *)s2)[i]) |