Move C runtime stuff into a separate library
authorcoderain <coderain@sdf.org>
Mon, 9 Oct 2017 17:10:24 +0000 (19:10 +0200)
committercoderain <coderain@sdf.org>
Mon, 9 Oct 2017 17:10:24 +0000 (19:10 +0200)
15 files changed:
.gitignore
Makefile
crt/.gitignore [new file with mode: 0644]
crt/Makefile [new file with mode: 0644]
crt/include/ctype.h [new file with mode: 0644]
crt/include/stdlib.h [new file with mode: 0644]
crt/include/string.h [new file with mode: 0644]
crt/src/algorithm.c [new file with mode: 0644]
crt/src/ctype.c [new file with mode: 0644]
crt/src/numconv.c [new file with mode: 0644]
crt/src/string.c [new file with mode: 0644]
kernel/Makefile
kernel/include/common.h
kernel/src/common.c
library/Makefile

index d07151e0e9e4a1e92671bbefb274aab00a70aa42..674843a1008368cbb642cdea08bbe67eda8c67a7 100644 (file)
@@ -8,6 +8,8 @@
 !Makefile
 !kernel
 !kernel/*
+!crt
+!crt/*
 !library
 !library/*
 !tests
index 3fdec0e51ef56b6e41ce98408aeefb9084ff6dc6..174130ce58486d74254d20cd1f41998c2a244c49 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,10 @@
 
 all: livecd.iso tests
 
-kernel:
+crt:
+       $(MAKE) -C crt all
+
+kernel: crt
        $(MAKE) -C kernel all
 
 library: kernel
diff --git a/crt/.gitignore b/crt/.gitignore
new file mode 100644 (file)
index 0000000..55a8867
--- /dev/null
@@ -0,0 +1,9 @@
+*
+
+# Include the following files:
+!.gitignore
+!Makefile
+!src
+!src/*
+!include
+!include/*
diff --git a/crt/Makefile b/crt/Makefile
new file mode 100644 (file)
index 0000000..15fa5e2
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# Makefile
+#
+# Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+DEBUG = yes
+
+# Compilers and tools
+CC = i686-elf-gcc
+ASM = nasm
+AR = i686-elf-ar
+
+# Directories
+SRCDIR = src
+OBJDIR = obj
+DEPDIR = dep
+
+# Flags
+CFLAGS = -Wall -Werror -ffreestanding -nostdlib -fPIC -I include
+ASMFLAGS = -felf
+
+ifeq ($(DEBUG), yes)
+    CFLAGS += -g
+else
+    CFLAGS += -O3
+endif
+
+# Input and output files
+SOURCES =  $(wildcard $(SRCDIR)/*.c)
+SOURCES += $(wildcard $(SRCDIR)/*.asm)
+
+DEPENDS = $(shell find $(DEPDIR) -type f -name \*.d)
+OBJECTS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(patsubst $(SRCDIR)/%.asm, $(OBJDIR)/%.o, $(SOURCES)))
+
+.PHONY: all clean
+
+all: $(OBJDIR) $(DEPDIR) libmlcrt.a
+
+-include $(DEPENDS)
+
+$(OBJDIR):
+       mkdir -p $(OBJDIR)
+
+$(DEPDIR):
+       mkdir -p $(DEPDIR)
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.c Makefile
+       mkdir -p $(dir $@)
+       mkdir -p $(dir $(@:$(OBJDIR)/%.o=$(DEPDIR)/%.d))
+       $(CC) $(CFLAGS) -MMD -MP -MF $(@:$(OBJDIR)/%.o=$(DEPDIR)/%.d) -o $@ -c $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.asm Makefile
+       $(ASM) $(ASMFLAGS) -o $@ $<
+
+libmlcrt.a: $(OBJECTS)
+       $(AR) rcs $@ $^
+
+clean:
+       rm -f libmlcrt.a
+       find $(OBJDIR) -name \*.o -delete
+       find $(DEPDIR) -name \*.d -delete
diff --git a/crt/include/ctype.h b/crt/include/ctype.h
new file mode 100644 (file)
index 0000000..e3c3b1b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * ctype.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+int isprint(int c);
+int isdigit(int c);
+int isxdigit(int c);
+int isspace(int c);
+char tolower(char c);
+char toupper(char c);
+
+#endif
diff --git a/crt/include/stdlib.h b/crt/include/stdlib.h
new file mode 100644 (file)
index 0000000..d850c54
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+char *itoa(int value, char *str, int base);
+int atoi(char *str);
+int strtol(const char *str, char **endptr, int base);
+unsigned long strtoul(const char *str, char **endptr, int base);
+unsigned long long strtoull(const char *str, char **endptr, int base);
+
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
+void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
+
+#endif
diff --git a/crt/include/string.h b/crt/include/string.h
new file mode 100644 (file)
index 0000000..21921f4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * string.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <limits.h>
+#include <ctype.h>
+
+char *strcpy(char *destination, const char *source);
+char *strncpy(char *destination, const char *source, size_t n);
+int strcmp(const char *str1, const char *str2);
+int stricmp(const char *str1, const char *str2);
+int strncmp(const char *str1, const char *str2, size_t n);
+char *strstr(const char *haystack, const char *needle);
+char *strchr(const char *str, char c);
+char *strrchr(const char *str, char c);
+char *strcat(char *destination, const char *source);
+char *strncat(char *destination, const char *source, size_t n);
+char *strdup(const char *source);
+char *strtok(char *str, const char *delimiters, char **endptr);
+size_t strlen(const char *str);
+void strrev(char *str);
+void memset(void *ptr, uint8_t value, uint32_t size);
+void memcpy(void *destination, const void *source, size_t n);
+void memmove(void *destination, const void *source, size_t n);
+int memcmp(const void *mem1, const void *mem2, size_t n);
+
+#endif
diff --git a/crt/src/algorithm.c b/crt/src/algorithm.c
new file mode 100644 (file)
index 0000000..c45e1d4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * algorithm.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
+{
+    void *pivot = (void*)((uintptr_t)base + (nmemb / 2) * size);
+    void *temp = __builtin_alloca(size);
+    if (nmemb <= 1) return;
+
+    size_t low = 0;
+    size_t high = nmemb - 1;
+
+    for (;;)
+    {
+        while (compare((void*)((uintptr_t)base + low * size), pivot) < 0) low++;
+        while (compare((void*)((uintptr_t)base + high * size), pivot) > 0) high--;
+        if (low >= high) break;
+
+        memcpy(temp, (void*)((uintptr_t)base + low * size), size);
+        memcpy((void*)((uintptr_t)base + low * size), (void*)((uintptr_t)base + high * size), size);
+        memcpy((void*)((uintptr_t)base + high * size), temp, size);
+    }
+
+    qsort(base, high, size, compare);
+    qsort((void*)((size_t)base + high * size), nmemb - high, size, compare);
+}
+
+void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
+{
+    long low = 0;
+    long high = nmemb - 1;
+
+    while (low <= high)
+    {
+        long mid = low + (high - low) / 2;
+        void *current = (void*)((uintptr_t)base + mid * size);
+        int comp = compare(current, key);
+
+        if (comp < 0) low = mid + 1;
+        else if (comp > 0) high = mid - 1;
+        else return current;
+    }
+
+    return NULL;
+}
diff --git a/crt/src/ctype.c b/crt/src/ctype.c
new file mode 100644 (file)
index 0000000..797ff58
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ctype.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+int isprint(int c)
+{
+    return c >= 0x20 && c <= 0x7E;
+}
+
+int isdigit(int c)
+{
+    return c >= '0' && c <= '9';
+}
+
+int isxdigit(int c)
+{
+    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+int isspace(int c)
+{
+    return strchr(" \t\n\v\f\r", c) != NULL;
+}
+
+char tolower(char c)
+{
+    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
+    return c;
+}
+
+char toupper(char c)
+{
+    if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
+    return c;
+}
diff --git a/crt/src/numconv.c b/crt/src/numconv.c
new file mode 100644 (file)
index 0000000..1d89453
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * numconv.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+char *itoa(int value, char *str, int base)
+{
+    int cnt = 0;
+    const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    int append_sign = 0;
+
+    if (base < 2 || base > 36) return NULL;
+
+    if (value == 0)
+    {
+        str[0] = '0';
+        str[1] = 0;
+        return str;
+    }
+
+    if (value < 0 && base == 10)
+    {
+        value = -value;
+        append_sign = 1;
+    }
+
+    uint32_t u_value = (uint32_t) value;
+
+    while (u_value > 0)
+    {
+        str[cnt++] = digits[u_value % base];
+        u_value /= base;
+    }
+
+    if (append_sign) str[cnt++] = '-';
+    str[cnt] = 0;
+    strrev(str);
+
+    return str;
+}
+
+int atoi(char *str)
+{
+    int i, len = strlen(str);
+    int ret = 0, z = 1;
+    int negative = (str[0] == '-');
+
+    if (negative) str[0] = '0';
+
+    for (i = len - 1; i >= 0; i--)
+    {
+        if (str[i] >= '0' && str[i] <= '9')
+        {
+            int prev_ret = ret;
+            ret += (str[i] - '0') * z;
+            if (ret < prev_ret)
+            {
+                ret = 2147483647;
+                break;
+            }
+            z *= 10;
+        }
+        else return 0;
+    }
+    if (negative) return -ret;
+    else return ret;
+}
+
+int strtol(const char *str, char **endptr, int base)
+{
+    int result = 0;
+    const char *ptr;
+    int negative = 0;
+    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
+    if (base < 2 || base > 36) return 0;
+
+    switch (*str)
+    {
+    case '-':
+        negative = 1;
+    case '+':
+        str++;
+        break;
+    }
+
+    for (ptr = str; *ptr; ptr++)
+    {
+        char *digit_ptr = strchr(digits, tolower(*ptr));
+        if (digit_ptr == NULL) break;
+
+        int digit = (int)(digit_ptr - digits);
+        if (digit >= base) break;
+
+        result *= base;
+        result += digit;
+    }
+
+    if (negative) result = -result;
+    if (endptr) *endptr = (char*)ptr;
+    return result;
+}
+
+unsigned long strtoul(const char *str, char **endptr, int base)
+{
+    unsigned long result = 0;
+    const char *ptr;
+    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
+    if (base < 2 || base > 36) return 0;
+
+    for (ptr = str; *ptr; ptr++)
+    {
+        char *digit_ptr = strchr(digits, tolower(*ptr));
+        if (digit_ptr == NULL) break;
+
+        int digit = (int)(digit_ptr - digits);
+        if (digit >= base || result > (ULONG_MAX / base)) break;
+
+        result *= base;
+        result += digit;
+    }
+
+    if (endptr) *endptr = (char*)ptr;
+    return result;
+}
+
+unsigned long long strtoull(const char *str, char **endptr, int base)
+{
+    unsigned long long result = 0;
+    const char *ptr;
+    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
+    if (base < 2 || base > 36) return 0;
+
+    for (ptr = str; *ptr; ptr++)
+    {
+        char *digit_ptr = strchr(digits, tolower(*ptr));
+        if (digit_ptr == NULL) break;
+
+        int digit = (int)(digit_ptr - digits);
+        if (digit >= base) break;
+        if (result > (ULONG_LONG_MAX / base)) break;
+
+        result *= (unsigned long long)base;
+        result += (unsigned long long)digit;
+    }
+
+    if (endptr) *endptr = (char*)ptr;
+    return result;
+}
diff --git a/crt/src/string.c b/crt/src/string.c
new file mode 100644 (file)
index 0000000..1d08d6a
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * string.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+char *strcpy(char *destination, const char *source)
+{
+    while (*source != 0) *(destination++) = *(source++);
+    *destination = 0;
+    return destination;
+}
+
+char *strncpy(char *destination, const char *source, uint32_t num)
+{
+    char *ptr = destination;
+    while ((num--) && (*source)) *(ptr++) = *(source++);
+    *ptr = 0;
+    return destination;
+}
+
+int strcmp(const char *str1, const char *str2)
+{
+    while (*str1 || *str2)
+    {
+        if (*str1 != *str2) break;
+        str1++;
+        str2++;
+    }
+
+    if (*str1 < *str2) return -1;
+    else if (*str1 > *str2) return 1;
+    else return 0;
+}
+
+int stricmp(const char *str1, const char *str2)
+{
+    while (*str1 || *str2)
+    {
+        if (tolower(*str1) != tolower(*str2)) break;
+        str1++;
+        str2++;
+    }
+    if (*str1 < *str2) return -1;
+    else if (*str1 > *str2) return 1;
+    else return 0;
+}
+
+int strncmp(const char *str1, const char *str2, size_t n)
+{
+    int i;
+
+    for (i = 0; i < n; i++)
+    {
+        if (str1[i] < str2[i]) return -1;
+        else if (str1[i] > str2[i]) return 1;
+        if (str1[i] == 0 || str2[i] == 0) break;
+    }
+
+    return 0;
+}
+
+char *strstr(const char *haystack, const char *needle)
+{
+    while (*haystack)
+    {
+        const char *s1 = haystack;
+        const char *s2 = needle;
+        int found = 1;
+
+        while (*s2)
+        {
+            if (*s1++ != *s2++)
+            {
+                found = 0;
+                break;
+            }
+        }
+
+        if (found) return (char*)haystack;
+        haystack++;
+    }
+
+    return NULL;
+}
+
+char *strchr(const char *str, char c)
+{
+    while ((*str != 0) && (*str != c)) str++;
+    if (*str == c) return (char*)str;
+    else return NULL;
+}
+
+char *strrchr(const char *str, char c)
+{
+    char *ret = NULL;
+
+    while (*str != 0)
+    {
+        if (*str == c) ret = (char*)str;
+        str++;
+    }
+
+    return ret;
+}
+
+char *strcat(char *destination, const char *source)
+{
+    strcpy(strchr(destination, '\0'), source);
+    return destination;
+}
+
+char *strncat(char *destination, const char *source, size_t n)
+{
+    char *ptr = strchr(destination, 0);
+    while ((n--) && (*source)) *(ptr++) = *(source++);
+    *ptr = 0;
+    return destination;
+}
+
+char *strdup(const char *source)
+{
+    char *destination = (char*)malloc(strlen(source) + 1);
+    if (destination) strcpy(destination, source);
+    return destination;
+}
+
+char *strtok(char *str, const char *delimiters, char **endptr)
+{
+    if (str == NULL) str = *endptr;
+    char *start = str;
+
+    while (*str != 0)
+    {
+        if (strchr(delimiters, *str) != NULL)
+        {
+            *str = 0;
+            *endptr = str + 1;
+            return start;
+        }
+
+        str++;
+    }
+
+    *endptr = str;
+    return start != str ? start : NULL;
+}
+
+size_t strlen(const char *str)
+{
+    int ret = 0;
+    while (str[ret] != 0) ret++;
+    return ret;
+}
+
+void strrev(char *str)
+{
+    size_t i, len = strlen(str);
+
+    for (i = 0; i < len / 2; i++)
+    {
+        int t = str[i];
+        str[i] = str[len - i - 1];
+        str[len - i - 1] = t;
+    }
+}
+
+void memset(void *ptr, uint8_t value, uint32_t size)
+{
+    uint32_t *p = ptr;
+    uint32_t tile = value | (value << 8) | (value << 16) | (value << 24);
+
+    while (size >= sizeof(uint32_t))
+    {
+        *p++ = tile;
+        size -= sizeof(uint32_t);
+    }
+
+    uint8_t *p_byte = (uint8_t*)p;
+    while (size--) *p_byte++ = value;
+}
+
+void memcpy(void *destination, const void *source, size_t n)
+{
+    uint8_t *src_byte = (uint8_t*)source;
+    uint8_t *dest_byte = (uint8_t*)destination;
+    if (!n) return;
+
+    if (n >> 2)
+    {
+        asm volatile ("cld\n"
+                      "rep movsd\n"
+                      : "=D"(dest_byte), "=S"(src_byte)
+                      : "D"(destination), "S"(source), "c"(n >> 2)
+                      : "cc", "memory");
+    }
+
+    switch (n & 3)
+    {
+    case 3:
+        *dest_byte++ = *src_byte++;
+    case 2:
+        *dest_byte++ = *src_byte++;
+    case 1:
+        *dest_byte++ = *src_byte++;
+    }
+}
+
+void memmove(void *destination, const void *source, size_t n)
+{
+    if (!n) return;
+
+    if (destination < source)
+    {
+        uint8_t *src_byte = (uint8_t*)source;
+        uint8_t *dest_byte = (uint8_t*)destination;
+
+        if (n >> 2)
+        {
+            asm volatile ("cld\n"
+                          "rep; movsd\n"
+                          : "=D"(dest_byte), "=S"(src_byte)
+                          : "D"(destination), "S"(source), "c"(n >> 2)
+                          : "cc", "memory");
+        }
+
+        switch (n & 3)
+        {
+        case 3:
+            *dest_byte++ = *src_byte++;
+        case 2:
+            *dest_byte++ = *src_byte++;
+        case 1:
+            *dest_byte++ = *src_byte++;
+        }
+    }
+    else if (destination > source)
+    {
+        uint8_t *src_byte = (uint8_t*)source + n;
+        uint8_t *dest_byte = (uint8_t*)destination + n;
+
+        switch (n & 3)
+        {
+        case 3:
+            *--dest_byte = *--src_byte;
+        case 2:
+            *--dest_byte = *--src_byte;
+        case 1:
+            *--dest_byte = *--src_byte;
+        }
+
+        if (n >> 2)
+        {
+            asm volatile ("std\n"
+                          "rep movsd\n"
+                          :
+                          : "D"(dest_byte - 4), "S"(src_byte - 4), "c"(n >> 2)
+                          : "cc", "memory");
+        }
+    }
+}
+
+int memcmp(const void *mem1, const void *mem2, size_t n)
+{
+    const uint8_t *p1 = (uint8_t*)mem1, *p2 = (uint8_t*)mem2;
+
+    while (n--)
+    {
+        if (*p1 < *p2) return -1;
+        else if (*p1 > *p2) return 1;
+
+        p1++;
+        p2++;
+    }
+
+    return 0;
+}
index 76932a0a71d74f988a7a920ddda4d9898fdee7bc..16c0d82d9fdfed3d1e38290ca707ce8103007ece 100644 (file)
@@ -34,9 +34,9 @@ DEPDIR = dep
 LIBGCC_DIR = $(shell $(CC) -print-file-name=)
 
 # Flags
-CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I include -I ..
+CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I include -I .. -I ../crt/include
 ASMFLAGS = -felf
-LDFLAGS = -T link.ld -L $(LIBGCC_DIR) -lgcc
+LDFLAGS = -T link.ld -L $(LIBGCC_DIR) -L ../crt -lgcc -lmlcrt
 
 ifeq ($(DEBUG), yes)
     CFLAGS += -g
index 8c1c24e4e0eb77eb5752ca97f7e8955a1f21a877..6cf9f1b2e045a98bd14c83b09fce4886ac636240 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef _COMMON_H_
 #define _COMMON_H_
 
+#include <stdlib.h>
+#include <string.h>
 #include <sdk/defs.h>
 
 /* Monolithium-specific Helper Macros */
