Almost succeed at repeatedly accepting signals.

This commit is contained in:
4lDO2
2024-06-23 23:30:34 +02:00
parent d6588668e2
commit 98a2a566d9
3 changed files with 35 additions and 24 deletions
+15 -11
View File
@@ -150,13 +150,13 @@ asmfunction!(__relibc_internal_sigentry: ["
and eax, ecx
and eax, {SIGW1_PENDING_MASK}
bsf eax, eax
jnz 4f
jnz 7f
add eax, 32
2:
// By now we have selected a signal, stored in eax (6-bit). We now need to choose whether or
// not to switch to the alternate signal stack. If SA_ONSTACK is clear for this signal, then
// skip the sigaltstack logic.
bt fs:[{tcb_sa_off} + {sa_onstack}], edx
bt fs:[{tcb_sa_off} + {sa_onstack}], eax
jc 3f
// Otherwise, the altstack is already active. The sigaltstack being disabled, is equivalent
@@ -180,10 +180,10 @@ asmfunction!(__relibc_internal_sigentry: ["
4:
// Now that we have a stack, we can finally start initializing the signal stack!
push 0 // SS
push 0x23 // SS
push fs:[{tcb_sc_off} + {sc_saved_rsp}]
push fs:[{tcb_sc_off} + {sc_saved_rflags}]
push 0 // CS
push 0x2b // CS
push fs:[{tcb_sc_off} + {sc_saved_rip}]
push rdi
@@ -202,7 +202,7 @@ asmfunction!(__relibc_internal_sigentry: ["
push r14
push r15
push rdx // selected signal
push rax // selected signal
sub rsp, 4096 + 24
@@ -214,7 +214,7 @@ asmfunction!(__relibc_internal_sigentry: ["
// TODO: self-modifying?
cmp byte ptr [rip + {supports_xsave}], 0
je 3f
je 6f
mov eax, 0xffffffff
mov edx, eax
@@ -227,8 +227,8 @@ asmfunction!(__relibc_internal_sigentry: ["
mov edx, eax
xrstor [rsp]
add rsp, 4096 + 24
2:
5:
add rsp, 4096 + 32
pop r15
pop r14
pop r13
@@ -245,20 +245,24 @@ asmfunction!(__relibc_internal_sigentry: ["
pop rsi
pop rdi
iretq
/*
pop qword ptr fs:[{tcb_sa_off} + {sa_tmp}]
add rsp, 8
popfq
pop rsp
jmp qword ptr fs:[{tcb_sa_off} + {sa_tmp}]
3:
*/
6:
fxsave64 [rsp]
mov rdi, rsp
call {inner}
fxrstor64 [rsp]
jmp 2b
4:
jmp 5b
7:
ud2
// Spurious signal
"] <= [
inner = sym inner_c,
+8 -6
View File
@@ -795,6 +795,14 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
}
}
let buf = create_set_addr_space_buf(
*new_addr_space_fd,
__relibc_internal_fork_ret as usize,
initial_rsp as usize,
);
let _ = syscall::write(*new_addr_space_sel_fd, &buf)?;
}
{
// Reuse the same sigaltstack and signal entry (all memory will be re-mapped CoW later).
//
// Do this after the address space is cloned, since the kernel will get a shared
@@ -804,12 +812,6 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
let _ = syscall::write(*new_sighandler_fd, &crate::signal::current_setsighandler_struct())?;
}
let buf = create_set_addr_space_buf(
*new_addr_space_fd,
__relibc_internal_fork_ret as usize,
initial_rsp as usize,
);
let _ = syscall::write(*new_addr_space_sel_fd, &buf)?;
}
copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
}
+12 -7
View File
@@ -2,7 +2,7 @@ use core::cell::{Cell, UnsafeCell};
use core::ffi::c_int;
use core::sync::atomic::{AtomicU64, Ordering};
use syscall::{Error, IntRegisters, Result, SetSighandlerData, SigProcControl, Sigcontrol, EINVAL, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGW0_NOCLDSTOP_BIT, SIGW0_TSTP_IS_STOP_BIT, SIGW0_TTIN_IS_STOP_BIT, SIGW0_TTOU_IS_STOP_BIT, SIGWINCH};
use syscall::{Error, IntRegisters, Result, SetSighandlerData, SigProcControl, Sigcontrol, SigcontrolFlags, EINVAL, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGW0_NOCLDSTOP_BIT, SIGW0_TSTP_IS_STOP_BIT, SIGW0_TTIN_IS_STOP_BIT, SIGW0_TTOU_IS_STOP_BIT, SIGWINCH};
use crate::{arch::*, Tcb};
use crate::sync::Mutex;
@@ -28,25 +28,30 @@ pub fn sighandler_function() -> usize {
#[repr(C)]
pub struct SigStack {
sa_handler: usize,
sig_num: usize,
#[cfg(target_arch = "x86_64")]
fx: [u8; 4096],
#[cfg(target_arch = "x86")]
fx: [u8; 512],
_pad: [usize; 4], // pad to 192 = 3 * 64 bytes
_pad: [usize; 3], // pad to 192 = 3 * 64 = 168 + 24 bytes
sig_num: usize,
regs: IntRegisters, // 160 bytes currently
}
#[inline(always)]
unsafe fn inner(stack: &mut SigStack) {
// TODO: Set procmask based on SA_NODEFER, SA_RESETHAND, and sa_mask.
// Re-enable signals again.
let control_flags = &Tcb::current().unwrap().os_specific.control.control_flags;
control_flags.store(control_flags.load(Ordering::Relaxed) & !SigcontrolFlags::INHIBIT_DELIVERY.bits(), Ordering::Release);
core::sync::atomic::compiler_fence(Ordering::Acquire);
let _ = syscall::write(1, b"INNER SIGNAL HANDLER\n");
loop {}
/*loop {}
let handler: extern "C" fn(c_int) = core::mem::transmute(stack.sa_handler);
handler(stack.sig_num as c_int)
handler(stack.sig_num as c_int)*/
}
#[cfg(not(target_arch = "x86"))]
pub(crate) unsafe extern "C" fn inner_c(stack: usize) {