/* * @author xamidev * @brief System call wrappers for userspace * @license GPL-3.0-only */ #pragma once // TODO: replace all ifndef/define/endif by pragma once.. #include #include // 3-args syscall static inline long syscall3(long n, long a, long b, long c) { long ret; __asm__ volatile ( "int $0x80" : "=a"(ret) : "a"(n), "D"(a), "S"(b), "d"(c) // a = rax, D = rdi, S = rsi, d = rdx : "memory" ); return ret; } // 4-args syscall static inline long syscall4(long n, long a, long b, long c, long d) { long ret; register long r10 __asm__("r10") = d; __asm__ volatile ( "int $0x80" : "=a"(ret) : "a"(n), "D"(a), "S"(b), "d"(c), "r"(r10) : "memory" ); return ret; } // Single-arg syscall static inline long syscall1(long n, long a) { return syscall3(n, a, 0, 0); } static inline int write(int fd, const char* buf, long len) { return (int)syscall3(1, fd, (long)buf, len); } static inline int read(int fd, char* buf, long len) { return (int)syscall3(0, fd, (long)buf, len); } static inline int open(const char* path, int flags) { return (int)syscall3(2, (long)path, flags, 0); } static inline int close(unsigned int fd) { return (int)syscall3(3, fd, 0, 0); } static inline int seek(int fd, int offset, int whence) { return (int)syscall3(8, fd, offset, whence); } static inline int tell(unsigned int fd) { return (int)syscall1(9, fd); } static inline int eof(unsigned int fd) { return (int)syscall1(10, fd); } static inline int draw(const unsigned char* buf, int width, int height, int channels) { return (int)syscall4(11, (long)buf, width, height, channels); } static inline void exit(int code) { __asm__ volatile ( "int $0x80" : : "a"(60), "D"(code) : "memory" ); for (;;); }