forked from Mirrors/tinycc
Support basic libc function
parent
785af9373a
commit
ed0d315ebb
|
@ -4,7 +4,7 @@ cd "$(dirname "$0")" &&
|
||||||
|
|
||||||
# Compile dietlibc
|
# Compile dietlibc
|
||||||
gcc -r -nostdlib -o libc.a -Ilibc/include -I../include \
|
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
|
# Build compiler
|
||||||
ln -fs base_config.h config.h &&
|
ln -fs base_config.h config.h &&
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.test
|
||||||
|
libc.a
|
|
@ -0,0 +1,3 @@
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
int main() {
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
int main() {
|
||||||
|
return 2;
|
||||||
|
}
|
|
@ -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 )
|
||||||
|
)
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
)
|
|
@ -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"
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /usr/bin/env sh
|
||||||
|
|
||||||
|
exec "$(dirname "$0")"/libc/test/test_x86_64.sh "gcc -nostdlib -g"
|
Loading…
Reference in New Issue