0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "error.h"
0010
0011 #include "../string.c"
0012
0013 #ifdef CONFIG_X86_32
0014 static void *____memcpy(void *dest, const void *src, size_t n)
0015 {
0016 int d0, d1, d2;
0017 asm volatile(
0018 "rep ; movsl\n\t"
0019 "movl %4,%%ecx\n\t"
0020 "rep ; movsb\n\t"
0021 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
0022 : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
0023 : "memory");
0024
0025 return dest;
0026 }
0027 #else
0028 static void *____memcpy(void *dest, const void *src, size_t n)
0029 {
0030 long d0, d1, d2;
0031 asm volatile(
0032 "rep ; movsq\n\t"
0033 "movq %4,%%rcx\n\t"
0034 "rep ; movsb\n\t"
0035 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
0036 : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
0037 : "memory");
0038
0039 return dest;
0040 }
0041 #endif
0042
0043 void *memset(void *s, int c, size_t n)
0044 {
0045 int i;
0046 char *ss = s;
0047
0048 for (i = 0; i < n; i++)
0049 ss[i] = c;
0050 return s;
0051 }
0052
0053 void *memmove(void *dest, const void *src, size_t n)
0054 {
0055 unsigned char *d = dest;
0056 const unsigned char *s = src;
0057
0058 if (d <= s || d - s >= n)
0059 return ____memcpy(dest, src, n);
0060
0061 while (n-- > 0)
0062 d[n] = s[n];
0063
0064 return dest;
0065 }
0066
0067
0068 void *memcpy(void *dest, const void *src, size_t n)
0069 {
0070 if (dest > src && dest - src < n) {
0071 warn("Avoiding potentially unsafe overlapping memcpy()!");
0072 return memmove(dest, src, n);
0073 }
0074 return ____memcpy(dest, src, n);
0075 }
0076
0077 #ifdef CONFIG_KASAN
0078 extern void *__memset(void *s, int c, size_t n) __alias(memset);
0079 extern void *__memmove(void *dest, const void *src, size_t n) __alias(memmove);
0080 extern void *__memcpy(void *dest, const void *src, size_t n) __alias(memcpy);
0081 #endif