]> git.corax.cc Git - corax/commitdiff
libc, kernel/klibc: Fix bug in memcpy() where quantities less than 4 byte wouldn...
authorMatthias Kruk <m@m10k.eu>
Sun, 26 Jul 2020 08:09:52 +0000 (17:09 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 26 Jul 2020 08:09:52 +0000 (17:09 +0900)
kernel/klibc/Makefile
kernel/klibc/string.c
kernel/klibc/string_ia32.S [new file with mode: 0644]
libc/Makefile
libc/string.c
libc/string_ia32.S [new file with mode: 0644]

index 40a2c94abc7d9b521791b82ccffc708abac7be8a..ff21f074dede149f5c0916ed07a6772de5c1b0d2 100644 (file)
@@ -1,6 +1,6 @@
 OUTPUT = klibc.a
 OBJECTS = string.o spinlock.o mutex.o posixcall.o coraxcall.o heap.o stdio.o signal.o \
-          kq.o sem.o
+          kq.o sem.o string_ia32.o
 PHONY = clean
 INCLUDES = -I../include -I../../include -I../..
 CFLAGS = -m32 -Wall -nostdlib -nodefaultlibs -nostartfiles -ffreestanding $(INCLUDES)
index 657d7460dfe7c7de1aee40ed312cbe2efe9f0dd6..aa56af366f328caff41d2ebcf7c78a4f4ed63343 100644 (file)
@@ -10,33 +10,6 @@ size_t strlen(const char *s)
        return(ret_val);
 }
 
-void* memcpy(void *dst, const void *src, size_t n)
-{
-       u32_t *d;
-       const u32_t *s;
-
-       d = (u32_t*)dst;
-       s = (const u32_t*)src;
-
-       while(n > 4) {
-               *d++ = *s++;
-               n -= 4;
-       }
-
-       if(n >= 2) {
-               *((u16_t*)d) = *((u16_t*)s);
-               d = (u32_t*)(((void*)d) + 2);
-               s = (u32_t*)(((void*)s) + 2);
-               n -= 2;
-       }
-
-       if(n >= 1) {
-               *((u8_t*)d) = *((u8_t*)s);
-       }
-
-       return(dst);
-}
-
 void* memset(void *dst, int val, u32_t n)
 {
        char *ptr;
diff --git a/kernel/klibc/string_ia32.S b/kernel/klibc/string_ia32.S
new file mode 100644 (file)
index 0000000..b2fb623
--- /dev/null
@@ -0,0 +1,44 @@
+#define __ASSEMBLY_SOURCE
+
+#include <config.h>
+
+.section .text
+
+.global memcpy
+
+memcpy:
+       pushl   %ebx
+
+       movl    8(%esp), %eax
+       movl    12(%esp), %ebx
+       movl    16(%esp), %ecx
+
+0:     testl   $0xfffffffc, %ecx
+       jz      1f
+
+       movl    (%ebx), %edx
+       movl    %edx, (%eax)
+       addl    $4, %eax
+       addl    $4, %ebx
+       subl    $4, %ecx
+       jmp     0b
+
+1:     testl   $0x2, %ecx
+       jz      2f
+
+       movw    (%ebx), %dx
+       movw    %dx, (%eax)
+       addl    $2, %eax
+       addl    $2, %ebx
+       subl    $2, %ecx
+
+2:     testl   $0x1, %ecx
+       jz      3f
+
+       movb    (%ebx), %dl
+       movb    %dl, (%eax)
+
+3:     movl    8(%esp), %eax
+
+       popl    %ebx
+       ret
index 2d4fc3d94940e148298a9b276c3b06b0a20628b0..2383060c257b4708dd3e037de102f969ab628bb6 100644 (file)
@@ -1,7 +1,7 @@
 OUTPUT = libc.a
-OBJECTS = syscall.o string.o signal.o start.o stdio.o
+OBJECTS = syscall.o string.o signal.o start.o stdio.o string_ia32.o
 PHONY = clean
-INCLUDES = -I../include
+INCLUDES = -I../include -I..
 CFLAGS = -m32 -Wall -nostdlib -nodefaultlibs -nostartfiles -ffreestanding $(INCLUDES)
 ASFLAGS = $(CFLAGS)
 LIBGCC = /usr/lib/gcc-cross/i686-linux-gnu/8/libgcc.a
index 5822776f21b742073d8429083ae783a6d5c471c4..a8e548a69cdbcfe92f3fad4928faa5565cd871ae 100644 (file)
@@ -22,30 +22,3 @@ void *memset(void *s, int c, size_t n)
 
        return(s);
 }
-
-void* memcpy(void *dst, const void *src, size_t n)
-{
-        u32_t *d;
-        const u32_t *s;
-
-        d = (u32_t*)dst;
-        s = (const u32_t*)src;
-
-        while(n > 4) {
-                *d++ = *s++;
-                n -= 4;
-        }
-
-        if(n >= 2) {
-                *((u16_t*)d) = *((u16_t*)s);
-                d = (u32_t*)(((void*)d) + 2);
-                s = (u32_t*)(((void*)s) + 2);
-                n -= 2;
-        }
-
-        if(n >= 1) {
-                *((u8_t*)d) = *((u8_t*)s);
-        }
-
-        return(dst);
-}
diff --git a/libc/string_ia32.S b/libc/string_ia32.S
new file mode 100644 (file)
index 0000000..b2fb623
--- /dev/null
@@ -0,0 +1,44 @@
+#define __ASSEMBLY_SOURCE
+
+#include <config.h>
+
+.section .text
+
+.global memcpy
+
+memcpy:
+       pushl   %ebx
+
+       movl    8(%esp), %eax
+       movl    12(%esp), %ebx
+       movl    16(%esp), %ecx
+
+0:     testl   $0xfffffffc, %ecx
+       jz      1f
+
+       movl    (%ebx), %edx
+       movl    %edx, (%eax)
+       addl    $4, %eax
+       addl    $4, %ebx
+       subl    $4, %ecx
+       jmp     0b
+
+1:     testl   $0x2, %ecx
+       jz      2f
+
+       movw    (%ebx), %dx
+       movw    %dx, (%eax)
+       addl    $2, %eax
+       addl    $2, %ebx
+       subl    $2, %ecx
+
+2:     testl   $0x1, %ecx
+       jz      3f
+
+       movb    (%ebx), %dl
+       movb    %dl, (%eax)
+
+3:     movl    8(%esp), %eax
+
+       popl    %ebx
+       ret