@@ -138,31 +140,6 @@ static inline uintptr_t pop_from_stack(uintptr_t *stack)
     return value;
 }
 
-int strlen(const char *str);
-void strrev(char *str);
-char *strcpy(char *destination, const char *source);
-char *strcat(char *destination, const char *source);
-char *strncpy(char *destination, const char *source, dword_t num);
-int strcmp(const char *str1, const char *str2);
-char *strchr(const char *str, char c);
-char *strrchr(const char *str, char c);
-int strncmp(const char *str1, const char *str2, int length);
-char *strstr(const char *haystack, const char *needle);
-char *strtok(char *str, const char *delimiters, char **endptr);
-dword_t strtoul(const char *str, char **endptr, int base);
-qword_t strtoull(const char *str, char **endptr, int base);
-char *strdup(const char *source);
-int isprint(int c);
-int isdigit(int c);
-int isxdigit(int c);
-int isspace(int c);
-char tolower(char c);
-char toupper(char c);
-void memset(void *ptr, byte_t value, dword_t size);
-int memcmp(const void *mem1, const void *mem2, dword_t size);
-void memcpy(void *destination, const void *source, dword_t size);
-void memmove(void *destination, const void *source, dword_t size);
-char *itoa(int value, char *str, int base);
 void putchar(char character);
 void puts(const char *string);
 void clearscreen();
