Files
zinnia/tests/user/lib/syscall.h
T
2026-10-27 23:11:15 +01:00

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);
}