这是我的旧问题的后续:通过 setcontext 从信号处理程序返回 https://stackoverflow.com/questions/69237910/returning-from-a-signal-handler-via-setcontext
我尝试编写程序集,用于在不需要更改阻塞信号的信号处理程序的内核协助(sigreturn 系统调用)的情况下,将上下文从信号处理程序切换回中断上下文(SA_NODEFER
).
到最后一点似乎是可行的(主要是重新加载寄存器):设置%rsp
and %rip
后退。
据我了解,如果有无红色区域,我可以这样做:
//use %rax to old %rsp, and %rcx as a scratch register
mov RSP_OFFSET(%rdi), %rax
// push old rip, rax, rcx, rdi using the scratch %rcx register
mov RIP_OFFSET(%rdi), %rcx
mov %rcx, -8(%rax)
mov RAX_OFFSET(%rdi), %rcx
mov %rcx, -16(%rax)
mov RCX_OFFSET(%rdi), %rcx
mov %rcx, -24(%rax)
mov RDI_OFFSET(%rdi), %rcx
mov %rcx, -32(%rax)
//make rax point to old_rsp - 32
lea -32(%rax), %rax
mov %rax, %rsp //restore rsp to that
//restore the pushed registers through actual popping
pop %rdi
pop %rcx
pop %rax
//pop and set %rip
ret
但是对于redzone来说,这似乎是不可能的,因为(?)没有办法原子地(相对于信号)并且没有寄存器使用从堆栈中弹出大量内容并跳转到存储在弹出部分深处的地址(或完全在某个地方)与备用信号堆栈的情况不同)。我查看了硬件任务切换,但 64 位保护模式不支持该功能。
这将如何应对即将到来的用户级中断?这些处理程序是否能够在不通过内核的情况下以某种方式返回?