Support basic libc function

meesbs
Marko Semet 2020-05-23 01:35:11 +02:00
parent 785af9373a
commit ed0d315ebb
16 changed files with 191 additions and 1 deletions

View File

@ -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 &&

View File

@ -0,0 +1,17 @@
#include <stddef.h>
#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

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -0,0 +1,6 @@
#include <stddef.h>
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);

2
bootstrap/libc/test/.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
*.test
libc.a

View File

@ -0,0 +1,3 @@
int main() {
return 0;
}

View File

@ -0,0 +1,3 @@
int main() {
return 1;
}

View File

@ -0,0 +1,3 @@
int main() {
return 2;
}

View File

@ -0,0 +1,30 @@
#! /usr/bin/env bash
# Args: <compiler>
# 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 )
)

View File

@ -0,0 +1,13 @@
#include <stddef.h>
#include <stdio.h>
int main() {
FILE* file = fopen("not_exists", "r");
if(file == NULL) {
return 0;
}
else {
return 1;
}
}

View File

@ -0,0 +1,13 @@
#include <stddef.h>
#include <stdio.h>
int main() {
FILE* file = fopen("fopen_success.c", "r");
if(file == NULL) {
return 1;
}
else {
return 0;
}
}

View File

@ -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)
)

View File

@ -0,0 +1,13 @@
#! /usr/bin/env bash
# Args: <compiler>
# 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"

View File

@ -0,0 +1,3 @@
#! /usr/bin/env sh
exec "$(dirname "$0")"/libc/test/test_x86_64.sh "gcc -nostdlib -g"