diff --git a/arch/amd64/syscall.c b/arch/amd64/syscall.c index 145fc2a..7a31d62 100644 --- a/arch/amd64/syscall.c +++ b/arch/amd64/syscall.c @@ -77,6 +77,7 @@ void *syscall_table[256] = { [SYSCALL_NRX_WAITPID] = sys_waitpid, [SYSCALL_NR_GETPGID] = sys_getpgid, [SYSCALL_NR_SETPGID] = sys_setpgid, + [SYSCALL_NR_SIGALTSTACK] = sys_sigaltstack, // System [SYSCALL_NR_SYNC] = sys_sync, diff --git a/include/sys/sys_proc.h b/include/sys/sys_proc.h index 807ab8a..ba683c1 100644 --- a/include/sys/sys_proc.h +++ b/include/sys/sys_proc.h @@ -1,6 +1,8 @@ #pragma once #include "sys/types.h" +struct user_stack; + int sys_kill(pid_t pid, int signum); void sys_exit(int status); void sys_sigentry(uintptr_t entry); @@ -14,6 +16,8 @@ gid_t sys_getgid(void); int sys_setuid(uid_t uid); int sys_setgid(gid_t gid); +int sys_sigaltstack(const struct user_stack *ss, struct user_stack *old_ss); + int sys_waitpid(pid_t pid, int *status, int flags); pid_t sys_getpgid(pid_t pid); int sys_setpgid(pid_t pid, pid_t pgrp); diff --git a/include/sys/thread.h b/include/sys/thread.h index 1344bc5..2ac6902 100644 --- a/include/sys/thread.h +++ b/include/sys/thread.h @@ -51,6 +51,11 @@ struct thread { struct process *proc; struct thread *next_thread; + // Signal + uintptr_t signal_entry; + uintptr_t signal_stack_base; + size_t signal_stack_size; + uint32_t flags; // Scheduler @@ -80,7 +85,6 @@ struct process { struct io_notify pid_notify; // Signal - uintptr_t signal_entry; uint64_t sigq; // State diff --git a/include/user/signum.h b/include/user/signum.h index 1110760..7278675 100644 --- a/include/user/signum.h +++ b/include/user/signum.h @@ -1,4 +1,5 @@ #pragma once +#include //#define SIGHUP 1 //#define SIGINT 2 @@ -57,4 +58,13 @@ #define NSIG 32 +struct user_stack { + void *ss_sp; + size_t ss_size; +}; + +#if !defined(__KERNEL__) +typedef struct user_stack stack_t; +#endif + int kill(int pid, int signum); diff --git a/include/user/syscall.h b/include/user/syscall.h index eb3fb10..1cc469b 100644 --- a/include/user/syscall.h +++ b/include/user/syscall.h @@ -51,6 +51,7 @@ #define SYSCALL_NR_SETGID 106 #define SYSCALL_NR_SETPGID 109 #define SYSCALL_NR_GETPGID 121 +#define SYSCALL_NR_SIGALTSTACK 131 #define SYSCALL_NRX_WAITPID 247 #define SYSCALL_NR_SOCKET 41 diff --git a/sys/execve.c b/sys/execve.c index d801cec..c717d4c 100644 --- a/sys/execve.c +++ b/sys/execve.c @@ -270,7 +270,10 @@ int sys_execve(const char *path, const char **argv, const char **envp) { argv_fixup[procv_vecp[0]] = 0; envp_fixup[procv_vecp[1]] = 0; - proc->signal_entry = 0; + thr->signal_entry = MM_NADDR; + thr->signal_stack_base = MM_NADDR; + thr->signal_stack_size = 0; + thr->data.rsp0 = thr->data.rsp0_top; // Allocate a new user stack diff --git a/sys/thread.c b/sys/thread.c index 5143e08..8603e0a 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -234,7 +234,8 @@ int process_init_thread(struct process *proc, uintptr_t entry, void *arg, int us proc->first_child = NULL; proc->next_child = NULL; proc->pgid = -1; - proc->pid = -1; + proc->pid = process_alloc_pid(user); + kdebug("New process #%d with main thread <%p>", proc->pid, main_thread); proc->sigq = 0; proc->proc_state = PROC_ACTIVE; @@ -277,10 +278,15 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int flags) { uintptr_t stack_pages = mm_phys_alloc_contiguous(2); //amd64_phys_alloc_contiguous(2); _assert(stack_pages != MM_NADDR); + thr->signal_entry = MM_NADDR; + thr->signal_stack_base = MM_NADDR; + thr->signal_stack_size = 0; + thr->data.rsp0_base = MM_VIRTUALIZE(stack_pages); thr->data.rsp0_size = MM_PAGE_SIZE * 2; thr->data.rsp0_top = thr->data.rsp0_base + thr->data.rsp0_size; thr->flags = (flags & THR_INIT_USER) ? 0 : THREAD_KERNEL; + thr->next_thread = NULL; if (flags & THR_INIT_USER) { thr->data.fxsave = kmalloc(FXSAVE_REGION); @@ -427,7 +433,6 @@ int sys_fork(struct sys_fork_frame *frame) { thread_wait_io_init(&dst->pid_notify); dst->flags = 0; strcpy(dst->name, src->name); - dst->signal_entry = src->signal_entry; process_ioctx_fork(dst, src); dst->parent = src; dst->next_child = src->first_child; @@ -439,6 +444,7 @@ int sys_fork(struct sys_fork_frame *frame) { dst->first_thread = dst_thread; dst->thread_count = 1; dst->proc_state = PROC_ACTIVE; + kdebug("New process #%d with main thread <%p>\n", dst->pid, dst_thread); // Initialize dst thread dst_thread->proc = dst; @@ -452,10 +458,15 @@ int sys_fork(struct sys_fork_frame *frame) { dst_thread->data.rsp0_size = MM_PAGE_SIZE * 2; dst_thread->data.rsp0_top = dst_thread->data.rsp0_base + dst_thread->data.rsp0_size; dst_thread->flags = 0; + dst_thread->next_thread = NULL; dst_thread->data.rsp3_base = src_thread->data.rsp3_base; dst_thread->data.rsp3_size = src_thread->data.rsp3_size; + dst_thread->signal_entry = src_thread->signal_entry; + dst_thread->signal_stack_base = src_thread->signal_stack_base; + dst_thread->signal_stack_size = src_thread->signal_stack_size; + dst_thread->data.cr3 = MM_PHYS(space); dst_thread->data.fxsave = kmalloc(FXSAVE_REGION); @@ -554,11 +565,14 @@ void thread_sigenter(int signum) { return; } - uintptr_t old_rsp0_top = thr->data.rsp0_top; - // XXX: Either use a separate stack or ensure stuff doesn't get overwritten - uintptr_t signal_rsp3 = thr->data.rsp3_base + 0x800; - context_sigenter(thr->proc->signal_entry, signal_rsp3, signum); + assert(thr->signal_entry != MM_NADDR, "Thread hasn't set its signal entry!\n"); + assert(thr->signal_stack_base != MM_NADDR, "Thread hasn't set its signal stack!\n"); + + uintptr_t old_rsp0_top = thr->data.rsp0_top; + uintptr_t signal_rsp3 = thr->signal_stack_base + thr->signal_stack_size; + + context_sigenter(thr->signal_entry, signal_rsp3, signum); thr->data.rsp0_top = old_rsp0_top; } @@ -704,7 +718,23 @@ int sys_kill(pid_t pid, int signum) { } void sys_sigentry(uintptr_t entry) { - thread_self->proc->signal_entry = entry; + thread_self->signal_entry = entry; +} + +int sys_sigaltstack(const struct user_stack *ss, struct user_stack *old_ss) { + struct thread *thr = thread_self; + _assert(thr); + + if (old_ss) { + old_ss->ss_sp = (void *) thr->signal_stack_base; + old_ss->ss_size = thr->signal_stack_size; + } + if (ss) { + thr->signal_stack_base = (uintptr_t) ss->ss_sp; + thr->signal_stack_size = ss->ss_size; + } + + return 0; } pid_t sys_getpid(void) {