1
0
Fork 0
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:
Stefan Lankes 2015-07-15 10:05:09 +02:00
parent c4237945c1
commit 7556ee66e1
3 changed files with 95 additions and 79 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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 */
};