Newer
Older
use syscall::{self, number::SYS_SIGRETURN, Result, SetSighandlerData, SignalStack};
use super::{
super::{types::*, Pal, PalSignal},
e, Sys,
};
use crate::{
header::{
signal::{sigaction, siginfo_t, sigset_t, stack_t},
platform::ERRNO,
unsafe fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
let path = match which {
ITIMER_REAL => "itimer:1",
ERRNO.set(EINVAL);
};
let fd = e(syscall::open(path, syscall::O_RDONLY | syscall::O_CLOEXEC));
return -1;
}
let mut spec = syscall::ITimerSpec::default();
let count = e(syscall::read(fd, &mut spec));
let _ = syscall::close(fd);
(*out).it_interval.tv_sec = spec.it_interval.tv_sec as time_t;
(*out).it_interval.tv_usec = spec.it_interval.tv_nsec / 1000;
(*out).it_value.tv_sec = spec.it_value.tv_sec as time_t;
(*out).it_value.tv_usec = spec.it_value.tv_nsec / 1000;
fn kill(pid: pid_t, sig: c_int) -> c_int {
e(syscall::kill(pid as usize, sig as usize)) as c_int
}
fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
e(syscall::kill(-(pgrp as isize) as usize, sig as usize)) as c_int
}
fn raise(sig: c_int) -> c_int {
Self::kill(Self::getpid(), sig)
unsafe fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
let path = match which {
ITIMER_REAL => "itimer:1",
ERRNO.set(EINVAL);
};
let fd = e(syscall::open(path, syscall::O_RDWR | syscall::O_CLOEXEC));
let mut spec = syscall::ITimerSpec::default();
let mut count = e(syscall::read(fd, &mut spec));
(*old).it_interval.tv_sec = spec.it_interval.tv_sec as time_t;
(*old).it_interval.tv_usec = spec.it_interval.tv_nsec / 1000;
(*old).it_value.tv_sec = spec.it_value.tv_sec as time_t;
(*old).it_value.tv_usec = spec.it_value.tv_nsec / 1000;
spec.it_interval.tv_sec = (*new).it_interval.tv_sec as i64;
spec.it_interval.tv_nsec = (*new).it_interval.tv_usec * 1000;
spec.it_value.tv_sec = (*new).it_value.tv_sec as i64;
spec.it_value.tv_nsec = (*new).it_value.tv_usec * 1000;
}
count = e(syscall::write(fd, &spec));
}
let _ = syscall::close(fd);
return -1;
}
0
}
fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int {
e(sigaction_impl(sig, act, oact).map(|()| 0)) as c_int
unsafe fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int {
unsafe fn sigpending(set: *mut sigset_t) -> c_int {
ERRNO.set(ENOSYS);
unsafe fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
e(sigprocmask_impl(how, set, oset).map(|()| 0)) as c_int
unsafe fn sigsuspend(set: *const sigset_t) -> c_int {
ERRNO.set(ENOSYS);
unsafe fn sigtimedwait(
set: *const sigset_t,
sig: *mut siginfo_t,
tp: *const timespec,
) -> c_int {
ERRNO.set(ENOSYS);
pub(crate) fn sigaction_impl(
sig: i32,
act: Option<&sigaction>,
oact: Option<&mut sigaction>,
) -> Result<()> {
let new_opt = act.map(|act| {
let sa_handler = unsafe { mem::transmute(act.sa_handler) };
syscall::SigAction {
sa_handler,
sa_mask: act.sa_mask as u64,
sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize)
.expect("sigaction: invalid bit pattern"),
}
});
let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default());
syscall::sigaction(sig as usize, new_opt.as_ref(), old_opt.as_mut())?;
if let (Some(old), Some(oact)) = (old_opt, oact) {
oact.sa_handler = unsafe { mem::transmute(old.sa_handler) };
oact.sa_mask = old.sa_mask as sigset_t;
oact.sa_flags = old.sa_flags.bits() as c_ulong;
}
Ok(())
}
pub(crate) unsafe fn sigprocmask_impl(
how: i32,
set: *const sigset_t,
oset: *mut sigset_t,
) -> Result<()> {
syscall::sigprocmask(how as usize, set.as_ref(), oset.as_mut())?;
Ok(())
}
#[cfg(target_arch = "x86_64")]
static CPUID_EAX1_ECX: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
pub fn sighandler_function() -> usize {
#[cfg(target_arch = "x86_64")]
// Check OSXSAVE bit
// TODO: HWCAP?
if CPUID_EAX1_ECX.load(core::sync::atomic::Ordering::Relaxed) & (1 << 27) != 0 {
__relibc_internal_sigentry_xsave as usize
__relibc_internal_sigentry_fxsave as usize
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#[cfg(any(target_arch = "x86", target_arch = "aarch64"))]
{
__relibc_internal_sigentry as usize
}
}
pub fn setup_sighandler() {
use core::mem::size_of;
// TODO
let altstack_base = 0_usize;
let altstack_len = 0_usize;
#[cfg(target_arch = "x86_64")]
{
let cpuid_eax1_ecx = unsafe { core::arch::x86_64::__cpuid(1) }.ecx;
CPUID_EAX1_ECX.store(cpuid_eax1_ecx, core::sync::atomic::Ordering::Relaxed);
}
let data = SetSighandlerData {
entry: sighandler_function(),
altstack_base,
altstack_len,
};
let fd = syscall::open(
"thisproc:current/sighandler",
syscall::O_WRONLY | syscall::O_CLOEXEC,
)
.expect("failed to open thisproc:current/sighandler");
syscall::write(fd, &data).expect("failed to write to thisproc:current/sighandler");
let _ = syscall::close(fd);
}
#[repr(C)]
pub struct SigStack {
#[cfg(target_arch = "x86_64")]
fx: [u8; 4096],
#[cfg(target_arch = "x86")]
fx: [u8; 512],
kernel_pushed: SignalStack,
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#[inline(always)]
unsafe fn inner(stack: &mut SigStack) {
let handler: extern "C" fn(c_int) = core::mem::transmute(stack.kernel_pushed.sa_handler);
handler(stack.kernel_pushed.sig_num as c_int)
}
#[cfg(not(target_arch = "x86"))]
unsafe extern "C" fn inner_c(stack: usize) {
inner(&mut *(stack as *mut SigStack))
}
#[cfg(target_arch = "x86")]
unsafe extern "fastcall" fn inner_fastcall(stack: usize) {
inner(&mut *(stack as *mut SigStack))
}
// TODO: is the memset necessary?
#[cfg(target_arch = "x86_64")]
asmfunction!(__relibc_internal_sigentry_xsave: ["
sub rsp, 4096
cld
mov rdi, rsp
xor eax, eax
mov ecx, 4096
rep stosb
mov eax, 0xffffffff
mov edx, eax
xsave [rsp]
mov rdi, rsp
call {inner}
mov eax, 0xffffffff
mov edx, eax
xrstor [rsp]
add rsp, 4096
mov eax, {SYS_SIGRETURN}
syscall
"] <= [inner = sym inner_c, SYS_SIGRETURN = const SYS_SIGRETURN]);
#[cfg(target_arch = "x86_64")]
asmfunction!(__relibc_internal_sigentry_fxsave: ["
sub rsp, 4096
fxsave64 [rsp]
mov rdi, rsp
call {inner}
fxrstor64 [rsp]
add rsp, 4096
mov eax, {SYS_SIGRETURN}
syscall
"] <= [inner = sym inner_c, SYS_SIGRETURN = const SYS_SIGRETURN]);
#[cfg(target_arch = "x86")]
asmfunction!(__relibc_internal_sigentry: ["
sub esp, 512
fxsave [esp]
mov ecx, esp
call {inner}
add esp, 512
"] <= [inner = sym inner_fastcall, SYS_SIGRETURN = const SYS_SIGRETURN]);
#[cfg(target_arch = "aarch64")]
asmfunction!(__relibc_internal_sigentry: ["
mov x0, sp
bl {inner}
mov x8, {SYS_SIGRETURN}
svc 0
"] <= [inner = sym inner_c, SYS_SIGRETURN = const SYS_SIGRETURN]);