From eba8e12e8f0d113056264f71b8cbcda730e93506 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Fri, 26 Aug 2022 12:19:13 +0200
Subject: shared: memmove

---
 src/shared/mem.c                 | 18 +++++++++++++++---
 src/shared/mem.h                 |  1 +
 src/user/app/tests/libc/string.c | 12 ++++++++++++
 src/user/app/vterm/draw.c        |  3 +--
 src/user/lib/fs/misc.c           |  5 +----
 5 files changed, 30 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/shared/mem.c b/src/shared/mem.c
index e3279f6..14dd6bd 100644
--- a/src/shared/mem.c
+++ b/src/shared/mem.c
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <shared/mem.h>
 #include <stdint.h>
 
@@ -28,16 +29,27 @@ void *memcpy(void *dest, const void *src, size_t n) {
 	// TODO erms, rep movsb
 	union dualptr_const s = {.c = src};
 	union dualptr d = {.c = dest};
+	if (dest == src) return dest;
+	// assert(src >= dest || src + n < dest);
 
-	for (; (d.u & 7) && n != 0; n--)
+	for (; (d.u & 7) && n != 0; n--) {
 		*(d.c)++ = *(s.c)++;
-
+	}
 	while (n >= sizeof(uintptr_t)) {
 		*(d.w)++ = *(s.w)++;
 		n -= sizeof(uintptr_t);
 	}
-	while (n-- != 0)
+	while (n-- != 0) {
 		*(d.c)++ = *(s.c)++;
+	}
+	return dest;
+}
+
+void *memmove(void *dest, const void *src, size_t n) {
+	if (src >= dest || src + n < dest)
+		return memcpy(dest, src, n);
+	for (; n; n--) /* naive reverse copy */
+		((uint8_t*)dest)[n-1] = ((uint8_t*)src)[n-1];
 	return dest;
 }
 
diff --git a/src/shared/mem.h b/src/shared/mem.h
index aac87f5..3597edf 100644
--- a/src/shared/mem.h
+++ b/src/shared/mem.h
@@ -8,6 +8,7 @@ void *memchr(const void *s, int c, size_t n);
 int memcmp(const void *s1, const void *s2, size_t n);
 
 void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
 void *memset(void *s, int c, size_t n);
 
 int strcmp(const char *s1, const char *s2);
diff --git a/src/user/app/tests/libc/string.c b/src/user/app/tests/libc/string.c
index f865d72..2e00049 100644
--- a/src/user/app/tests/libc/string.c
+++ b/src/user/app/tests/libc/string.c
@@ -38,6 +38,17 @@ static void test_memset(void) {
 	free(buf);
 }
 
+static void test_memmove(void) {
+	const int partsize = 64;
+	char buf[partsize * 3];
+	for (int i = 0; i < partsize * 2; i++) {
+		memset(buf, 0, sizeof buf);
+		for (int j = 0; j < partsize; j++) buf[i + j] = j;
+		memmove(buf + partsize, buf + i, partsize);
+		for (int j = 0; j < partsize; j++) test(buf[partsize + j] == j);
+	}
+}
+
 static void test_strcmp(void) {
 	test(0 == strcmp("string", "string"));
 	test(0 > strcmp("str", "string"));
@@ -102,6 +113,7 @@ static void test_strtok(void) {
 void r_libc_string(void) {
 	run_test(test_memcmp);
 	run_test(test_memset);
+	run_test(test_memmove);
 	run_test(test_strcmp);
 	run_test(test_strtol);
 	run_test(test_strspn);
diff --git a/src/user/app/vterm/draw.c b/src/user/app/vterm/draw.c
index 50c56ed..ee36a0f 100644
--- a/src/user/app/vterm/draw.c
+++ b/src/user/app/vterm/draw.c
@@ -7,9 +7,8 @@ struct framebuf fb;
 struct rect dirty;
 
 void scroll(void) {
-	// TODO memmove. this is UD
 	size_t row_len = fb.pitch * font.h;
-	memcpy(fb.b, fb.b + row_len, fb.len - row_len);
+	memmove(fb.b, fb.b + row_len, fb.len - row_len);
 	memset(fb.b + fb.len - row_len, 0, row_len);
 	cursor.y--;
 
diff --git a/src/user/lib/fs/misc.c b/src/user/lib/fs/misc.c
index d130901..7922659 100644
--- a/src/user/lib/fs/misc.c
+++ b/src/user/lib/fs/misc.c
@@ -51,10 +51,7 @@ void fs_passthru(const char *prefix) {
 						break;
 					}
 
-					// TODO memmove
-					char tmp[64];
-					memcpy(tmp, buf, res.len);
-					memcpy(buf + prefix_len, tmp, res.len);
+					memmove(buf + prefix_len, buf, res.len);
 					memcpy(buf, prefix, prefix_len);
 					res.len += prefix_len;
 				}
-- 
cgit v1.2.3