Signal entry/exit works (crude)
This commit is contained in:
@@ -3,6 +3,13 @@
|
||||
#define SYSCALL_NR_READ 0
|
||||
#define SYSCALL_NR_WRITE 1
|
||||
|
||||
#define SYSCALL_NRX_SIGENTRY 13
|
||||
void sys_sigentry(uintptr_t entry);
|
||||
#define SYSCALL_NR_SIGRETURN 15
|
||||
void sys_sigreturn(void);
|
||||
#define SYSCALL_NRX_SUICIDE 253
|
||||
void sys_suicide(void);
|
||||
|
||||
#define SYSCALL_NR_FORK 57
|
||||
int sys_fork(void *ctx);
|
||||
#define SYSCALL_NR_EXIT 60
|
||||
|
||||
@@ -28,6 +28,9 @@ struct thread {
|
||||
uint64_t sleep_deadline;
|
||||
struct thread *wait_prev, *wait_next;
|
||||
|
||||
// Signal
|
||||
uintptr_t signal_entry;
|
||||
|
||||
// State
|
||||
pid_t pid;
|
||||
enum thread_state state;
|
||||
|
||||
@@ -100,3 +100,60 @@ context_switch_first:
|
||||
|
||||
ret
|
||||
.size context_switch_to, . - context_switch_to
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.global context_sigreturn
|
||||
context_sigreturn:
|
||||
movq tmp0(%rip), %rsp
|
||||
|
||||
popq %rbx
|
||||
popq %rbp
|
||||
popq %r12
|
||||
popq %r13
|
||||
popq %r14
|
||||
popq %r15
|
||||
|
||||
ret
|
||||
|
||||
|
||||
.global context_sigenter
|
||||
context_sigenter:
|
||||
// %rdi - entry
|
||||
// %rsi - stack
|
||||
pushq %r15
|
||||
pushq %r14
|
||||
pushq %r13
|
||||
pushq %r12
|
||||
pushq %rbp
|
||||
pushq %rbx
|
||||
|
||||
// Use alternate TSS.RSP0 so syscall frame does not get overwritten
|
||||
movq get_cpu(CPU_THREAD), %rbx
|
||||
movq %rsp, tmp0(%rip)
|
||||
movq %rsp, THREAD_RSP0(%rbx)
|
||||
movq %rsp, THREAD_RSP0_TOP(%rbx)
|
||||
movq THREAD_RSP0_TOP(%rbx), %rbx
|
||||
movq get_cpu(CPU_TSS), %r12
|
||||
movq %rbx, TSS_RSP0(%r12)
|
||||
|
||||
pushq $0x1B
|
||||
pushq %rsi
|
||||
|
||||
pushq $0x200
|
||||
|
||||
pushq $0x23
|
||||
pushq %rdi
|
||||
|
||||
iretq
|
||||
|
||||
.section .bss
|
||||
tmp0:
|
||||
.quad 0
|
||||
// 0xffffff000528df90
|
||||
// r15 = 0, r14 = 0, r13 = 0, r12 = 0,
|
||||
// rbp = 0xffffff000528dfd8, rbx = 0x0
|
||||
|
||||
@@ -25,6 +25,10 @@ void *syscall_table[256] = {
|
||||
[SYSCALL_NR_READ] = sys_read,
|
||||
[SYSCALL_NR_WRITE] = sys_write,
|
||||
|
||||
[SYSCALL_NRX_SUICIDE] = sys_suicide,
|
||||
[SYSCALL_NRX_SIGENTRY] = sys_sigentry,
|
||||
[SYSCALL_NR_SIGRETURN] = sys_sigreturn,
|
||||
|
||||
[SYSCALL_NR_EXIT] = sys_exit,
|
||||
|
||||
[SYSCALL_NR_DEBUG_SLEEP] = sys_debug_sleep,
|
||||
|
||||
@@ -166,6 +166,10 @@ void yield(void) {
|
||||
from->state = THREAD_READY;
|
||||
}
|
||||
|
||||
if (to->pid == 1) {
|
||||
kinfo("%p\n", to->data.rsp0);
|
||||
}
|
||||
|
||||
to->state = THREAD_RUNNING;
|
||||
get_cpu()->thread = to;
|
||||
context_switch_to(to, from);
|
||||
|
||||
@@ -344,3 +344,32 @@ void thread_sleep(struct thread *thr, uint64_t deadline) {
|
||||
timer_add_sleep(thr);
|
||||
sched_unqueue(thr, THREAD_WAITING);
|
||||
}
|
||||
|
||||
extern void context_sigenter(uintptr_t entry, uintptr_t stack);
|
||||
extern void context_sigreturn(void);
|
||||
static char fuck[4096];
|
||||
|
||||
void sys_sigreturn(void) {
|
||||
context_sigreturn();
|
||||
}
|
||||
|
||||
void sys_suicide(void) {
|
||||
struct thread *thr = thread_self;
|
||||
_assert(thr);
|
||||
kinfo("Enter\n");
|
||||
uintptr_t old_rsp0_top = thr->data.rsp0_top;
|
||||
thr->data.rsp0_top = (uintptr_t) &fuck[4096];
|
||||
|
||||
context_sigenter(thr->signal_entry, 0x100500);
|
||||
|
||||
thr->data.rsp0_top = old_rsp0_top;
|
||||
|
||||
kinfo("Leave\n");
|
||||
}
|
||||
|
||||
void sys_sigentry(uintptr_t entry) {
|
||||
struct thread *thr = thread_self;
|
||||
_assert(thr);
|
||||
|
||||
thr->signal_entry = entry;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user