sysdeps/linux: implement various sysdeps

This commit is contained in:
Geert Custers 2020-03-21 11:34:19 +01:00
parent 9c6c6586a1
commit bb436d43a1
2 changed files with 75 additions and 0 deletions

View file

@ -41,6 +41,19 @@ extern "C" {
return ret;
}
static sc_word_t do_asm_syscall5(int sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
sc_word_t ret;
register sc_word_t arg4_reg asm("r10") = arg4;
register sc_word_t arg5_reg asm("r8") = arg5;
asm volatile ("syscall" : "=a"(ret)
: "a"(sc), "D"(arg1), "S"(arg2), "d"(arg3),
"r"(arg4_reg), "r"(arg5_reg)
: "rcx", "r11", "memory");
return ret;
}
static sc_word_t do_asm_syscall6(int sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
@ -71,6 +84,10 @@ namespace mlibc {
sc_word_t arg4) {
return do_asm_syscall4(sc, arg1, arg2, arg3, arg4);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
return do_asm_syscall5(sc, arg1, arg2, arg3, arg4, arg5);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
return do_asm_syscall6(sc, arg1, arg2, arg3, arg4, arg5, arg6);

View file

@ -18,7 +18,13 @@
#define NR_mmap 9
#define NR_sigaction 13
#define NR_ioctl 16
#define NR_select 23
#define NR_socket 41
#define NR_connect 42
#define NR_sendmsg 46
#define NR_recvmsg 47
#define NR_exit 60
#define NR_fcntl 72
#define NR_arch_prctl 158
#define NR_clock_gettime 228
@ -150,6 +156,58 @@ int sys_sigaction(int signum, const struct sigaction *act,
return 0;
}
int sys_socket(int domain, int type, int protocol, int *fd) {
auto ret = do_syscall(NR_socket, domain, type, protocol);
if (int e = sc_error(ret); e)
return e;
*fd = sc_int_result<int>(ret);
return 0;
}
int sys_msg_send(int sockfd, const struct msghdr *msg, int flags, ssize_t *length) {
auto ret = do_syscall(NR_sendmsg, sockfd, msg, flags);
if (int e = sc_error(ret); e)
return e;
*length = sc_int_result<ssize_t>(ret);
return 0;
}
int sys_msg_recv(int sockfd, struct msghdr *msg, int flags, ssize_t *length) {
auto ret = do_syscall(NR_recvmsg, sockfd, msg, flags);
if (int e = sc_error(ret); e)
return e;
*length = sc_int_result<ssize_t>(ret);
return 0;
}
int sys_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
auto ret = do_syscall(NR_connect, sockfd, addr, addrlen);
if (int e = sc_error(ret); e)
return e;
return 0;
}
int sys_fcntl(int fd, int cmd, va_list args, int *result) {
auto arg = va_arg(args, unsigned long);
// TODO: the api for linux differs for each command so fcntl()s might fail with -EINVAL
// we should implement all the different fcntl()s
auto ret = do_syscall(NR_fcntl, fd, cmd, arg);
if (int e = sc_error(ret); e)
return e;
*result = sc_int_result<int>(ret);
return 0;
}
int sys_select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout, int *num_fd) {
auto ret = do_syscall(NR_select, nfds, readfds, writefds,
exceptfds, timeout);
if (int e = sc_error(ret); e)
return e;
*num_fd = sc_int_result<int>(ret);
return 0;
}
void sys_exit(int status) {
do_syscall(NR_exit, status);
__builtin_trap();