#if defined(__x86_64__) #include "../int.h" #include "../sys.h" // Start code #ifndef _START_DEFINED #define _START_DEFINED extern int main(int argc, char **argv); void _start() { void *fp = __builtin_frame_address(0); register int argc asm("rdi") = *(uint64_t *)(fp + 8); register char **argv asm("rsi") = fp + 16; exit(main(argc, argv)); } #endif /* ifndef _START_DEFINED */ // include other generic functions #include "generic.h" // // syscall functions #define SYS_EXIT 60 void exit(int8_t status) { asm volatile("syscall" : : "a"(SYS_EXIT), "D"(status) :); for (;;) ; } #define SYS_WRITE 1 intptr_t write(int32_t fd, const void *buf, intptr_t size) { intptr_t n_written = 0; asm volatile("syscall\n" "movq %0, %%rax\n" : "=r"(n_written) : "a"(SYS_WRITE), "D"(fd), "S"(buf), "d"(size) // RDI, RSI, RDX are used in x86-64 for write args : "rcx", "r11"); return n_written; } #define SYS_READ 0 intptr_t read(int32_t fd, const void *buf, intptr_t size) { intptr_t n_read = 0; asm volatile("syscall\n" "movq %0, %%rax\n" : "=r"(n_read) : "a"(SYS_READ), "D"(fd), "S"(buf), "d"(size) // RDI, RSI, RDX are used in x86-64 for write args : "rcx", "r11", "memory"); return n_read; } #define SYS_FORK 57 uint32_t fork() { uint64_t rtn; asm volatile("syscall\n" // syscall "movq %0, %%rax\n" // save return value : "=r"(rtn) : "a"(SYS_FORK) :); return (uint32_t)rtn; } #define SYS_EXECVE 59 int32_t execve(const char *filename, const char *argv[], const char *envp[]) { int64_t rtn; asm volatile("syscall\n" : "=r"(rtn) : "a"(SYS_EXECVE), "D"(filename), "S"(argv), "d"(envp) : "rcx", "r11"); return (int32_t)rtn; } #define SYS_WAIT4 61 uint32_t wait4(uint32_t pid, int *wstatus, int options, void *rusage) { uint32_t child_pid; asm volatile("mov %5, %%r10\n" "syscall\n" : "=a"(child_pid) : "a"(SYS_WAIT4), "D"(pid), "S"(wstatus), "d"(options), "r"(rusage) : "rcx", "r10", "r11", "memory"); return child_pid; } uint32_t waitpid(uint32_t pid, int *wstatus, int options) { return wait4(pid, wstatus, options, 0); } #define SYS_OPENAT 257 int32_t openat(int32_t fd, const char *filename, uint32_t flags, uint32_t mode) { int32_t file; asm volatile( "mov %5, %%r10\n" "syscall\n" : "=a"(file) : "a"(SYS_OPENAT), "D"(fd), "S"(filename), "d"(flags), "r"((uint64_t)mode) // RDI, RSI, RDX are used in x86-64 for write args : "rcx", "r10", "r11"); return file; } #define SYS_CLOSE 3 int close(unsigned int fd) { int rtn; asm volatile("syscall" : "=a"(rtn) : "a"(SYS_CLOSE), "D"(fd) : "rcx", "r11"); return rtn; } #define SYS_FSYNC 74 int fsync(unsigned int fd) { int rtn; asm volatile("syscall" : "=a"(rtn) : "a"(SYS_FSYNC), "D"(fd) : "rcx", "r11"); return rtn; } #define SYS_SOCKET 41 int socket(int domain, int type, int protocol) { int32_t fd; asm volatile("syscall\n" : "=a"(fd) : "a"(SYS_SOCKET), "D"(domain), "S"(type), "d"(protocol) : "rcx", "r11"); return fd; } #define SYS_SETSOCKOPT 54 int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) { int rtn; asm volatile("mov %5, %%r10\n" "mov %6, %%r8\n" "syscall\n" : "=a"(rtn) : "a"(SYS_SETSOCKOPT), "D"(fd), "S"(level), "d"(optname), "r"(optval), "r"((uint64_t)optlen) : "rcx", "r11"); return rtn; } #define SYS_BIND 49 int bind(int fd, const void *sockaddr, socklen_t addrlen) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_BIND), "D"(fd), "S"(sockaddr), "d"(addrlen) : "rcx", "r11"); return rtn; } #define SYS_LISTEN 50 int listen(int fd, int backlog) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_LISTEN), "D"(fd), "S"(backlog) : "rcx", "r11"); return rtn; } #define SYS_ACCEPT 43 int accept(int fd, void *addr, socklen_t *addrlen) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_ACCEPT), "D"(fd), "S"(addr), "d"(addrlen) : "rcx", "r11", "memory"); return rtn; } #define SYS_CONNECT 42 int connect(int fd, void *addr, socklen_t addrlen) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_CONNECT), "D"(fd), "S"(addr), "d"(addrlen) : "rcx", "r11"); return rtn; } #define SYS_SENDTO 44 ssize_t sendto(int fd, const void *buf, size_t size, int flags, const void *sockaddr, socklen_t addrlen) { ssize_t nsent; asm volatile("mov %5, %%r10\n" "mov %6, %%r8\n" "mov %7, %%r9\n" "syscall\n" : "=a"(nsent) : "a"(SYS_SENDTO), "D"(fd), "S"(buf), "d"(size), "r"((int64_t)flags), "r"(sockaddr), "r"((uint64_t)addrlen) : "rcx", "r11"); return nsent; } #define SYS_RECVFROM 45 ssize_t recvfrom(int fd, const void *buf, size_t size, int flags, const void *sockaddr, socklen_t addrlen) { ssize_t nrecv; asm volatile("mov %5, %%r10\n" "mov %6, %%r8\n" "mov %7, %%r9\n" "syscall\n" : "=a"(nrecv) : "a"(SYS_RECVFROM), "D"(fd), "S"(buf), "d"(size), "r"((int64_t)flags), "r"(sockaddr), "r"((int64_t)addrlen) : "rcx", "r11", "memory"); return nrecv; } #define SYS_CLOCK_SETTIME 227 int clock_settime(clockid_t clockid, const struct timespec *tp) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_CLOCK_SETTIME), "D"(clockid), "S"(tp) : "rcx", "r11"); return rtn; } #define SYS_CLOCK_GETTIME 228 int clock_gettime(clockid_t clockid, struct timespec *tp) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_CLOCK_GETTIME), "D"(clockid), "S"(tp) : "rcx", "r11", "memory"); return rtn; } #define SYS_CLOCK_GETRES 229 int clock_getres(clockid_t clockid, struct timespec *res) { int rtn; asm volatile("syscall\n" : "=a"(rtn) : "a"(SYS_CLOCK_GETRES), "D"(clockid), "S"(res) : "rcx", "r11", "memory"); return rtn; } #define SYS_CLOCK_NANOSLEEP 230 int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec *remain) { int rtn; asm volatile("mov %5, %%r10\n" "syscall\n" : "=a"(rtn) : "a"(SYS_CLOCK_NANOSLEEP), "D"(clockid), "S"(flags), "d"(t), "r"(remain) : "rcx", "r11", "memory"); return rtn; } #define SYS_RT_SIGACTION 13 int rt_sigaction(int signum, const void *act, void *oldact, size_t sigset_len) { int rtn; asm volatile("mov %5, %%r10\n" "syscall\n" : "=a"(rtn) : "a"(SYS_RT_SIGACTION), "D"(signum), "S"(act), "d"(oldact), "r"(sigset_len) : "rcx", "r11", "memory"); return rtn; } #endif /* ifdef __x86_64__ */