forked from Mirrors/tinycc
Support basic libc function
parent
785af9373a
commit
ed0d315ebb
|
@ -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 &&
|
||||
|
|
|
@ -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