diff --git a/bootstrap/build_x86_64.sh b/bootstrap/build_x86_64.sh index 1059837..cc2c54d 100755 --- a/bootstrap/build_x86_64.sh +++ b/bootstrap/build_x86_64.sh @@ -4,7 +4,7 @@ cd "$(dirname "$0")" && # Compile dietlibc gcc -r -nostdlib -o libc.a -Ilibc/include -I../include \ - libc/src/cstring.c && + libc/src/cstring.c libc/src/cstdio.c libc/src/syscalls.c && # Build compiler ln -fs base_config.h config.h && diff --git a/bootstrap/libc/include/stdio.h b/bootstrap/libc/include/stdio.h new file mode 100644 index 0000000..ee160fe --- /dev/null +++ b/bootstrap/libc/include/stdio.h @@ -0,0 +1,17 @@ +#include + +#ifndef __STDIO_H__ +#define __STDIO_H__ + +// Type definitions +typedef void FILE; + +// Values +extern FILE* stdout; +extern FILE* stderr; +extern FILE* stdin; + +// Basic file handlers +extern FILE* fopen(const char* filename, const char* mode); + +#endif diff --git a/bootstrap/libc/src/base_x86_64.s b/bootstrap/libc/src/base_x86_64.s new file mode 100644 index 0000000..b41bf14 --- /dev/null +++ b/bootstrap/libc/src/base_x86_64.s @@ -0,0 +1,34 @@ +.global _start +.global __syscall + +.text +_start: + // Run main + call main + + // Exit process + mov %rax, %rdi + mov $60, %rax + syscall + +__syscall: + // Save the config (except rax) + push %rdi + push %rsi + push %rdx + push %r10 + + // Make the syscall + mov %rdi, %rax + mov %rsi, %rdi + mov %rdx, %rsi + mov %rcx, %rdx + mov %r8d, %r10d + syscall + + // Restore and return + pop %r10 + pop %rdx + pop %rsi + pop %rdi + retq diff --git a/bootstrap/libc/src/cstdio.c b/bootstrap/libc/src/cstdio.c new file mode 100644 index 0000000..a4ed7bf --- /dev/null +++ b/bootstrap/libc/src/cstdio.c @@ -0,0 +1,18 @@ +#include "syscalls.h" + +// File definition +typedef void FILE; + +// Values TODO: Make it correct +//FILE* stdout = 0; +//FILE* stderr = 1; +//FILE* stdin = 2; + +// Base file writer +FILE* fopen(const char* filename, const char* mode) { + int inode = open(filename, 0, 0x1a4); + if(inode < 0) { + return NULL; + } + return (FILE*) (size_t) inode; +} diff --git a/bootstrap/libc/src/syscalls.c b/bootstrap/libc/src/syscalls.c new file mode 100644 index 0000000..e621c11 --- /dev/null +++ b/bootstrap/libc/src/syscalls.c @@ -0,0 +1,18 @@ +#include "syscalls.h" + +#ifdef __x86_64__ + #define SYSCALL_READ 0 + #define SYSCALL_WRITE 1 + #define SYSCALL_OPEN 2 + #define SYSCALL_CLOSE 3 +#else + #error Unsupported architecture +#endif + +int open(const char* path, int flags, int mode) { + return __syscall(SYSCALL_OPEN, (size_t) path, (size_t) flags, (size_t) mode, + 0); +} +int close(int fd) { + return __syscall(SYSCALL_CLOSE, (size_t) fd, 0, 0, 0); +} diff --git a/bootstrap/libc/src/syscalls.h b/bootstrap/libc/src/syscalls.h new file mode 100644 index 0000000..059b149 --- /dev/null +++ b/bootstrap/libc/src/syscalls.h @@ -0,0 +1,6 @@ +#include + +extern volatile size_t __syscall(size_t code, size_t arg1, size_t arg2, + size_t arg3, size_t arg4); + +int open(const char* path, int flags, int mode); diff --git a/bootstrap/libc/test/.gitignore b/bootstrap/libc/test/.gitignore new file mode 100644 index 0000000..5adbec2 --- /dev/null +++ b/bootstrap/libc/test/.gitignore @@ -0,0 +1,2 @@ +*.test +libc.a diff --git a/bootstrap/libc/test/base/exit_0.c b/bootstrap/libc/test/base/exit_0.c new file mode 100644 index 0000000..33c14ce --- /dev/null +++ b/bootstrap/libc/test/base/exit_0.c @@ -0,0 +1,3 @@ +int main() { + return 0; +} diff --git a/bootstrap/libc/test/base/exit_1.c b/bootstrap/libc/test/base/exit_1.c new file mode 100644 index 0000000..6346e2d --- /dev/null +++ b/bootstrap/libc/test/base/exit_1.c @@ -0,0 +1,3 @@ +int main() { + return 1; +} diff --git a/bootstrap/libc/test/base/exit_2.c b/bootstrap/libc/test/base/exit_2.c new file mode 100644 index 0000000..5cca8e2 --- /dev/null +++ b/bootstrap/libc/test/base/exit_2.c @@ -0,0 +1,3 @@ +int main() { + return 2; +} diff --git a/bootstrap/libc/test/base/test.sh b/bootstrap/libc/test/base/test.sh new file mode 100755 index 0000000..40f7fc9 --- /dev/null +++ b/bootstrap/libc/test/base/test.sh @@ -0,0 +1,30 @@ +#! /usr/bin/env bash +# Args: + + +# Test exists +cd "$(dirname "$0")" && +( + echo TEST: exit_0 && + $1 -I../../../include -o exit_0.test exit_0.c ../libc.a && + ( + ./exit_0.test + if [ "$?" != "0" ]; then exit 1; fi + ) || ( echo FAILED; exit 1 ) +) && +( + echo TEST: exit_1 && + $1 -I../../../include -o exit_1.test exit_1.c ../libc.a && + ( + ./exit_1.test + if [ "$?" != "1" ]; then exit 1; fi + ) || ( echo FAILED; exit 1 ) +) && +( + echo TEST: exit_2 && + $1 -I../../../include -o exit_2.test exit_2.c ../libc.a && + ( + ./exit_2.test + if [ "$?" != "2" ]; then exit 1; fi + ) || ( echo FAILED; exit 1 ) +) diff --git a/bootstrap/libc/test/stdio/fopen_fail.c b/bootstrap/libc/test/stdio/fopen_fail.c new file mode 100644 index 0000000..1b9b341 --- /dev/null +++ b/bootstrap/libc/test/stdio/fopen_fail.c @@ -0,0 +1,13 @@ +#include +#include + + +int main() { + FILE* file = fopen("not_exists", "r"); + if(file == NULL) { + return 0; + } + else { + return 1; + } +} diff --git a/bootstrap/libc/test/stdio/fopen_success.c b/bootstrap/libc/test/stdio/fopen_success.c new file mode 100644 index 0000000..8965d9b --- /dev/null +++ b/bootstrap/libc/test/stdio/fopen_success.c @@ -0,0 +1,13 @@ +#include +#include + + +int main() { + FILE* file = fopen("fopen_success.c", "r"); + if(file == NULL) { + return 1; + } + else { + return 0; + } +} diff --git a/bootstrap/libc/test/stdio/test.sh b/bootstrap/libc/test/stdio/test.sh new file mode 100755 index 0000000..45b2aa0 --- /dev/null +++ b/bootstrap/libc/test/stdio/test.sh @@ -0,0 +1,14 @@ +#! /usr/bin/env bash + + +cd "$(dirname "$0")" && +( + echo TEST: fopen_fail + gcc -nostdlib -O0 -I ../../include -o fopen_fail.test fopen_fail.c ../libc.a && + ./fopen_fail.test || ( echo ERROR; exit 1) +) && +( + echo TEST: fopen_success + gcc -nostdlib -O0 -I ../../include -o fopen_success.test fopen_success.c ../libc.a && + ./fopen_success.test || ( echo ERROR; exit 1) +) diff --git a/bootstrap/libc/test/test_x86_64.sh b/bootstrap/libc/test/test_x86_64.sh new file mode 100755 index 0000000..88ca878 --- /dev/null +++ b/bootstrap/libc/test/test_x86_64.sh @@ -0,0 +1,13 @@ +#! /usr/bin/env bash +# Args: + + +# Build libc +cd "$(dirname "$0")" && +echo BUILD libc.a && +$1 -r -o libc.a -I../include \ + ../src/cstring.c ../src/cstdio.c ../src/syscalls.c ../src/base_x86_64.s && + +# Test +./base/test.sh "$1" && +./stdio/test.sh "$1" diff --git a/bootstrap/test_gcc_x86_64.sh b/bootstrap/test_gcc_x86_64.sh new file mode 100755 index 0000000..9c216cd --- /dev/null +++ b/bootstrap/test_gcc_x86_64.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env sh + +exec "$(dirname "$0")"/libc/test/test_x86_64.sh "gcc -nostdlib -g"