230 lines
7.3 KiB
C
230 lines
7.3 KiB
C
// SPDX-License-Identifier: ISC
|
|
|
|
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
enum syscall_number : uintptr_t {
|
|
#define SYSCALL_DECLARE(number, name, num_args) SYS_##name = number,
|
|
#include <zinnia/syscall_list.inc>
|
|
#undef SYSCALL_DECLARE
|
|
};
|
|
|
|
enum syslog_kind : uintptr_t {
|
|
SYSLOG_ERR = 3,
|
|
SYSLOG_INFO = 6,
|
|
};
|
|
|
|
struct sys_ret {
|
|
uintptr_t value;
|
|
uintptr_t error;
|
|
};
|
|
|
|
static inline struct sys_ret syscall6(
|
|
enum syscall_number num,
|
|
uintptr_t a0,
|
|
uintptr_t a1,
|
|
uintptr_t a2,
|
|
uintptr_t a3,
|
|
uintptr_t a4,
|
|
uintptr_t a5
|
|
) {
|
|
register uintptr_t r10 asm("r10") = a3;
|
|
register uintptr_t r8 asm("r8") = a4;
|
|
register uintptr_t r9 asm("r9") = a5;
|
|
uintptr_t value;
|
|
uintptr_t error;
|
|
asm volatile("syscall"
|
|
: "=a"(value), "=d"(error)
|
|
: "a"(num), "D"(a0), "S"(a1), "d"(a2), "r"(r10), "r"(r8), "r"(r9)
|
|
: "rcx", "r11", "memory");
|
|
return (struct sys_ret){value, error};
|
|
}
|
|
|
|
static inline struct sys_ret syscall3(enum syscall_number num, uintptr_t a0, uintptr_t a1, uintptr_t a2) {
|
|
return syscall6(num, a0, a1, a2, 0, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret syscall4(enum syscall_number num, uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3) {
|
|
return syscall6(num, a0, a1, a2, a3, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret syscall5(
|
|
enum syscall_number num,
|
|
uintptr_t a0,
|
|
uintptr_t a1,
|
|
uintptr_t a2,
|
|
uintptr_t a3,
|
|
uintptr_t a4
|
|
) {
|
|
return syscall6(num, a0, a1, a2, a3, a4, 0);
|
|
}
|
|
|
|
[[noreturn]]
|
|
static inline void sys_exit(int status) {
|
|
syscall3(SYS_exit, (uintptr_t)status, 0, 0);
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
static inline struct sys_ret sys_syslog(enum syslog_kind kind, const char* msg, size_t len) {
|
|
return syscall3(SYS_syslog, kind, (uintptr_t)msg, len);
|
|
}
|
|
|
|
static inline struct sys_ret sys_mmap(void* addr, size_t len, uint32_t prot, uint32_t flags, int fd, int64_t off) {
|
|
return syscall6(SYS_mmap, (uintptr_t)addr, len, prot, flags, (uintptr_t)fd, (uintptr_t)off);
|
|
}
|
|
|
|
static inline struct sys_ret sys_munmap(void* addr, size_t len) {
|
|
return syscall3(SYS_munmap, (uintptr_t)addr, len, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_openat(int dirfd, const char* path, uint32_t flags, uint32_t mode) {
|
|
return syscall4(SYS_openat, (uintptr_t)dirfd, (uintptr_t)path, flags, mode);
|
|
}
|
|
|
|
static inline struct sys_ret sys_close(int fd) {
|
|
return syscall3(SYS_close, (uintptr_t)fd, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_pread(int fd, void* buf, size_t len, uint64_t off) {
|
|
return syscall4(SYS_pread, (uintptr_t)fd, (uintptr_t)buf, len, off);
|
|
}
|
|
|
|
static inline struct sys_ret sys_fstat(int fd, void* buf) {
|
|
return syscall3(SYS_fstat, (uintptr_t)fd, (uintptr_t)buf, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_getuname(void* buf) {
|
|
return syscall3(SYS_getuname, (uintptr_t)buf, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_setuname(const void* buf) {
|
|
return syscall3(SYS_setuname, (uintptr_t)buf, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_mprotect(void* addr, size_t len, uint32_t prot) {
|
|
return syscall3(SYS_mprotect, (uintptr_t)addr, len, prot);
|
|
}
|
|
|
|
static inline struct sys_ret sys_madvise(void* addr, size_t len, int advice) {
|
|
return syscall3(SYS_madvise, (uintptr_t)addr, len, (uintptr_t)advice);
|
|
}
|
|
|
|
static inline struct sys_ret sys_msync(void* addr, size_t len, int flags) {
|
|
return syscall3(SYS_msync, (uintptr_t)addr, len, (uintptr_t)flags);
|
|
}
|
|
|
|
static inline struct sys_ret sys_pwrite(int fd, const void* buf, size_t len, uint64_t off) {
|
|
return syscall4(SYS_pwrite, (uintptr_t)fd, (uintptr_t)buf, len, off);
|
|
}
|
|
|
|
static inline struct sys_ret sys_readv(int fd, const void* iov, size_t count) {
|
|
return syscall3(SYS_readv, (uintptr_t)fd, (uintptr_t)iov, count);
|
|
}
|
|
|
|
static inline struct sys_ret sys_writev(int fd, const void* iov, size_t count) {
|
|
return syscall3(SYS_writev, (uintptr_t)fd, (uintptr_t)iov, count);
|
|
}
|
|
|
|
static inline struct sys_ret sys_seek(int fd, int64_t off, int whence) {
|
|
return syscall3(SYS_seek, (uintptr_t)fd, (uintptr_t)off, (uintptr_t)whence);
|
|
}
|
|
|
|
static inline struct sys_ret sys_fstatat(int dirfd, const char* path, void* buf, uint32_t flags) {
|
|
return syscall4(SYS_fstatat, (uintptr_t)dirfd, (uintptr_t)path, (uintptr_t)buf, flags);
|
|
}
|
|
|
|
static inline struct sys_ret sys_faccessat(int dirfd, const char* path, uint32_t mode, uint32_t flags) {
|
|
return syscall4(SYS_faccessat, (uintptr_t)dirfd, (uintptr_t)path, mode, flags);
|
|
}
|
|
|
|
static inline struct sys_ret sys_fcntl(int fd, int cmd, uintptr_t arg) {
|
|
return syscall3(SYS_fcntl, (uintptr_t)fd, (uintptr_t)cmd, arg);
|
|
}
|
|
|
|
static inline struct sys_ret sys_ftruncate(int fd, int64_t len) {
|
|
return syscall3(SYS_ftruncate, (uintptr_t)fd, (uintptr_t)len, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_truncate(const char* path, int64_t len) {
|
|
return syscall3(SYS_truncate, (uintptr_t)path, (uintptr_t)len, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_getcwd(char* buf, size_t len) {
|
|
return syscall3(SYS_getcwd, (uintptr_t)buf, len, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_chdir(const char* path) {
|
|
return syscall3(SYS_chdir, (uintptr_t)path, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_fchdir(int fd) {
|
|
return syscall3(SYS_fchdir, (uintptr_t)fd, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_mkdirat(int dirfd, const char* path, uint32_t mode) {
|
|
return syscall3(SYS_mkdirat, (uintptr_t)dirfd, (uintptr_t)path, mode);
|
|
}
|
|
|
|
static inline struct sys_ret sys_rmdirat(int dirfd, const char* path) {
|
|
return syscall3(SYS_rmdirat, (uintptr_t)dirfd, (uintptr_t)path, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_unlinkat(int dirfd, const char* path, uint32_t flags) {
|
|
return syscall3(SYS_unlinkat, (uintptr_t)dirfd, (uintptr_t)path, flags);
|
|
}
|
|
|
|
static inline struct sys_ret sys_getdents(int fd, void* buf, size_t len) {
|
|
return syscall3(SYS_getdents, (uintptr_t)fd, (uintptr_t)buf, len);
|
|
}
|
|
|
|
static inline struct sys_ret sys_renameat(int old_dirfd, const char* old_path, int new_dirfd, const char* new_path) {
|
|
return syscall4(SYS_renameat, (uintptr_t)old_dirfd, (uintptr_t)old_path, (uintptr_t)new_dirfd, (uintptr_t)new_path);
|
|
}
|
|
|
|
static inline struct sys_ret sys_linkat(
|
|
int old_dirfd,
|
|
const char* old_path,
|
|
int new_dirfd,
|
|
const char* new_path,
|
|
uint32_t flags
|
|
) {
|
|
return syscall5(
|
|
SYS_linkat,
|
|
(uintptr_t)old_dirfd,
|
|
(uintptr_t)old_path,
|
|
(uintptr_t)new_dirfd,
|
|
(uintptr_t)new_path,
|
|
flags
|
|
);
|
|
}
|
|
|
|
static inline struct sys_ret sys_symlinkat(const char* target, int dirfd, const char* path) {
|
|
return syscall3(SYS_symlinkat, (uintptr_t)target, (uintptr_t)dirfd, (uintptr_t)path);
|
|
}
|
|
|
|
static inline struct sys_ret sys_readlinkat(int dirfd, const char* path, char* buf, size_t len) {
|
|
return syscall4(SYS_readlinkat, (uintptr_t)dirfd, (uintptr_t)path, (uintptr_t)buf, len);
|
|
}
|
|
|
|
static inline struct sys_ret sys_dup(int fd) {
|
|
return syscall3(SYS_dup, (uintptr_t)fd, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_dup3(int old_fd, int new_fd, uint32_t flags) {
|
|
return syscall3(SYS_dup3, (uintptr_t)old_fd, (uintptr_t)new_fd, flags);
|
|
}
|
|
|
|
static inline struct sys_ret sys_umask(uint32_t mask) {
|
|
return syscall3(SYS_umask, mask, 0, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_pipe(int* fds, uint32_t flags) {
|
|
return syscall3(SYS_pipe, (uintptr_t)fds, flags, 0);
|
|
}
|
|
|
|
static inline struct sys_ret sys_ppoll(void* fds, size_t nfds, const void* timeout, const void* sigmask) {
|
|
return syscall4(SYS_ppoll, (uintptr_t)fds, nfds, (uintptr_t)timeout, (uintptr_t)sigmask);
|
|
}
|