[PATCH] msvcrt: Import memmove from musl

Fabian Maurer dark.shadow4 at web.de
Tue Aug 11 11:31:49 CDT 2020


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49663
Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/msvcrt/string.c | 53 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index ab6747db5c..fb2ef3ee01 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <math.h>
 #include <limits.h>
+#include <stdint.h>
 #include <errno.h>
 #include "msvcrt.h"
 #include "bnum.h"
@@ -2482,22 +2483,50 @@ int __cdecl MSVCRT_memcmp(const void *ptr1, const void *ptr2, MSVCRT_size_t n)

 /*********************************************************************
  *                  memmove (MSVCRT.@)
+ * Copied from musl (http://www.musl-libc.org/): src/string/memmove.c
+ *
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
  */
 void * __cdecl MSVCRT_memmove(void *dst, const void *src, MSVCRT_size_t n)
 {
-    volatile unsigned char *d = dst;  /* avoid gcc optimizations */
-    const unsigned char *s = src;
-
-    if ((MSVCRT_size_t)dst - (MSVCRT_size_t)src >= n)
-    {
-        while (n--) *d++ = *s++;
-    }
-    else
-    {
-        d += n - 1;
-        s += n - 1;
-        while (n--) *d-- = *s--;
+    char *d = dst;
+    const char *s = src;
+	typedef __attribute__((__may_alias__)) size_t WT;
+	const int WS = sizeof(WT);
+
+    if (d==s) return d;
+
+    if (d<s) {
+#ifdef __GNUC__
+        if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+            while ((uintptr_t)d % WS) {
+                if (!n--) return dst;
+                *d++ = *s++;
+            }
+            for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
+        }
+#endif
+        for (; n; n--) *d++ = *s++;
+    } else {
+#ifdef __GNUC__
+        if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+            while ((uintptr_t)(d+n) % WS) {
+                if (!n--) return dst;
+                d[n] = s[n];
+            }
+            while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
+        }
+#endif
+        while (n) n--, d[n] = s[n];
     }
+
     return dst;
 }

--
2.28.0




More information about the wine-devel mailing list