mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
redesign of system call handling
- use a table to determine the address of the system call - fix numbering of the system calls
This commit is contained in:
parent
c4237945c1
commit
7556ee66e1
3 changed files with 95 additions and 79 deletions
|
@ -545,23 +545,28 @@ isrsyscall:
|
|||
push rdi
|
||||
push rsi
|
||||
|
||||
; push system call number
|
||||
push rax
|
||||
|
||||
; get kernel stack
|
||||
call get_kernel_stack
|
||||
|
||||
; restore registers
|
||||
mov r8, [rsp+56]
|
||||
mov r9, [rsp+48]
|
||||
mov r10, [rsp+40]
|
||||
mov r11, [rsp+32]
|
||||
mov rdx, [rsp+24]
|
||||
mov r8, [rsp+64]
|
||||
mov r9, [rsp+56]
|
||||
mov r10, [rsp+48]
|
||||
mov r11, [rsp+40]
|
||||
mov rdx, [rsp+32]
|
||||
; see below
|
||||
; mov rcx, [rsp+16]
|
||||
mov rdi, [rsp+8]
|
||||
mov rsi, [rsp+0]
|
||||
; mov rcx, [rsp+24]
|
||||
mov rdi, [rsp+16]
|
||||
mov rsi, [rsp+8]
|
||||
|
||||
xchg rsp, rax ; => rax contains pointer to the kernel stack
|
||||
push rax ; store user-level stack pointer
|
||||
|
||||
push rax ; contains original rsp
|
||||
; restore system call number
|
||||
mov rax, [rax+0]
|
||||
|
||||
; syscall stores in rcx the return address
|
||||
; => using of r10 for the temporary storage of the 4th argument
|
||||
|
@ -569,14 +574,16 @@ isrsyscall:
|
|||
|
||||
; during a system call, HermitCore allows interrupts
|
||||
sti
|
||||
call syscall_handler
|
||||
extern syscall_table
|
||||
call [rax*8+syscall_table]
|
||||
cli
|
||||
|
||||
; restore user-level stack
|
||||
; restore user-level stack pointer
|
||||
pop r10
|
||||
mov rsp, r10
|
||||
|
||||
; restore registers
|
||||
add rsp, 8 ; ignore old value of rax
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rcx
|
||||
|
|
|
@ -47,33 +47,33 @@ extern "C" {
|
|||
#define __NR_open 2
|
||||
#define __NR_close 3
|
||||
#define __NR_read 4
|
||||
#define __NR_lseek 6
|
||||
#define __NR_unlink 7
|
||||
#define __NR_getpid 8
|
||||
#define __NR_kill 9
|
||||
#define __NR_fstat 10
|
||||
#define __NR_sbrk 11
|
||||
#define __NR_fork 12
|
||||
#define __NR_wait 13
|
||||
#define __NR_execve 14
|
||||
#define __NR_times 15
|
||||
#define __NR_accept 16
|
||||
#define __NR_bind 17
|
||||
#define __NR_closesocket 18
|
||||
#define __NR_connect 19
|
||||
#define __NR_listen 20
|
||||
#define __NR_recv 21
|
||||
#define __NR_send 22
|
||||
#define __NR_socket 23
|
||||
#define __NR_getsockopt 24
|
||||
#define __NR_setsockopt 25
|
||||
#define __NR_gethostbyname 26
|
||||
#define __NR_sendto 27
|
||||
#define __NR_recvfrom 28
|
||||
#define __NR_select 29
|
||||
#define __NR_stat 30
|
||||
#define __NR_dup 31
|
||||
#define __NR_dup2 32
|
||||
#define __NR_lseek 5
|
||||
#define __NR_unlink 6
|
||||
#define __NR_getpid 7
|
||||
#define __NR_kill 8
|
||||
#define __NR_fstat 9
|
||||
#define __NR_sbrk 10
|
||||
#define __NR_fork 11
|
||||
#define __NR_wait 12
|
||||
#define __NR_execve 13
|
||||
#define __NR_times 14
|
||||
#define __NR_accept 15
|
||||
#define __NR_bind 16
|
||||
#define __NR_closesocket 17
|
||||
#define __NR_connect 18
|
||||
#define __NR_listen 19
|
||||
#define __NR_recv 20
|
||||
#define __NR_send 21
|
||||
#define __NR_socket 22
|
||||
#define __NR_getsockopt 23
|
||||
#define __NR_setsockopt 24
|
||||
#define __NR_gethostbyname 25
|
||||
#define __NR_sendto 26
|
||||
#define __NR_recvfrom 27
|
||||
#define __NR_select 28
|
||||
#define __NR_stat 29
|
||||
#define __NR_dup 30
|
||||
#define __NR_dup2 31
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -73,46 +73,55 @@ static ssize_t sys_sbrk(int incr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ssize_t syscall_handler(uint32_t sys_nr, ...)
|
||||
static int sys_open(const char* name, int flags, int mode)
|
||||
{
|
||||
ssize_t ret = -EINVAL;
|
||||
va_list vl;
|
||||
|
||||
check_workqueues();
|
||||
|
||||
va_start(vl, sys_nr);
|
||||
|
||||
switch(sys_nr)
|
||||
{
|
||||
case __NR_exit:
|
||||
sys_exit(va_arg(vl, uint32_t));
|
||||
ret = 0;
|
||||
break;
|
||||
case __NR_write: {
|
||||
int fd = va_arg(vl, int);
|
||||
const char* buf = va_arg(vl, const char*);
|
||||
size_t len = va_arg(vl, size_t);
|
||||
ret = sys_write(fd, buf, len);
|
||||
break;
|
||||
}
|
||||
//TODO: Currently, we ignore file descriptors
|
||||
case __NR_open:
|
||||
case __NR_close:
|
||||
ret = 0;
|
||||
break;
|
||||
case __NR_sbrk: {
|
||||
int incr = va_arg(vl, int);
|
||||
|
||||
ret = sys_sbrk(incr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
kprintf("invalid system call: 0x%lx\n", sys_nr);
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
};
|
||||
|
||||
va_end(vl);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_close(int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int default_handler(void)
|
||||
{
|
||||
kprintf("Invalid system call\n");
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
size_t syscall_table[] = {
|
||||
(size_t) sys_exit, /* __NR_exit */
|
||||
(size_t) sys_write, /* __NR_write */
|
||||
(size_t) sys_open, /* __NR_open */
|
||||
(size_t) sys_close, /* __NR_close */
|
||||
(size_t) default_handler, /* __NR_read */
|
||||
(size_t) default_handler, /* __NR_lseek */
|
||||
(size_t) default_handler, /* __NR_unlink */
|
||||
(size_t) default_handler, /* __NR_getpid */
|
||||
(size_t) default_handler, /* __NR_kill */
|
||||
(size_t) default_handler, /* __NR_fstat */
|
||||
(size_t) sys_sbrk, /* __NR_sbrk */
|
||||
(size_t) default_handler, /* __NR_fork */
|
||||
(size_t) default_handler, /* __NR_wait */
|
||||
(size_t) default_handler, /* __NR_execve */
|
||||
(size_t) default_handler, /* __NR_times */
|
||||
(size_t) default_handler, /* __NR_accept */
|
||||
(size_t) default_handler, /* __NR_bind */
|
||||
(size_t) default_handler, /* __NR_closesocket */
|
||||
(size_t) default_handler, /* __NR_connect */
|
||||
(size_t) default_handler, /* __NR_listen */
|
||||
(size_t) default_handler, /* __NR_recv */
|
||||
(size_t) default_handler, /* __NR_send */
|
||||
(size_t) default_handler, /* __NR_socket */
|
||||
(size_t) default_handler, /* __NR_getsockopt */
|
||||
(size_t) default_handler, /* __NR_setsockopt */
|
||||
(size_t) default_handler, /* __NR_gethostbyname */
|
||||
(size_t) default_handler, /* __NR_sendto */
|
||||
(size_t) default_handler, /* __NR_recvfrom */
|
||||
(size_t) default_handler, /* __NR_select */
|
||||
(size_t) default_handler, /* __NR_stat */
|
||||
(size_t) default_handler, /* __NR_dup */
|
||||
(size_t) default_handler, /* __NR_dup2 */
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue