Files
NJU_PA/navy-apps/libs/libos/src/syscall.c
tracer-ics2023 03ba7d6683 > compile NEMU
221220000 张三
Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 14:46:00 up 8 days,  2:29,  1 user,  load average: 0.64, 0.48, 0.37
2024-09-26 14:46:00 +08:00

188 lines
4.0 KiB
C

#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
#include <time.h>
#include "syscall.h"
#include <stdint.h>
// helper macros
#define _concat(x, y) x ## y
#define concat(x, y) _concat(x, y)
#define _args(n, list) concat(_arg, n) list
#define _arg0(a0, ...) a0
#define _arg1(a0, a1, ...) a1
#define _arg2(a0, a1, a2, ...) a2
#define _arg3(a0, a1, a2, a3, ...) a3
#define _arg4(a0, a1, a2, a3, a4, ...) a4
#define _arg5(a0, a1, a2, a3, a4, a5, ...) a5
// extract an argument from the macro array
#define SYSCALL _args(0, ARGS_ARRAY)
#define GPR1 _args(1, ARGS_ARRAY)
#define GPR2 _args(2, ARGS_ARRAY)
#define GPR3 _args(3, ARGS_ARRAY)
#define GPR4 _args(4, ARGS_ARRAY)
#define GPRx _args(5, ARGS_ARRAY)
// ISA-depedent definitions
#if defined(__ISA_X86__)
# define ARGS_ARRAY ("int $0x80", "eax", "ebx", "ecx", "edx", "eax")
#elif defined(__ISA_MIPS32__)
# define ARGS_ARRAY ("syscall", "v0", "a0", "a1", "a2", "v0")
#elif defined(__riscv)
#ifdef __riscv_e
# define ARGS_ARRAY ("ecall", "a5", "a0", "a1", "a2", "a0")
#else
# define ARGS_ARRAY ("ecall", "a7", "a0", "a1", "a2", "a0")
#endif
#elif defined(__ISA_AM_NATIVE__)
# define ARGS_ARRAY ("call *0x100000", "rdi", "rsi", "rdx", "rcx", "rax")
#elif defined(__ISA_X86_64__)
# define ARGS_ARRAY ("int $0x80", "rdi", "rsi", "rdx", "rcx", "rax")
#elif defined(__ISA_LOONGARCH32R__)
# define ARGS_ARRAY ("syscall 0", "a7", "a0", "a1", "a2", "a0")
#else
#error _syscall_ is not implemented
#endif
intptr_t _syscall_(intptr_t type, intptr_t a0, intptr_t a1, intptr_t a2) {
register intptr_t _gpr1 asm (GPR1) = type;
register intptr_t _gpr2 asm (GPR2) = a0;
register intptr_t _gpr3 asm (GPR3) = a1;
register intptr_t _gpr4 asm (GPR4) = a2;
register intptr_t ret asm (GPRx);
asm volatile (SYSCALL : "=r" (ret) : "r"(_gpr1), "r"(_gpr2), "r"(_gpr3), "r"(_gpr4));
return ret;
}
void _exit(int status) {
_syscall_(SYS_exit, status, 0, 0);
while (1);
}
int _open(const char *path, int flags, mode_t mode) {
return _syscall_(SYS_open, (intptr_t)path, flags, mode);
}
int _write(int fd, void *buf, size_t count) {
return _syscall_(SYS_write, fd, (intptr_t)buf, count);
}
void *_sbrk(intptr_t increment) {
extern char _end;
static char* brk = &_end;
char* prev_brk = brk;
brk += increment;
char buf[128];
if (_syscall_(SYS_brk, (intptr_t)brk, 0, 0) != 0) {
return (void*)-1;
}
return prev_brk;
}
int _read(int fd, void *buf, size_t count) {
return _syscall_(SYS_read, fd, (intptr_t)buf, count);
}
int _close(int fd) {
return _syscall_(SYS_close, fd, 0, 0);
}
off_t _lseek(int fd, off_t offset, int whence) {
return _syscall_(SYS_lseek, fd, offset, whence);
}
int _gettimeofday(struct timeval *tv, struct timezone *tz) {
return _syscall_(SYS_gettimeofday, (intptr_t)tv, (intptr_t)tz, 0);
}
int _execve(const char *fname, char * const argv[], char *const envp[]) {
return _syscall_(SYS_execve, (intptr_t)fname, (intptr_t)argv, (intptr_t)envp);
}
// Syscalls below are not used in Nanos-lite.
// But to pass linking, they are defined as dummy functions.
int _fstat(int fd, struct stat *buf) {
return -1;
}
int _stat(const char *fname, struct stat *buf) {
assert(0);
return -1;
}
int _kill(int pid, int sig) {
_exit(-SYS_kill);
return -1;
}
pid_t _getpid() {
_exit(-SYS_getpid);
return 1;
}
pid_t _fork() {
assert(0);
return -1;
}
pid_t vfork() {
assert(0);
return -1;
}
int _link(const char *d, const char *n) {
assert(0);
return -1;
}
int _unlink(const char *n) {
assert(0);
return -1;
}
pid_t _wait(int *status) {
assert(0);
return -1;
}
clock_t _times(void *buf) {
assert(0);
return 0;
}
int pipe(int pipefd[2]) {
assert(0);
return -1;
}
int dup(int oldfd) {
assert(0);
return -1;
}
int dup2(int oldfd, int newfd) {
return -1;
}
unsigned int sleep(unsigned int seconds) {
assert(0);
return -1;
}
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) {
assert(0);
return -1;
}
int symlink(const char *target, const char *linkpath) {
assert(0);
return -1;
}
int ioctl(int fd, unsigned long request, ...) {
return -1;
}