Fix sigtimedwait realtime signals, almost handler too.
This commit is contained in:
+35
-10
@@ -7,11 +7,11 @@ use core::{
|
||||
use syscall::{
|
||||
data::{SigProcControl, Sigcontrol},
|
||||
error::*,
|
||||
RtSigInfo,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
proc::{fork_inner, FdGuard, ForkArgs},
|
||||
protocol::{ProcCall, RtSigInfo},
|
||||
signal::{get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
|
||||
Tcb,
|
||||
};
|
||||
@@ -29,6 +29,9 @@ pub struct SigArea {
|
||||
pub tmp_rdx: usize,
|
||||
pub tmp_rdi: usize,
|
||||
pub tmp_rsi: usize,
|
||||
pub tmp_r8: usize,
|
||||
pub tmp_r10: usize,
|
||||
pub tmp_r12: usize,
|
||||
pub tmp_rt_inf: RtSigInfo,
|
||||
pub tmp_id_inf: u64,
|
||||
|
||||
@@ -37,6 +40,7 @@ pub struct SigArea {
|
||||
pub disable_signals_depth: u64,
|
||||
pub last_sig_was_restart: bool,
|
||||
pub last_sigstack: Option<NonNull<SigStack>>,
|
||||
pub proc_fd: usize, // TODO: use global variable instead, fix linker errors
|
||||
}
|
||||
|
||||
#[repr(C, align(16))]
|
||||
@@ -188,6 +192,9 @@ asmfunction!(__relibc_internal_sigentry: ["
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_rdx}], rdx
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_rdi}], rdi
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_rsi}], rsi
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r8
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r10
|
||||
mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r12
|
||||
|
||||
// First, select signal, always pick first available bit
|
||||
1:
|
||||
@@ -225,14 +232,24 @@ asmfunction!(__relibc_internal_sigentry: ["
|
||||
jc 2f // if so, continue as usual
|
||||
|
||||
// otherwise, try (competitively) dequeueing realtime signal
|
||||
mov esi, eax
|
||||
mov eax, {SYS_SIGDEQUEUE}
|
||||
mov rdi, fs:[0]
|
||||
add rdi, {tcb_sa_off} + {sa_tmp_rt_inf} // out pointer of dequeued realtime sig
|
||||
|
||||
// SYS_CALL(fd, payload_base, payload_len, metadata_base, metadata_len | (flags << 8))
|
||||
// rax rdi rsi rdx r10 r8
|
||||
|
||||
mov r12d, eax
|
||||
mov rsi, fs:[0]
|
||||
mov rdi, [rsi+{tcb_sa_off}+{sa_proc_fd}]
|
||||
add rsi, {tcb_sa_off} + {sa_tmp_rt_inf} // out pointer of dequeued realtime sig
|
||||
mov rdx, {RTINF_SIZE}
|
||||
mov [rsi], eax
|
||||
lea r10, [rip + {proc_call_sigdeq}]
|
||||
mov r8, 1
|
||||
mov eax, {SYS_CALL}
|
||||
syscall
|
||||
ud2
|
||||
test eax, eax
|
||||
jnz 1b // assumes error can only be EAGAIN
|
||||
lea eax, [esi + 32]
|
||||
lea eax, [r12d + 32]
|
||||
jmp 9f
|
||||
2:
|
||||
mov edx, eax
|
||||
@@ -285,13 +302,13 @@ asmfunction!(__relibc_internal_sigentry: ["
|
||||
push fs:[{tcb_sa_off} + {sa_tmp_rdx}]
|
||||
push rcx
|
||||
push fs:[{tcb_sa_off} + {sa_tmp_rax}]
|
||||
push r8
|
||||
push fs:[{tcb_sa_off} + {sa_tmp_r8}]
|
||||
push r9
|
||||
push r10
|
||||
push fs:[{tcb_sa_off} + {sa_tmp_r10}]
|
||||
push r11
|
||||
push rbx
|
||||
push rbp
|
||||
push r12
|
||||
push fs:[{tcb_sa_off} + {sa_tmp_r12}]
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
@@ -418,10 +435,14 @@ __relibc_internal_sigentry_crit_third:
|
||||
sa_tmp_rdx = const offset_of!(SigArea, tmp_rdx),
|
||||
sa_tmp_rdi = const offset_of!(SigArea, tmp_rdi),
|
||||
sa_tmp_rsi = const offset_of!(SigArea, tmp_rsi),
|
||||
sa_tmp_r8 = const offset_of!(SigArea, tmp_r8),
|
||||
sa_tmp_r10 = const offset_of!(SigArea, tmp_r10),
|
||||
sa_tmp_r12 = const offset_of!(SigArea, tmp_r12),
|
||||
sa_tmp_rt_inf = const offset_of!(SigArea, tmp_rt_inf),
|
||||
sa_tmp_id_inf = const offset_of!(SigArea, tmp_id_inf),
|
||||
sa_altstack_top = const offset_of!(SigArea, altstack_top),
|
||||
sa_altstack_bottom = const offset_of!(SigArea, altstack_bottom),
|
||||
sa_proc_fd = const offset_of!(SigArea, proc_fd),
|
||||
sc_saved_rflags = const offset_of!(Sigcontrol, saved_archdep_reg),
|
||||
sc_saved_rip = const offset_of!(Sigcontrol, saved_ip),
|
||||
sc_word = const offset_of!(Sigcontrol, word),
|
||||
@@ -437,7 +458,9 @@ __relibc_internal_sigentry_crit_third:
|
||||
REDZONE_SIZE = const 128,
|
||||
STACK_ALIGN = const 16,
|
||||
SA_ONSTACK_BIT = const 58, // (1 << 58) >> 32 = 0x0400_0000
|
||||
SYS_SIGDEQUEUE = const syscall::SYS_SIGDEQUEUE,
|
||||
SYS_CALL = const syscall::SYS_CALL,
|
||||
proc_call_sigdeq = sym PROC_CALL_SIGDEQ,
|
||||
RTINF_SIZE = const size_of::<RtSigInfo>(),
|
||||
]);
|
||||
|
||||
extern "C" {
|
||||
@@ -503,3 +526,5 @@ pub fn current_sp() -> usize {
|
||||
}
|
||||
sp
|
||||
}
|
||||
|
||||
static PROC_CALL_SIGDEQ: u64 = ProcCall::Sigdeq as u64;
|
||||
|
||||
+5
-7
@@ -17,7 +17,11 @@ use core::{
|
||||
use generic_rt::{ExpectTlsFree, GenericTcb};
|
||||
use syscall::Sigcontrol;
|
||||
|
||||
use self::{proc::FdGuard, protocol::ProcMeta, sync::Mutex};
|
||||
use self::{
|
||||
proc::{FdGuard, STATIC_PROC_INFO},
|
||||
protocol::ProcMeta,
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
@@ -235,12 +239,6 @@ struct DynamicProcInfo {
|
||||
sgid: u32,
|
||||
}
|
||||
|
||||
static STATIC_PROC_INFO: SyncUnsafeCell<StaticProcInfo> = SyncUnsafeCell::new(StaticProcInfo {
|
||||
pid: 0,
|
||||
ppid: 0,
|
||||
proc_fd: MaybeUninit::uninit(),
|
||||
has_proc_fd: false,
|
||||
});
|
||||
static DYNAMIC_PROC_INFO: Mutex<DynamicProcInfo> = Mutex::new(DynamicProcInfo {
|
||||
pgid: u32::MAX,
|
||||
ruid: u32::MAX,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use core::{
|
||||
cell::SyncUnsafeCell,
|
||||
fmt::Debug,
|
||||
mem::{size_of, MaybeUninit},
|
||||
};
|
||||
@@ -9,7 +10,7 @@ use crate::{
|
||||
protocol::{ProcCall, ThreadCall},
|
||||
read_proc_meta, static_proc_info,
|
||||
sys::{proc_call, thread_call},
|
||||
RtTcb, DYNAMIC_PROC_INFO, STATIC_PROC_INFO,
|
||||
RtTcb, StaticProcInfo, DYNAMIC_PROC_INFO,
|
||||
};
|
||||
|
||||
use alloc::{boxed::Box, collections::BTreeMap, vec};
|
||||
@@ -983,3 +984,10 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
|
||||
managed_thr_fd,
|
||||
]
|
||||
}
|
||||
pub(crate) static STATIC_PROC_INFO: SyncUnsafeCell<StaticProcInfo> =
|
||||
SyncUnsafeCell::new(StaticProcInfo {
|
||||
pid: 0,
|
||||
ppid: 0,
|
||||
proc_fd: MaybeUninit::zeroed(),
|
||||
has_proc_fd: false,
|
||||
});
|
||||
|
||||
@@ -33,6 +33,7 @@ pub enum ProcCall {
|
||||
|
||||
// TODO: replace with sendfd equivalent syscall for sending memory
|
||||
SyncSigPctl = 10,
|
||||
Sigdeq = 11,
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(usize)]
|
||||
@@ -57,6 +58,7 @@ impl ProcCall {
|
||||
8 => Self::Kill,
|
||||
9 => Self::Sigq,
|
||||
10 => Self::SyncSigPctl,
|
||||
11 => Self::Sigdeq,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -147,3 +149,12 @@ impl ProcKillTarget {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub struct RtSigInfo {
|
||||
pub arg: usize,
|
||||
pub code: i32,
|
||||
pub uid: u32,
|
||||
pub pid: u32, // TODO: usize?
|
||||
}
|
||||
unsafe impl plain::Plain for RtSigInfo {}
|
||||
|
||||
+23
-10
@@ -1,13 +1,19 @@
|
||||
use core::{ffi::c_int, mem::MaybeUninit, ptr::NonNull, sync::atomic::Ordering};
|
||||
use core::{ffi::c_int, ptr::NonNull, sync::atomic::Ordering};
|
||||
|
||||
use syscall::{
|
||||
data::AtomicU64, CallFlags, Error, RawAction, Result, RtSigInfo, SenderInfo, SetSighandlerData,
|
||||
data::AtomicU64, CallFlags, Error, RawAction, Result, SenderInfo, SetSighandlerData,
|
||||
SigProcControl, Sigcontrol, SigcontrolFlags, TimeSpec, EAGAIN, EINTR, EINVAL, ENOMEM, EPERM,
|
||||
SIGCHLD, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::this_thread_call, RtTcb, Tcb,
|
||||
arch::*,
|
||||
proc::FdGuard,
|
||||
protocol::{ProcCall, RtSigInfo, ThreadCall},
|
||||
static_proc_info,
|
||||
sync::Mutex,
|
||||
sys::{proc_call, this_thread_call},
|
||||
RtTcb, Tcb,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@@ -558,6 +564,11 @@ pub fn setup_sighandler(tcb: &RtTcb) {
|
||||
// equivalent to not using any altstack at all (the default).
|
||||
arch.altstack_top = usize::MAX;
|
||||
arch.altstack_bottom = 0;
|
||||
/*#[cfg(target_arch = "x86_64")]
|
||||
unsafe {
|
||||
assert!(static_proc_info().has_proc_fd);
|
||||
arch.proc_fd = **static_proc_info().proc_fd.assume_init_ref();
|
||||
}*/
|
||||
// TODO
|
||||
#[cfg(any(target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
{
|
||||
@@ -774,15 +785,17 @@ fn try_claim_single(sig_idx: u32, thread_control: Option<&Sigcontrol>) -> Option
|
||||
|
||||
if sig_group == 1 && thread_control.is_none() {
|
||||
// Queued (realtime) signal
|
||||
let mut ret = MaybeUninit::<RtSigInfo>::uninit();
|
||||
let rt_inf = unsafe {
|
||||
syscall::syscall2(
|
||||
syscall::SYS_SIGDEQUEUE,
|
||||
ret.as_mut_ptr() as usize,
|
||||
sig_idx as usize - 32,
|
||||
let rt_inf: RtSigInfo = unsafe {
|
||||
let mut buf = [0_u8; size_of::<RtSigInfo>()];
|
||||
buf[..4].copy_from_slice(&(sig_idx - 32).to_ne_bytes());
|
||||
proc_call(
|
||||
**static_proc_info().proc_fd.assume_init_ref(),
|
||||
&mut buf,
|
||||
CallFlags::empty(),
|
||||
&[ProcCall::Sigdeq as usize],
|
||||
)
|
||||
.ok()?;
|
||||
ret.assume_init()
|
||||
core::mem::transmute(buf)
|
||||
};
|
||||
Some(SiginfoAbi {
|
||||
si_signo: sig_idx as i32 + 1,
|
||||
|
||||
+4
-4
@@ -6,12 +6,12 @@ use core::{
|
||||
|
||||
use syscall::{
|
||||
error::{Error, Result, EINTR},
|
||||
CallFlags, RtSigInfo, TimeSpec, EINVAL, ERESTART,
|
||||
CallFlags, TimeSpec, EINVAL, ERESTART,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::manually_enter_trampoline,
|
||||
protocol::{ProcCall, ProcKillTarget, ThreadCall, WaitFlags},
|
||||
protocol::{ProcCall, ProcKillTarget, RtSigInfo, ThreadCall, WaitFlags},
|
||||
signal::tmp_disable_signals,
|
||||
DynamicProcInfo, RtTcb, Tcb, DYNAMIC_PROC_INFO,
|
||||
};
|
||||
@@ -69,9 +69,9 @@ pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> {
|
||||
uid: 0, // TODO
|
||||
pid: posix_getpid(),
|
||||
};
|
||||
match wrapper(false, false, || {
|
||||
match wrapper(false, true, || {
|
||||
this_proc_call(
|
||||
&mut siginf,
|
||||
unsafe { plain::as_mut_bytes(&mut siginf) },
|
||||
CallFlags::empty(),
|
||||
&[ProcCall::Sigq as usize, pid, sig],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user