1 #include "asan_impl.h"
2 #include "libc.h"
3 #include <string.h>
4 
5 #define WT size_t
6 #define WS (sizeof(WT))
7 
memmove(void * dest,const void * src,size_t n)8 NO_ASAN void* memmove(void* dest, const void* src, size_t n) {
9     char* d = dest;
10     const char* s = src;
11 
12     if (d == s)
13         return d;
14     if (s + n <= d || d + n <= s)
15         return __unsanitized_memcpy(d, s, n);
16 
17     if (d < s) {
18         if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
19             while ((uintptr_t)d % WS) {
20                 if (!n--)
21                     return dest;
22                 *d++ = *s++;
23             }
24             for (; n >= WS; n -= WS, d += WS, s += WS)
25                 *(WT*)d = *(WT*)s;
26         }
27         for (; n; n--)
28             *d++ = *s++;
29     } else {
30         if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
31             while ((uintptr_t)(d + n) % WS) {
32                 if (!n--)
33                     return dest;
34                 d[n] = s[n];
35             }
36             while (n >= WS)
37                 n -= WS, *(WT*)(d + n) = *(WT*)(s + n);
38         }
39         while (n)
40             n--, d[n] = s[n];
41     }
42 
43     return dest;
44 }
45 
46 __typeof(memmove) __unsanitized_memmove __attribute__((alias("memmove")));
47 __asan_weak_alias(memmove)
48