// An extremely minimalist syscalls.c for newlib // Based on riscv newlib libgloss/riscv/machine/syscall.h // Written by Clifford Wolf. #include #include #include #define UNIMPL_FUNC(_f) ".globl " #_f "\n.type " #_f ", @function\n" #_f ":\n" asm ( ".text\n" ".align 2\n" UNIMPL_FUNC(open) UNIMPL_FUNC(openat) UNIMPL_FUNC(lseek) UNIMPL_FUNC(stat) UNIMPL_FUNC(lstat) UNIMPL_FUNC(fstatat) UNIMPL_FUNC(isatty) UNIMPL_FUNC(access) UNIMPL_FUNC(faccessat) UNIMPL_FUNC(link) UNIMPL_FUNC(unlink) UNIMPL_FUNC(execve) UNIMPL_FUNC(getpid) UNIMPL_FUNC(fork) UNIMPL_FUNC(kill) UNIMPL_FUNC(wait) UNIMPL_FUNC(times) UNIMPL_FUNC(gettimeofday) UNIMPL_FUNC(ftime) UNIMPL_FUNC(utime) UNIMPL_FUNC(chown) UNIMPL_FUNC(chmod) UNIMPL_FUNC(chdir) UNIMPL_FUNC(getcwd) UNIMPL_FUNC(sysconf) "j unimplemented_syscall\n" ); void unimplemented_syscall() { const char *p = "Unimplemented system call called!\n"; while (*p) *(volatile int*)0x10000000 = *(p++); asm volatile ("ebreak"); __builtin_unreachable(); } ssize_t read(int file, void *ptr, size_t len) { // always EOF return 0; } ssize_t write(int file, const void *ptr, size_t len) { const void *eptr = ptr + len; while (ptr != eptr) *(volatile int*)0x10000000 = *(char*)(ptr++); return len; } int close(int file) { // close is called before _exit() return 0; } int fstat(int file, struct stat *st) { // fstat is called during libc startup errno = ENOENT; return -1; } void *sbrk(ptrdiff_t incr) { extern unsigned char _end[]; // Defined by linker static unsigned long heap_end; if (heap_end == 0) heap_end = (long)_end; heap_end += incr; return (void *)(heap_end - incr); } void _exit(int exit_status) { asm volatile ("ebreak"); __builtin_unreachable(); }