Files
banan-os/kernel/arch/x86_64/Signal.S
Bananymous 8ca3c5d778 Kernel: Clean up signal handling
We now appreciate sa_mask and SA_NODEFER and change the signal mask for
the duration of signal handler. This is done by making a sigprocmask
syscall at the end of the signal handler. Back-to-back signals will
still grow stack as original registers are popped AFTER the block mask
is updated. I guess this is why linux has sigreturn(?).
2026-04-05 02:25:59 +03:00

93 lines
1.4 KiB
ArmAsm

.section .userspace, "ax"
// stack contains
// (8 bytes) return address
// (8 bytes) return stack
// (8 bytes) return rflags
// (8 bytes) restore sigmask
// (56 bytes) siginfo_t
// (8 bytes) signal number
// (8 bytes) signal handler
.global signal_trampoline
signal_trampoline:
pushq %r15 // gregs
pushq %r14
pushq %r13
pushq %r12
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rsi
pushq %rdi
pushq %rdx
pushq %rcx
pushq %rbx
pushq %rax
pushq %rbp
// FIXME: populate these
xorq %rax, %rax
pushq %rax // stack
pushq %rax
pushq %rax
pushq %rax // sigset
pushq %rax // link
movq %rsp, %rdx // ucontext
leaq 176(%rsp), %rsi // siginfo
movq 168(%rsp), %rdi // signal number
movq 160(%rsp), %rax // handler
// align stack to 16 bytes
movq %rsp, %rbp
andq $-16, %rsp
subq $512, %rsp
fxsave64 (%rsp)
call *%rax
fxrstor64 (%rsp)
addq $512, %rsp
// restore stack
movq %rbp, %rsp
addq $40, %rsp
// restore sigmask
movq $83, %rdi // SYS_SIGPROCMASK
movq $3, %rsi // SIG_SETMASK
leaq 192(%rsp), %rdx // set
xorq %r10, %r10 // oset
syscall
// restore registers
popq %rbp
popq %rax
popq %rbx
popq %rcx
popq %rdx
popq %rdi
popq %rsi
popq %r8
popq %r9
popq %r10
popq %r11
popq %r12
popq %r13
popq %r14
popq %r15
// skip handler, number, siginfo_t, sigmask
addq $80, %rsp
// restore flags
popfq
movq (%rsp), %rsp
// return over red-zone
ret $128