Almost succeed at repeatedly accepting signals.
This commit is contained in:
+15
-11
@@ -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,
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user