Files
banan-os/kernel/arch/i686/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

82 lines
1.3 KiB
ArmAsm

.section .userspace, "ax"
// stack contains
// (4 bytes) return address
// (4 bytes) return stack
// (4 bytes) return rflags
// (8 bytes) restore sigmask
// (36 bytes) siginfo_t
// (4 bytes) signal number
// (4 bytes) signal handler
.global signal_trampoline
signal_trampoline:
pushl %esi // gregs
pushl %edi
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl %ebp
// FIXME: populate these
xorl %eax, %eax
pushl %eax // stack
pushl %eax
pushl %eax
pushl %eax // sigset
pushl %eax
pushl %eax // link
movl %esp, %edx // ucontext
leal 60(%esp), %esi // siginfo
movl 56(%esp), %edi // signal number
movl 52(%esp), %eax // handlers
// align stack to 16 bytes
movl %esp, %ebp
andl $-16, %esp
subl $512, %esp
fxsave (%esp)
subl $4, %esp
pushl %edx
pushl %esi
pushl %edi
call *%eax
addl $16, %esp
fxrstor (%esp)
addl $512, %esp
// restore stack
movl %ebp, %esp
addl $24, %esp
// restore sigmask
movl $83, %eax // SYS_SIGPROCMASK
movl $3, %ebx // SIG_SETMASK
leal 72(%esp), %ecx // set
xorl %edx, %edx // oset
int $0xF0
// restore registers
popl %ebp
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %edi
popl %esi
// skip handler, number, siginfo_t, sigmask
addl $52, %esp
// restore flags
popf
movl (%esp), %esp
ret