@@ -176,7 +153,5 @@ int sprintf(char *output, const char *format, ...);
 const char *get_error_string(dword_t err_code);
 int max(int a, int b);
 int min(int a, int b);
-void qsort(void *base, dword_t nmemb, dword_t size, int (*compare)(const void*, const void*));
-void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
 
 #endif
index f90b0bc803910f4906c7d1d6db22630b01e919a9..bfc57bc80e67996b1d88f18ccd375031a0844b98 100644 (file)
@@ -28,24 +28,6 @@ static byte_t terminal_color = 0x07;
 
 bool_t video_initialized = FALSE;
 
-int strlen(const char *str)
-{
-    int ret = 0;
-    while (str[ret] != 0) ret++;
-    return ret;
-}
-
-void strrev(char *str)
-{
-    int i, len = strlen(str);
-    for (i = 0; i < len / 2; i++)
-    {
-        int t = str[i];
-        str[i] = str[len - i - 1];
-        str[len - i - 1] = t;
-    }
-}
-
 const char *get_error_string(dword_t err_num)
 {
     static const char *error_strings[] = {
@@ -82,410 +64,6 @@ const char *get_error_string(dword_t err_num)
     return NULL;
 }
 
-char *itoa(int value, char *str, int base)
-{
-    int cnt = 0;
-    const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-    bool_t append_sign = FALSE;
-
-    if (base < 2 || base > 36) return NULL;
-
-    if (value == 0)
-    {
-        str[0] = '0';
-        str[1] = 0;
-        return str;
-    }
-
-    if (value < 0 && base == 10)
-    {
-        value = -value;
-        append_sign = TRUE;
-    }
-
-    dword_t u_value = (dword_t) value;
-
-    while (u_value > 0)
-    {
-        str[cnt++] = digits[u_value % base];
-        u_value /= base;
-    }
-
-    if (append_sign) str[cnt++] = '-';
-    str[cnt] = 0;
-    strrev(str);
-
-    return str;
-}
-
-int atoi(char *str)
-{
-    int i, len = strlen(str);
-    int ret = 0, z = 1;
-    bool_t negative = (str[0] == '-');
-
-    if (negative) str[0] = '0';
-
-    for (i = len - 1; i >= 0; i--)
-    {
-        if (str[i] >= '0' && str[i] <= '9')
-        {
-            int prev_ret = ret;
-            ret += (str[i] - '0') * z;
-            if (ret < prev_ret)
-            {
-                ret = 2147483647;
-                break;
-            }
-            z *= 10;
-        }
-        else return 0;
-    }
-    if (negative) return -ret;
-    else return ret;
-}
-
-int strtol(const char *str, char **endptr, int base)
-{
-    int result = 0;
-    const char *ptr;
-    bool_t negative = FALSE;
-    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
-    if (base < 2 || base > 36) return 0;
-
-    switch (*str)
-    {
-    case '-':
-        negative = TRUE;
-    case '+':
-        str++;
-        break;
-    }
-
-    for (ptr = str; *ptr; ptr++)
-    {
-        char *digit_ptr = strchr(digits, tolower(*ptr));
-        if (digit_ptr == NULL) break;
-
-        int digit = (int)(digit_ptr - digits);
-        if (digit >= base) break;
-
-        result *= base;
-        result += digit;
-    }
-
-    if (negative) result = -result;
-    if (endptr) *endptr = (char*)ptr;
-    return result;
-}
-
-dword_t strtoul(const char *str, char **endptr, int base)
-{
-    dword_t result = 0;
-    const char *ptr;
-    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
-    if (base < 2 || base > 36) return 0;
-
-    for (ptr = str; *ptr; ptr++)
-    {
-        char *digit_ptr = strchr(digits, tolower(*ptr));
-        if (digit_ptr == NULL) break;
-
-        int digit = (int)(digit_ptr - digits);
-        if (digit >= base || result > (DWORD_MAX / base)) break;
-
-        result *= base;
-        result += digit;
-    }
-
-    if (endptr) *endptr = (char*)ptr;
-    return result;
-}
-
-qword_t strtoull(const char *str, char **endptr, int base)
-{
-    qword_t result = 0;
-    const char *ptr;
-    const char *digits = "0123456789abcdefghijklmnopqrstuvxyz";
-    if (base < 2 || base > 36) return 0;
-
-    for (ptr = str; *ptr; ptr++)
-    {
-        char *digit_ptr = strchr(digits, tolower(*ptr));
-        if (digit_ptr == NULL) break;
-
-        int digit = (int)(digit_ptr - digits);
-        if (digit >= base) break;
-        if (result > (QWORD_MAX / base)) break;
-
-        result *= (qword_t)base;
-        result += (qword_t)digit;
-    }
-
-    if (endptr) *endptr = (char*)ptr;
-    return result;
-}
-
-void memset(void *ptr, byte_t value, dword_t size)
-{
-    dword_t *p = ptr;
-    dword_t tile = value | (value << 8) | (value << 16) | (value << 24);
-
-    while (size >= sizeof(dword_t))
-    {
-        *p++ = tile;
-        size -= sizeof(dword_t);
-    }
-
-    byte_t *p_byte = (byte_t*)p;
-    while (size--) *p_byte++ = value;
-}
-
-void memcpy(void *destination, const void *source, dword_t size)
-{
-    byte_t *src_byte = (byte_t*)source;
-    byte_t *dest_byte = (byte_t*)destination;
-    if (!size) return;
-
-    if (size >> 2)
-    {
-        asm volatile ("cld\n"
-                      "rep movsd\n"
-                      : "=D"(dest_byte), "=S"(src_byte)
-                      : "D"(destination), "S"(source), "c"(size >> 2)
-                      : "cc", "memory");
-    }
-
-    switch (size & 3)
-    {
-    case 3:
-        *dest_byte++ = *src_byte++;
-    case 2:
-        *dest_byte++ = *src_byte++;
-    case 1:
-        *dest_byte++ = *src_byte++;
-    }
-}
-
-void memmove(void *destination, const void *source, dword_t size)
-{
-    if (!size) return;
-
-    if (destination < source)
-    {
-        byte_t *src_byte = (byte_t*)source;
-        byte_t *dest_byte = (byte_t*)destination;
-
-        if (size >> 2)
-        {
-            asm volatile ("cld\n"
-                          "rep movsd\n"
-                          : "=D"(dest_byte), "=S"(src_byte)
-                          : "D"(destination), "S"(source), "c"(size >> 2)
-                          : "cc", "memory");
-        }
-
-        switch (size & 3)
-        {
-        case 3:
-            *dest_byte++ = *src_byte++;
-        case 2:
-            *dest_byte++ = *src_byte++;
-        case 1:
-            *dest_byte++ = *src_byte++;
-        }
-    }
-    else if (destination > source)
-    {
-        byte_t *src_byte = (byte_t*)source + size;
-        byte_t *dest_byte = (byte_t*)destination + size;
-
-        switch (size & 3)
-        {
-        case 3:
-            *--dest_byte = *--src_byte;
-        case 2:
-            *--dest_byte = *--src_byte;
-        case 1:
-            *--dest_byte = *--src_byte;
-        }
-
-        if (size >> 2)
-        {
-            asm volatile ("std\n"
-                          "rep movsd\n"
-                          :
-                          : "D"(dest_byte - 4), "S"(src_byte - 4), "c"(size >> 2)
-                          : "cc", "memory");
-        }
-    }
-}
-
-int memcmp(const void *mem1, const void *mem2, dword_t size)
-{
-    const byte_t *p1 = (byte_t*)mem1, *p2 = (byte_t*)mem2;
-
-    while (size--)
-    {
-        if (*p1 < *p2) return -1;
-        else if (*p1 > *p2) return 1;
-
-        p1++;
-        p2++;
-    }
-
-    return 0;
-}
-
-char *strcpy(char *destination, const char *source)
-{
-    while (*source != 0) *(destination++) = *(source++);
-    *destination = 0;
-    return destination;
-}
-
-int strcmp(const char *str1, const char *str2)
-{
-    while (*str1 || *str2)
-    {
-        if (*str1 != *str2) break;
-        str1++;
-        str2++;
-    }
-
-    if (*str1 < *str2) return -1;
-    else if (*str1 > *str2) return 1;
-    else return 0;
-}
-
-int isprint(int c)
-{
-    return c >= 0x20 && c <= 0x7E;
-}
-
-int isdigit(int c)
-{
-    return c >= '0' && c <= '9';
-}
-
-int isxdigit(int c)
-{
-    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-}
-
-int isspace(int c)
-{
-    return strchr(" \t\n\v\f\r", c) != NULL;
-}
-
-char tolower(char c)
-{
-    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
-    return c;
-}
-
-char toupper(char c)
-{
-    if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
-    return c;
-}
-
-int stricmp(const char *str1, const char *str2)
-{
-    while (*str1 || *str2)
-    {
-        if (tolower(*str1) != tolower(*str2)) break;
-        str1++;
-        str2++;
-    }
-    if (*str1 < *str2) return -1;
-    else if (*str1 > *str2) return 1;
-    else return 0;
-}
-
-int strncmp(const char *str1, const char *str2, int length)
-{
-    int i;
-    for (i = 0; i < length; i++)
-    {
-        if (str1[i] < str2[i]) return -1;
-        else if (str1[i] > str2[i]) return 1;
-        if (str1[i] == 0 || str2[i] == 0) break;
-    }
-    return 0;
-}
-
-char *strstr(const char *haystack, const char *needle)
-{
-    while (*haystack)
-    {
-        const char *s1 = haystack;
-        const char *s2 = needle;
-        bool_t found = TRUE;
-
-        while (*s2)
-        {
-            if (*s1++ != *s2++)
-            {
-                found = FALSE;
-                break;
-            }
-        }
-
-        if (found) return (char*)haystack;
-        haystack++;
-    }
-
-    return NULL;
-}
-
-char *strchr(const char *str, char c)
-{
-    while ((*str != 0) && (*str != c)) str++;
-    if (*str == c) return (char*)str;
-    else return NULL;
-}
-
-char *strrchr(const char *str, char c)
-{
-    char *ret = NULL;
-    while (*str != 0)
-    {
-        if (*str == c) ret = (char*)str;
-        str++;
-    }
-    return ret;
-}
-
-char *strcat(char *destination, const char *source)
-{
-    strcpy(strchr(destination, 0), source);
-    return destination;
-}
-
-char *strncpy(char *destination, const char *source, dword_t num)
-{
-    char *ptr = destination;
-    while ((num--) && (*source)) *(ptr++) = *(source++);
-    *ptr = 0;
-    return destination;
-}
-
-char *strncat(char *destination, const char *source, dword_t num)
-{
-    char *ptr = strchr(destination, 0);
-    while ((num--) && (*source)) *(ptr++) = *(source++);
-    *ptr = 0;
-    return destination;
-}
-
-char *strdup(const char *source)
-{
-    char *destination = (char*)malloc(strlen(source) + 1);
-    if (destination) strcpy(destination, source);
-    return destination;
-}
-
 void set_text_color(byte_t color)
 {
     terminal_color = color;
@@ -706,7 +284,7 @@ int vsnprintf(char *output, dword_t count, const char *format, va_list args)
             if (external_width) width = *va_arg(args, int*);
             if (external_precision) precision = *va_arg(args, int*);
 
-            if (strlen(num_buffer) < precision)
+            if ((int)strlen(num_buffer) < precision)
             {
                 int leading_zeros = precision - strlen(num_buffer);
                 memmove(&num_buffer[leading_zeros], &num_buffer[0], leading_zeros);
@@ -849,71 +427,7 @@ int printf(const char *format, ...)
     return ret;
 }
 
-char *strtok(char *str, const char *delimiters, char **endptr)
-{
-    if (str == NULL) str = *endptr;
-    char *start = str;
-
-    while (*str != 0)
-    {
-        if (strchr(delimiters, *str) != NULL)
-        {
-            *str = 0;
-            *endptr = str + 1;
-            return start;
-        }
-
-        str++;
-    }
-
-    *endptr = str;
-    return start != str ? start : NULL;
-}
-
 int abs(int x)
 {
     return (x < 0) ? -x : x;
 }
-
-void qsort(void *base, dword_t nmemb, dword_t size, int (*compare)(const void*, const void*))
-{
-    void *pivot = (void*)((uintptr_t)base + (nmemb / 2) * size);
-    void *temp = __builtin_alloca(size);
-    if (nmemb <= 1) return;
-
-    dword_t low = 0;
-    dword_t high = nmemb - 1;
-
-    while (TRUE)
-    {
-        while (compare((void*)((uintptr_t)base + low * size), pivot) < 0) low++;
-        while (compare((void*)((uintptr_t)base + high * size), pivot) > 0) high--;
-        if (low >= high) break;
-
-        memcpy(temp, (void*)((uintptr_t)base + low * size), size);
-        memcpy((void*)((uintptr_t)base + low * size), (void*)((uintptr_t)base + high * size), size);
-        memcpy((void*)((uintptr_t)base + high * size), temp, size);
-    }
-
-    qsort(base, high, size, compare);
-    qsort((void*)((dword_t)base + high * size), nmemb - high, size, compare);
-}
-
-void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
-{
-    long low = 0;
-    long high = nmemb - 1;
-
-    while (low <= high)
-    {
-        long mid = low + (high - low) / 2;
-        void *current = (void*)((uintptr_t)base + mid * size);
-        int comp = compare(current, key);
-
-        if (comp < 0) low = mid + 1;
-        else if (comp > 0) high = mid - 1;
-        else return current;
-    }
-
-    return NULL;
-}
index da5fb4ab06eed5c4635d3a71b0577cd3ea9d4b00..f3033dafc90ff43497d97cb5e0941867d0a383af 100644 (file)
@@ -22,7 +22,6 @@ DEBUG = yes
 # Compilers and tools
 CC = i686-elf-gcc
 ASM = nasm
-LINK = i686-elf-ld
 AR = i686-elf-ar
 
 # Directories
@@ -33,7 +32,6 @@ DEPDIR = dep
 # Flags
 CFLAGS = -Wall -Werror -ffreestanding -nostdlib -fPIC -I ..
 ASMFLAGS = -felf
-LDFLAGS = -shared
 
 ifeq ($(DEBUG), yes)
     CFLAGS += -g