diff --git a/Makefile b/Makefile index 0617481..e8b772f 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ O?=build STAGE=$(O)/stage KERNEL_HDRS?=kernel-hdr -CC=$(CROSS_COMPILE)gcc +CC=x86_64-elf-yggdrasil-gcc DIRS=$(O) \ $(O)/libc \ + $(O)/lib \ $(STAGE) HDRS=$(shell find $(S) -type f -name "*.h") STAGE_BIN=$(STAGE)/init \ @@ -13,38 +14,14 @@ STAGE_BIN=$(STAGE)/init \ $(STAGE)/bin/ls \ $(STAGE)/bin/reboot -CFLAGS=-ffreestanding \ - -nostdlib \ - -msse \ - -msse2 \ - -Ilibc/include \ - -ggdb \ - -O0 \ - -I$(KERNEL_HDRS) +usr_CFLAGS=-msse \ + -msse2 \ + -ggdb \ + -O0 \ + -ffreestanding -usr_LDFLAGS=-nostdlib \ - -lgcc \ - -Tlibc/program.ld -usr_STATIC_LIBS=$(O)/libc.a - -libc_CRTI=$(O)/libc/crti.o -libc_CRTN=$(O)/libc/crtn.o -libc_OBJS=$(O)/libc/crt0.o \ - $(O)/libc/syscall.o \ - $(O)/libc/vsnprintf.o \ - $(O)/libc/printf.o \ - $(O)/libc/string.o \ - $(O)/libc/errno.o \ - $(O)/libc/stdio.o \ - $(O)/libc/init.o \ - $(O)/libc/malloc.o \ - $(O)/libc/dirent.o \ - $(O)/libc/signal.o \ - $(O)/libc/global.o \ - $(O)/libc/time.o - -sys_CRTBEGIN=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o) -sys_CRTEND=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o) +usr_LDFLAGS=-lgcc \ + -static all: mkdirs $(O)/initrd.img @@ -59,39 +36,12 @@ mkdirs: mkstage-etc: mkdir -p $(STAGE)/dev $(STAGE)/mnt $(STAGE)/bin - chmod +x $(STAGE)/etc/file.txt cp -r etc $(STAGE) # Application building -$(STAGE)/init: init.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a +$(STAGE)/init: init.c @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) - @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ - $(libc_CRTI) \ - $(sys_CRTBEGIN) \ - init.c \ - $(sys_CRTEND) \ - $(libc_CRTN) \ - $(usr_STATIC_LIBS) + $(CC) -o $@ $(usr_CFLAGS) $(usr_LDFLAGS) init.c -$(STAGE)/bin/%: core/bin/%.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a - @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) - @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ - $(libc_CRTI) \ - $(sys_CRTBEGIN) \ - $< \ - $(sys_CRTEND) \ - $(libc_CRTN) \ - $(usr_STATIC_LIBS) - -# libc building -$(O)/libc.a: $(libc_OBJS) - @printf " AR\t%s\n" $(@:$(O)/%=%) - @$(AR) rcs $@ $(libc_OBJS) - -$(O)/libc/%.o: libc/%.c $(HDRS) - @printf " CC\t%s\n" $(@:$(O)/%=%) - @$(CC) -c -o $@ $(CFLAGS) $< - -$(O)/libc/%.o: libc/%.S - @printf " AS\t%s\n" $(@:$(O)/%=%) - @$(CC) -c -o $@ $(CFLAGS) $< +$(STAGE)/bin/%: core/bin/%.c + $(CC) -o $@ $(usr_CFLAGS) $(usr_LDFLAGS) $< diff --git a/init.c b/init.c index 410c6b2..78168bb 100644 --- a/init.c +++ b/init.c @@ -30,9 +30,6 @@ extern __attribute__((noreturn)) void abort(void); -#define assert(x) \ - if (!(x)) abort() - struct builtin { const char *name; const char *desc; diff --git a/libc/crt0.S b/libc/crt0.S deleted file mode 100644 index 9d23bfd..0000000 --- a/libc/crt0.S +++ /dev/null @@ -1,25 +0,0 @@ -.section .text -.global _start -.type _start, %function -// Arguments: -// %rdi - argp -_start: - movq $0, %rbp - // For callee linkage - pushq %rbp - pushq %rbp - movq %rsp, %rbp - - push %rdi - call __libc_init - - call _init - - mov __libc_argc, %rdi - pop %rsi - - // exit(main(argc, argv)) - call main - movq %rax, %rdi - call exit -.size _start, . - _start diff --git a/libc/crti.S b/libc/crti.S deleted file mode 100644 index a85782e..0000000 --- a/libc/crti.S +++ /dev/null @@ -1,16 +0,0 @@ -/* x86_64 crti.s */ -.section .init -.global _init -.type _init, @function -_init: - push %rbp - movq %rsp, %rbp - /* gcc will nicely put the contents of crtbegin.o's .init section here. */ - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %rbp - movq %rsp, %rbp - /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/libc/crtn.S b/libc/crtn.S deleted file mode 100644 index b446d9f..0000000 --- a/libc/crtn.S +++ /dev/null @@ -1,10 +0,0 @@ -/* x86_64 crtn.s */ -.section .init - /* gcc will nicely put the contents of crtend.o's .init section here. */ - popq %rbp - ret - -.section .fini - /* gcc will nicely put the contents of crtend.o's .fini section here. */ - popq %rbp - ret diff --git a/libc/dirent.c b/libc/dirent.c deleted file mode 100644 index 73969e7..0000000 --- a/libc/dirent.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "dirent.h" -#include "bits/syscall.h" -#include -#include -#include - -extern void *malloc(size_t count); -extern void free(void *p); - -struct DIR_private { - int fd; - struct dirent buf; -}; - -DIR *opendir(const char *path) { - int fd; - DIR *res; - - if (!(res = malloc(sizeof(struct DIR_private)))) { - errno = ENOMEM; - return NULL; - } - - - if ((fd = open(path, O_DIRECTORY | O_RDONLY, 0)) < 0) { - fd = errno; - free(res); - errno = fd; - // errno is set - return NULL; - } - - res->fd = fd; - memset(&res->buf, 0, sizeof(res->buf)); - - return res; -} - -void closedir(DIR *dirp) { - if (!dirp) { - return; - } - close(dirp->fd); - free(dirp); -} - -struct dirent *readdir(DIR *dirp) { - ssize_t res; - if (!dirp) { - errno = EBADF; - return NULL; - } - if ((res = sys_readdir(dirp->fd, &dirp->buf)) <= 0) { - return NULL; - } - return &dirp->buf; -} diff --git a/libc/errno.c b/libc/errno.c deleted file mode 100644 index 941c59a..0000000 --- a/libc/errno.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -static const char *err_strings0[35] = { - "Success", - "Operation not permitted", - "No such file or directory", - "No such process", - "Interrupted system call", - "I/O error", - "No such device or address", - "Argument list too long", - "Exec format error", - "Bad file number", - "No child processes", - "Try again", - "Out of memory", - "Permission denied", - "Bad address", - "Block device required", - "Device or resource busy", - "File exists", - "Cross-device link", - "No such device", - "Not a directory", - "Is a directory", - "Invalid argument", - "File table overflow", - "Too many open files", - "Not a typewriter", - "Text file busy", - "File too large", - "No space left on device", - "Illegal seek", - "Read-only file system", - "Too many links", - "Broken pipe", - "Math argument out of domain of func", - "Math result not representable" -}; - -int errno; - -char *strerror(int n) { - if (n >= 0 && n <= 34) { - return (char *) err_strings0[n]; - } - return (char *) "Unknown error"; -} - -void perror(const char *e) { - if (e && *e) { - printf("%s: %s\n", e, strerror(errno)); - } else { - puts(strerror(errno)); - } -} diff --git a/libc/global.c b/libc/global.c deleted file mode 100644 index 1c04fb7..0000000 --- a/libc/global.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "bits/global.h" - -void *__cur_brk; -uint64_t __libc_argc = 0; diff --git a/libc/include/bits/global.h b/libc/include/bits/global.h deleted file mode 100644 index 6b0435b..0000000 --- a/libc/include/bits/global.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include - -extern void *__cur_brk; -extern uint64_t __libc_argc; diff --git a/libc/include/bits/printf.h b/libc/include/bits/printf.h deleted file mode 100644 index 68ffd26..0000000 --- a/libc/include/bits/printf.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include -#include - -int printf(const char *fmt, ...); -int snprintf(char *buf, size_t size, const char *fmt, ...); -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); diff --git a/libc/include/bits/syscall.h b/libc/include/bits/syscall.h deleted file mode 100644 index 81ec6c7..0000000 --- a/libc/include/bits/syscall.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -ssize_t read(int fd, void *buf, size_t count); -ssize_t write(int fd, const void *buf, size_t count); -int open(const char *filename, int flags, int mode); -void close(int fd); -int stat(const char *filename, struct stat *st); -void *mmap(void *addr, size_t len, int prot, int flags, int fd, uintptr_t offset); -int fork(void); -int execve(const char *filename, const char *const argv[], const char *const envp[]); -ssize_t sys_readdir(int fd, struct dirent *entp); -int kill(int pid, int signum); -void __kernel_signal(uintptr_t handler); -__attribute__((noreturn)) void __kernel_sigret(void); -int getpid(void); -int chdir(const char *filename); -char *getcwd(char *buf, size_t size); -int nanosleep(const struct timespec *req, struct timespec *rem); -int openpty(int *amaster, int *aslave); -int gettimeofday(struct timeval *tv, struct timezone *tz); -int reboot(int magic1, int magic2, unsigned int cmd, void *arg); -int access(const char *filename, int mode); -int waitpid(int pid, int *status); -int unlink(const char *pathname); -int mkdir(const char *pathname, int mode); -int creat(const char *pathname, int mode); -int rmdir(const char *pathname); -int mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data); -int setuid(uid_t uid); -int setgid(gid_t gid); -uid_t getuid(void); -gid_t getgid(void); -int chmod(const char *path, mode_t mode); -int chown(const char *path, uid_t uid, gid_t gid); - -__attribute__((noreturn)) void exit(int code); diff --git a/libc/include/dirent.h b/libc/include/dirent.h deleted file mode 100644 index adb5774..0000000 --- a/libc/include/dirent.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -typedef struct DIR_private DIR; - -DIR *opendir(const char *path); -void closedir(DIR *dirp); -struct dirent *readdir(DIR *dirp); diff --git a/libc/include/errno.h b/libc/include/errno.h deleted file mode 100644 index d85454b..0000000 --- a/libc/include/errno.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include - -extern int errno; - -char *strerror(int errnum); -void perror(const char *s); diff --git a/libc/include/signal.h b/libc/include/signal.h deleted file mode 100644 index 0e1c34f..0000000 --- a/libc/include/signal.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -typedef void (*sighandler_t) (int); - -sighandler_t signal(int signum, sighandler_t handler); - -int raise(int signum); diff --git a/libc/include/stdio.h b/libc/include/stdio.h deleted file mode 100644 index c89bef8..0000000 --- a/libc/include/stdio.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -int puts(const char *s); -int putchar(int c); - -#include "bits/printf.h" diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h deleted file mode 100644 index 46de31c..0000000 --- a/libc/include/stdlib.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void abort(void); diff --git a/libc/include/string.h b/libc/include/string.h deleted file mode 100644 index 0d57aa0..0000000 --- a/libc/include/string.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include - -void *memcpy(void *restrict dst, const void *restrict src, size_t cnt); -void *memmove(void *dst, const void *src, size_t cnt); -void *memset(void *dst, int v, size_t count); -int memcmp(const void *a, const void *b, size_t count); - -size_t strlen(const char *s); -int strncmp(const char *a, const char *b, size_t lim); -int strcmp(const char *a, const char *b); -char *strchr(const char *a, int c); -char *strrchr(const char *a, int c); -char *strcpy(char *dst, const char *src); -char *strncpy(char *dst, const char *src, size_t lim); -char *strcat(char *dst, const char *src); -char *strncat(char *dst, const char *src, size_t lim); diff --git a/libc/include/time.h b/libc/include/time.h deleted file mode 100644 index 2bfead5..0000000 --- a/libc/include/time.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -int usleep(long us); diff --git a/libc/include/unistd.h b/libc/include/unistd.h deleted file mode 100644 index 5485295..0000000 --- a/libc/include/unistd.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "bits/syscall.h" -#include - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -void *sbrk(intptr_t diff); -int reboot(int magic1, int magic2, unsigned int cmd, void *arg); diff --git a/libc/init.c b/libc/init.c deleted file mode 100644 index 77cd98c..0000000 --- a/libc/init.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "bits/global.h" - -extern char __heap_start; -extern void __libc_signal_init(void); -static const char *argp_dummy[] = { 0 }; - -void __libc_init(char **argp) { - __libc_signal_init(); - __libc_argc = 0; - if (argp) { - while (argp[__libc_argc]) { - ++__libc_argc; - } - } - __cur_brk = &__heap_start; - errno = 0; -} diff --git a/libc/malloc.c b/libc/malloc.c deleted file mode 100644 index 49c2a9c..0000000 --- a/libc/malloc.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "bits/global.h" - -// XXX: I'll implement a proper heap in the following commits -void *malloc(size_t count) { - void *p = __cur_brk; - if (sbrk(count) == p) { - return NULL; - } - return p; -} - -void free(void *ptr) { - -} diff --git a/libc/printf.c b/libc/printf.c deleted file mode 100644 index 0bcaaec..0000000 --- a/libc/printf.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "bits/printf.h" -#include -#define PRINTF_BUFFER_SIZE 1024 - -int printf(const char *fmt, ...) { - char buf[PRINTF_BUFFER_SIZE]; - va_list args; - va_start(args, fmt); - int res = vsnprintf(buf, PRINTF_BUFFER_SIZE, fmt, args); - va_end(args); - - // TODO: use libc's FILE * instead - return write(STDOUT_FILENO, buf, res); -} - -int snprintf(char *buf, size_t lim, const char *fmt, ...) { - va_list args; - int res; - - va_start(args, fmt); - res = vsnprintf(buf, PRINTF_BUFFER_SIZE, fmt, args); - va_end(args); - - return res; -} diff --git a/libc/program.ld b/libc/program.ld deleted file mode 100644 index f7d68df..0000000 --- a/libc/program.ld +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Userspace program linker script, - * partially derived from GCC's -static one - */ -ENTRY(_start) - -SECTIONS { - . = 0x400000; - - .text : ALIGN(4K) { - KEEP (*(SORT_NONE(.init))) - *(.text) - KEEP (*(SORT_NONE(.fini))) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - - .rodata : { - *(.rodata) - *(.eh_frame) - } - - .data : ALIGN(4K) { - *(.data) - } - - .bss : ALIGN(4K) { - *(.bss) - } - - __program_end = .; - __heap_start = .; -} diff --git a/libc/signal.c b/libc/signal.c deleted file mode 100644 index c42dfb1..0000000 --- a/libc/signal.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include - -static sighandler_t signal_handlers[16] = {0}; - -void SIG_IGN(int signum) { - printf("Ignored: %d\n", signum); - - while (1); -} - -void SIG_DFL(int signum) { - int pid = getpid(); - - switch (signum) { - case SIGKILL: - printf("%d: killed\n", pid); - break; - case SIGABRT: - printf("%d: aborted\n", pid); - break; - case SIGSEGV: - printf("%d: segmentation fault\n", pid); - break; - default: - printf("%d: signal %d\n", pid, signum); - break; - } - - exit(1); -} - -static void __libc_signal_handle(int signum) { - if (signum >= 16) { - SIG_DFL(signum); - } else { - signal_handlers[signum](signum); - } - - __kernel_sigret(); -} - -void __libc_signal_init(void) { - for (size_t i = 0; i < 16; ++i) { - signal_handlers[i] = SIG_DFL; - } - - __kernel_signal((uintptr_t) __libc_signal_handle); -} - -sighandler_t signal(int signum, sighandler_t new_handler) { - sighandler_t old_handler; - - if (signum >= 16) { - printf("Fuck\n"); - exit(1); - } - - old_handler = signal_handlers[signum]; - signal_handlers[signum] = new_handler; - return old_handler; -} - -int raise(int signum) { - return kill(getpid(), signum); -} - -void abort(void) { - kill(getpid(), SIGABRT); -} diff --git a/libc/stdio.c b/libc/stdio.c deleted file mode 100644 index e22aaf2..0000000 --- a/libc/stdio.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int puts(const char *s) { - size_t l = strlen(s); - int w = write(STDOUT_FILENO, s, l); - char c = '\n'; - - if (w == l) { - write(STDOUT_FILENO, &c, 1); - } - return w; -} - -int putchar(int c) { - int res; - if ((res = write(STDOUT_FILENO, &c, 1)) < 0) { - return res; - } - return c; -} diff --git a/libc/string.c b/libc/string.c deleted file mode 100644 index c4d835d..0000000 --- a/libc/string.c +++ /dev/null @@ -1,167 +0,0 @@ -#include - -char *strcat(char *dst, const char *src) { - size_t l = strlen(dst); - strcpy(dst + l, src); - return dst; -} - -char *strncat(char *dst, const char *src, size_t lim) { - size_t l = strlen(dst); - if (l < lim) { - return dst; - } - size_t r = lim - l; - strncpy(dst + l, src, r); - return dst; -} - -size_t strlen(const char *a) { - size_t s = 0; - while (*a++) { - ++s; - } - return s; -} - -int strncmp(const char *a, const char *b, size_t n) { - size_t c = 0; - for (; c < n && (*a || *b); ++c, ++a, ++b) { - if (*a != *b) { - return -1; - } - } - return 0; -} - -int strcmp(const char *a, const char *b) { - if (a == b) { - return 0; - } - if (a == NULL || b == NULL) { - return -1; - } - for (; *a || *b; ++a, ++b) { - if (*a != *b) { - return 1; - } - } - return 0; -} - -char *strcpy(char *dst, const char *src) { - size_t i; - for (i = 0; src[i]; ++i) { - dst[i] = src[i]; - } - dst[i] = 0; - return dst; -} - -char *strncpy(char *dst, const char *src, size_t lim) { - size_t i = 0; - while (i < lim) { - if (!src[i]) { - dst[i] = 0; - return dst; - } - dst[i] = src[i]; - ++i; - } - return dst; -} - -char *strchr(const char *s, int c) { - while (*s) { - if (*s == (char) c) { - return (char *) s; - } - ++s; - } - return NULL; -} - -char *strrchr(const char *s, int c) { - ssize_t l = (ssize_t) strlen(s); - if (!l) { - return NULL; - } - while (l >= 0) { - if (s[l] == (char) c) { - return (char *) &s[l]; - } - --l; - } - return NULL; -} - -int memcmp(const void *a, const void *b, size_t n) { - const char *l = a; - const char *r = b; - for (; n && *l == *r; --n, ++l, ++r); - return n ? *l - *r : 0; -} - -void *memmove(void *dest, const void *src, size_t n) { - char *d = dest; - const char *s = src; - - if (d == s) { - return d; - } - - if ((s + n) <= d || (d + n) <= s) { - return memcpy(d, s, n); - } - - if (d < s) { - if (((uintptr_t) s) % sizeof(size_t) == ((uintptr_t) d) % sizeof(size_t)) { - while (((uintptr_t) d) % sizeof(size_t)) { - if (!n--) { - return dest; - } - *d++ = *s++; - } - for (; n >= sizeof(size_t); n -= sizeof(size_t), d += sizeof(size_t), s += sizeof(size_t)) { - *((size_t *) d) = *((size_t *) s); - } - } - for (; n; n--) { - *d++ = *s++; - } - } else { - if (((uintptr_t) s) % sizeof(size_t) == ((uintptr_t) d) % sizeof(size_t)) { - while (((uintptr_t) (d + n)) % sizeof(size_t)) { - if (!n--) { - return dest; - } - d[n] = s[n]; - } - while (n >= sizeof(size_t)) { - n -= sizeof(size_t); - *((size_t *) (d + n)) = *((size_t *) (s + n)); - } - } - while (n) { - n--; - d[n] = s[n]; - } - } - - return dest; -} - -void *memset(void *blk, int v, size_t sz) { - for (size_t i = 0; i < sz; ++i) { - ((char *) blk)[i] = v; - } - return blk; -} - -void *memcpy(void *dst, const void *src, size_t sz) { - for (size_t i = 0; i < sz; ++i) { - ((char *) dst)[i] = ((const char *) src)[i]; - } - return dst; -} - diff --git a/libc/syscall.c b/libc/syscall.c deleted file mode 100644 index 415ea36..0000000 --- a/libc/syscall.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "bits/syscall.h" -#include "bits/global.h" -#include - -#define ASM_REGISTER(name) \ - register uint64_t name asm (#name) - -#define ASM_SYSCALL0(r0) ({ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory"); \ - rax; \ - }) - -#define ASM_SYSCALL1(r0, r1) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory"); \ - rax; \ - }) - -#define ASM_SYSCALL2(r0, r1, r2) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx"); \ - rax; \ - }) - -#define ASM_SYSCALL3(r0, r1, r2, r3) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - ASM_REGISTER(rdx) = (uint64_t) (r3); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx"); \ - rax; \ - }) - -#define ASM_SYSCALL4(r0, r1, r2, r3, r4) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - ASM_REGISTER(rdx) = (uint64_t) (r3); \ - ASM_REGISTER(r10) = (uint64_t) (r4); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx", "r10"); \ - rax; \ - }) - -#define ASM_SYSCALL5(r0, r1, r2, r3, r4, r5) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - ASM_REGISTER(rdx) = (uint64_t) (r3); \ - ASM_REGISTER(r10) = (uint64_t) (r4); \ - ASM_REGISTER( r8) = (uint64_t) (r5); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx", "r10", "r8"); \ - rax; \ - }) - -#define SET_ERRNO(t, r) ({ \ - t res = (t) r; \ - if (res < 0) { \ - errno = -res; \ - } \ - ((int) res) < 0 ? (t) -1 : res; \ - }) - -ssize_t write(int fd, const void *buf, size_t count) { - return SET_ERRNO(ssize_t, ASM_SYSCALL3(SYSCALL_NR_WRITE, fd, buf, count)); -} - -ssize_t read(int fd, void *buf, size_t count) { - return SET_ERRNO(ssize_t, ASM_SYSCALL3(SYSCALL_NR_READ, fd, buf, count)); -} - -ssize_t sys_readdir(int fd, struct dirent *entp) { - return SET_ERRNO(ssize_t, ASM_SYSCALL2(SYSCALL_NR_READDIR, fd, entp)); -} - -int open(const char *filename, int flags, int mode) { - return SET_ERRNO(int, ASM_SYSCALL3(SYSCALL_NR_OPEN, filename, flags, mode)); -} - -void close(int fd) { - (void) ASM_SYSCALL1(SYSCALL_NR_CLOSE, fd); -} - -int stat(const char *filename, struct stat *st) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_STAT, filename, st)); -} - -int brk(void *addr) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_BRK, addr)); -} - -int fork(void) { - return SET_ERRNO(int, ASM_SYSCALL0(SYSCALL_NR_FORK)); -} - -int execve(const char *filename, const char *const argv[], const char *const envp[]) { - return SET_ERRNO(int, ASM_SYSCALL3(SYSCALL_NR_EXECVE, filename, argv, envp)); -} - -__attribute__((noreturn)) void exit(int code) { - (void) ASM_SYSCALL1(SYSCALL_NR_EXIT, code); - while (1); -} - -int kill(int pid, int signum) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_KILL, pid, signum)); -} - -void __kernel_signal(uintptr_t entry) { - (void) ASM_SYSCALL1(SYSCALL_NRX_SIGNAL, entry); -} - -__attribute__((noreturn)) void __kernel_sigret(void) { - (void) ASM_SYSCALL0(SYSCALL_NRX_SIGRET); - while (1); -} - -int getpid(void) { - return ASM_SYSCALL0(SYSCALL_NR_GETPID); -} - -int chdir(const char *filename) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_CHDIR, filename)); -} - -char *getcwd(char *buf, size_t lim) { - if (SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_GETCWD, buf, lim)) == 0) { - return buf; - } else { - return NULL; - } -} - -int nanosleep(const struct timespec *req, struct timespec *rem) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_NANOSLEEP, req, rem)); -} - -int openpty(int *master, int *slave) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NRX_OPENPTY, master, slave)); -} - -int gettimeofday(struct timeval *tv, struct timezone *tz) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_GETTIMEOFDAY, tv, tz)); -} - -int reboot(int magic1, int magic2, unsigned int cmd, void *arg) { - return SET_ERRNO(int, ASM_SYSCALL4(SYSCALL_NR_REBOOT, magic1, magic2, cmd, arg)); -} - -int access(const char *filename, int mode) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_ACCESS, filename, mode)); -} - -int waitpid(int pid, int *status) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NRX_WAITPID, pid, status)); -} - -int mkdir(const char *pathname, int mode) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_MKDIR, pathname, mode)); -} - -int unlink(const char *pathname) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_UNLINK, pathname)); -} - -int rmdir(const char *pathname) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_RMDIR, pathname)); -} - -int mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data) { - return SET_ERRNO(int, ASM_SYSCALL5(SYSCALL_NR_MOUNT, dev_name, dir_name, type, flags, data)); -} - -int setuid(uid_t uid) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_SETUID, uid)); -} - -int setgid(gid_t gid) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_SETGID, gid)); -} - -uid_t getuid(void) { - return (uid_t) ASM_SYSCALL0(SYSCALL_NR_GETUID); -} - -gid_t getgid(void) { - return (gid_t) ASM_SYSCALL0(SYSCALL_NR_GETGID); -} - -int chmod(const char *path, mode_t mode) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_CHMOD, path, mode)); -} - -int chown(const char *path, uid_t uid, gid_t gid) { - return SET_ERRNO(int, ASM_SYSCALL3(SYSCALL_NR_CHOWN, path, uid, gid)); -} - -// Although sbrk() is implemented in userspace, I guess it should also be here -void *sbrk(intptr_t inc) { - if (inc == 0) { - return __cur_brk; - } - - void *new_brk = (void *) ((uintptr_t) __cur_brk + inc); - - if (brk(new_brk) != 0) { - return __cur_brk; - } else { - return __cur_brk = new_brk; - } -} diff --git a/libc/time.c b/libc/time.c deleted file mode 100644 index f75a68a..0000000 --- a/libc/time.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "time.h" -#include "bits/syscall.h" - -int usleep(long us) { - struct timespec tv = { us / 1000000, (us % 1000) * 1000 }; - return nanosleep(&tv, NULL); -} diff --git a/libc/vsnprintf.c b/libc/vsnprintf.c deleted file mode 100644 index 5370763..0000000 --- a/libc/vsnprintf.c +++ /dev/null @@ -1,255 +0,0 @@ -#include "bits/printf.h" -#include -#include - -union printfv { - int value_int; - unsigned int value_uint; - long value_long; - uint32_t value_uint32; - uint64_t value_uint64; - uintptr_t value_ptr; - const char *value_str; -}; - -static const char *s_print_xs_set0 = "0123456789abcdef"; -static const char *s_print_xs_set1 = "0123456789ABCDEF"; - -static int vsnprintf_ds(int64_t x, char *res, int s, int sz) { - if (!x) { - res[0] = '0'; - res[1] = 0; - return 1; - } - - int c; - uint64_t v; - - if (sz) { - if (s && x < 0) { - v = (uint64_t) -x; - } else { - s = 0; - v = (uint64_t) x; - } - } else { - if (s && ((int32_t) x) < 0) { - v = (uint64_t) -((int32_t) x); - } else { - s = 0; - v = (uint64_t) x; - } - } - - c = 0; - - while (v) { - res[c++] = '0' + v % 10; - v /= 10; - } - - if (s) { - res[c++] = '-'; - } - - res[c] = 0; - - for (int i = 0, j = c - 1; i < j; ++i, --j) { - res[i] ^= res[j]; - res[j] ^= res[i]; - res[i] ^= res[j]; - } - - return c; -} - -static int vsnprintf_xs(uint64_t v, char *res, const char *set) { - if (!v) { - res[0] = '0'; - res[1] = 0; - return 1; - } - - int c = 0; - - while (v) { - res[c++] = set[v & 0xF]; - v >>= 4; - } - - res[c] = 0; - - for (int i = 0, j = c - 1; i < j; ++i, --j) { - res[i] ^= res[j]; - res[j] ^= res[i]; - res[i] ^= res[j]; - } - - return c; -} - - - -int vsnprintf(char *buf, size_t len, const char *fmt, va_list args) { - union printfv val; - char cbuf[64]; - size_t p = 0; - // padn > 0: - // --------vvvvv - // padn < 0: - // vvvv---------- - int padn; - char padc; - int pads; - int clen; - char c; - -#define __putc(ch) \ - if (p == len - 1) { \ - goto __end; \ - } else { \ - buf[p++] = ch; \ - } - -#define __puts(s, l) \ - if (padn >= 0) { \ - if (l < padn) { \ - size_t padd = padn - l; \ - if (p + padd < len + 1) { \ - memset(buf + p, padc, padd); \ - p += padd; \ - } else { \ - memset(buf + p, padc, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } \ - if (p + l < len + 1) { \ - strncpy(buf + p, s, l); \ - p += l; \ - } else { \ - strncpy(buf + p, s, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } else { \ - padn = -padn; \ - if (p + l < len + 1) { \ - strncpy(buf + p, s, l); \ - p += l; \ - } else { \ - strncpy(buf + p, s, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - if (l < padn) { \ - size_t padd = padn - l; \ - if (p + padd < len + 1) { \ - memset(buf + p, padc, padd); \ - p += padd; \ - } else { \ - memset(buf + p, padc, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } \ - } - - while ((c = *fmt)) { - switch (c) { - case '%': - c = *++fmt; - padn = 0; - padc = ' '; - pads = 1; - - if (c == '0') { - padc = c; - c = *++fmt; - } - if (c == '-') { - pads = -1; - c = *++fmt; - } - - while (c >= '0' && c <= '9') { - padn *= 10; - padn += c - '0'; - c = *++fmt; - } - - padn *= pads; - - switch (c) { - case 'l': - // Not supported - return -1; - - case 's': - if ((val.value_str = va_arg(args, const char *))) { - __puts(val.value_str, strlen(val.value_str)); - } else { - __puts("(null)", 6); - } - break; - - case 'p': - val.value_ptr = va_arg(args, uintptr_t); - __putc('0'); - __putc('x'); - padn = sizeof(uintptr_t) * 2; - padc = '0'; - clen = vsnprintf_xs(val.value_ptr, cbuf, s_print_xs_set0); - __puts(cbuf, clen); - break; - - case 'i': - case 'd': - val.value_int = va_arg(args, int); - clen = vsnprintf_ds(val.value_int, cbuf, 1, 1); - __puts(cbuf, clen); - break; - case 'u': - val.value_uint = va_arg(args, unsigned int); - clen = vsnprintf_ds(val.value_uint, cbuf, 0, 1); - __puts(cbuf, clen); - break; - - case 'x': - val.value_uint32 = va_arg(args, uint32_t); - clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set0); - __puts(cbuf, clen); - break; - case 'X': - val.value_uint32 = va_arg(args, uint32_t); - clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set1); - __puts(cbuf, clen); - break; - - case 'c': - val.value_int = va_arg(args, int); - __putc(val.value_int); - break; - - default: - __putc('%'); - __putc(c); - break; - } - - break; - default: - __putc(c); - break; - } - - ++fmt; - } - -#undef __puts -#undef __putc - -__end: - buf[p] = 0; - return p; -}