| #include "asan_impl.h" |
| #include "libc.h" |
| #include <string.h> |
| |
| #define WT size_t |
| #define WS (sizeof(WT)) |
| |
| NO_ASAN void* memmove(void* dest, const void* src, size_t n) { |
| char* d = dest; |
| const char* s = src; |
| |
| if (d == s) |
| return d; |
| if (s + n <= d || d + n <= s) |
| return __unsanitized_memcpy(d, s, n); |
| |
| if (d < s) { |
| if ((uintptr_t)s % WS == (uintptr_t)d % WS) { |
| while ((uintptr_t)d % WS) { |
| if (!n--) |
| return dest; |
| *d++ = *s++; |
| } |
| for (; n >= WS; n -= WS, d += WS, s += WS) |
| *(WT*)d = *(WT*)s; |
| } |
| for (; n; n--) |
| *d++ = *s++; |
| } else { |
| if ((uintptr_t)s % WS == (uintptr_t)d % WS) { |
| while ((uintptr_t)(d + n) % WS) { |
| if (!n--) |
| return dest; |
| d[n] = s[n]; |
| } |
| while (n >= WS) |
| n -= WS, *(WT*)(d + n) = *(WT*)(s + n); |
| } |
| while (n) |
| n--, d[n] = s[n]; |
| } |
| |
| return dest; |
| } |
| |
| __typeof(memmove) __unsanitized_memmove __attribute__((alias("memmove"))); |
| __asan_weak_alias(memmove) |