Move some of signal config to redox-rt.

This commit is contained in:
4lDO2
2024-06-19 13:18:08 +02:00
parent a800693266
commit 4eb20628f3
10 changed files with 166 additions and 220 deletions
+10 -18
View File
@@ -44,12 +44,7 @@ unsafe extern "C" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pi
let _ = syscall::close(new_pid_fd);
}
core::arch::global_asm!(
"
.p2align 6
.globl __relibc_internal_fork_wrapper
.type __relibc_internal_fork_wrapper, @function
__relibc_internal_fork_wrapper:
asmfunction!(__relibc_internal_fork_wrapper: ["
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
stp x25, x26, [sp, #-16]!
@@ -64,13 +59,9 @@ __relibc_internal_fork_wrapper:
mov x0, sp
bl __relibc_internal_fork_impl
b 2f
"]);
.size __relibc_internal_fork_wrapper, . - __relibc_internal_fork_wrapper
.p2align 6
.globl __relibc_internal_fork_ret
.type __relibc_internal_fork_ret, @function
__relibc_internal_fork_ret:
asmfunction!(__relibc_internal_fork_hook: ["
ldp x0, x1, [sp]
bl __relibc_internal_fork_hook
@@ -89,11 +80,12 @@ __relibc_internal_fork_ret:
ldp x29, x30, [sp], #16
ret
"]);
.size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret"
);
asmfunction!(__relibc_internal_sigentry: ["
mov x0, sp
bl {inner}
extern "C" {
pub(crate) fn __relibc_internal_fork_wrapper() -> usize;
pub(crate) fn __relibc_internal_fork_ret();
}
mov x8, {SYS_SIGRETURN}
svc 0
"] <= [inner = sym inner_c, SYS_SIGRETURN = const SYS_SIGRETURN]);
+15 -19
View File
@@ -45,13 +45,7 @@ unsafe extern "cdecl" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, ne
let _ = syscall::close(new_pid_fd);
}
//TODO: x86
core::arch::global_asm!(
"
.p2align 6
.globl __relibc_internal_fork_wrapper
.type __relibc_internal_fork_wrapper, @function
__relibc_internal_fork_wrapper:
asmfunction!(__relibc_internal_fork_wrapper: ["
push ebp
mov ebp, esp
@@ -70,13 +64,9 @@ __relibc_internal_fork_wrapper:
call __relibc_internal_fork_impl
pop esp
jmp 2f
"] <= []);
.size __relibc_internal_fork_wrapper, . - __relibc_internal_fork_wrapper
.p2align 6
.globl __relibc_internal_fork_ret
.type __relibc_internal_fork_ret, @function
__relibc_internal_fork_ret:
asmfunction!(__relibc_internal_fork_ret: ["
// Arguments already on the stack
call __relibc_internal_fork_hook
@@ -97,11 +87,17 @@ __relibc_internal_fork_ret:
pop ebp
ret
"] <= []);
asmfunction!(__relibc_internal_sigentry: ["
sub esp, 512
fxsave [esp]
.size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret"
);
mov ecx, esp
call {inner}
extern "cdecl" {
pub(crate) fn __relibc_internal_fork_wrapper() -> usize;
pub(crate) fn __relibc_internal_fork_ret();
}
add esp, 512
fxrstor [esp]
mov eax, {SYS_SIGRETURN}
int 0x80
"] <= [inner = sym inner_fastcall, SYS_SIGRETURN = const SYS_SIGRETURN]);
+43 -18
View File
@@ -1,6 +1,8 @@
use syscall::number::SYS_SIGRETURN;
use syscall::error::*;
use crate::proc::{fork_inner, FdGuard};
use crate::signal::inner_c;
// Setup a stack starting from the very end of the address space, and then growing downwards.
pub(crate) const STACK_TOP: usize = 1 << 47;
@@ -45,12 +47,7 @@ unsafe extern "sysv64" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, n
let _ = syscall::close(new_pid_fd);
}
core::arch::global_asm!(
"
.p2align 6
.globl __relibc_internal_fork_wrapper
.type __relibc_internal_fork_wrapper, @function
__relibc_internal_fork_wrapper:
asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
push rbp
mov rbp, rsp
@@ -70,12 +67,8 @@ __relibc_internal_fork_wrapper:
call __relibc_internal_fork_impl
jmp 2f
.size __relibc_internal_fork_wrapper, . - __relibc_internal_fork_wrapper
.p2align 6
.globl __relibc_internal_fork_ret
.type __relibc_internal_fork_ret, @function
__relibc_internal_fork_ret:
"] <= []);
asmfunction!(__relibc_internal_fork_ret: ["
mov rdi, [rsp]
mov rsi, [rsp + 8]
call __relibc_internal_fork_hook
@@ -97,11 +90,43 @@ __relibc_internal_fork_ret:
pop rbp
ret
"] <= []);
// TODO: is the memset necessary?
asmfunction!(__relibc_internal_sigentry_fxsave: ["
sub rsp, 4096
.size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret"
);
fxsave64 [rsp]
extern "sysv64" {
pub(crate) fn __relibc_internal_fork_wrapper() -> usize;
pub(crate) fn __relibc_internal_fork_ret();
}
mov rdi, rsp
call {inner}
fxrstor64 [rsp]
add rsp, 4096
mov eax, {SYS_SIGRETURN}
syscall
"] <= [inner = sym inner_c, SYS_SIGRETURN = const SYS_SIGRETURN]);
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]);
+22 -1
View File
@@ -1,12 +1,33 @@
#![no_std]
#![feature(array_chunks, int_roundings, let_chains, slice_ptr_get)]
#![feature(asm_const, array_chunks, int_roundings, let_chains, slice_ptr_get)]
#![forbid(unreachable_patterns)]
extern crate alloc;
#[macro_export]
macro_rules! asmfunction(
($name:ident $(-> $ret:ty)? : [$($asmstmt:expr),*$(,)?] <= [$($decl:ident = $(sym $symname:ident)?$(const $constval:expr)?),*$(,)?]$(,)? ) => {
::core::arch::global_asm!(concat!("
.p2align 4
.section .text.", stringify!($name), ", \"ax\", @progbits
.globl ", stringify!($name), "
.type ", stringify!($name), ", @function
", stringify!($name), ":
", $($asmstmt, "\n",)* "
.size ", stringify!($name), ", . - ", stringify!($name), "
"), $($decl = $(sym $symname)?$(const $constval)?),*);
extern "C" {
pub fn $name() $(-> $ret)?;
}
}
);
pub mod arch;
pub mod proc;
// TODO: Replace auxvs with a non-stack-based interface, but keep getauxval for compatibility
#[path = "../../src/platform/auxv_defs.rs"]
pub mod auxv_defs;
pub mod signal;
+1 -1
View File
@@ -795,7 +795,7 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
continue;
}
let mut buf;
let buf;
// TODO: write! using some #![no_std] Cursor type (tracking the length)?
#[cfg(target_pointer_width = "64")]
+73
View File
@@ -0,0 +1,73 @@
use core::ffi::c_int;
use crate::arch::*;
#[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
} else {
__relibc_internal_sigentry_fxsave as usize
}
#[cfg(any(target_arch = "x86", target_arch = "aarch64"))]
{
__relibc_internal_sigentry as usize
}
}
pub fn setup_sighandler() {
// 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 = syscall::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: syscall::SignalStack,
}
#[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"))]
pub(crate) 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))
}
-19
View File
@@ -352,22 +352,3 @@ macro_rules! strto_float_impl {
}
}};
}
#[macro_export]
macro_rules! asmfunction(
($name:ident : [$($asmstmt:expr),*$(,)?] <= [$($decl:ident = $(sym $symname:ident)?$(const $constval:expr)?),*$(,)?]$(,)? ) => {
::core::arch::global_asm!(concat!("
.p2align 4
.section .text.", stringify!($name), ", \"ax\", @progbits
.globl ", stringify!($name), "
.type ", stringify!($name), ", @function
", stringify!($name), ":
", $($asmstmt, "\n",)* "
.size ", stringify!($name), ", . - ", stringify!($name), "
"), $($decl = $(sym $symname)?$(const $constval)?),*);
extern "C" {
pub fn $name();
}
}
);
+1 -4
View File
@@ -9,10 +9,7 @@ use syscall::{
use crate::sync::rwlock::Rwlock;
use super::{
extra::FdGuard,
signal::sighandler_function,
};
use redox_rt::{proc::FdGuard, signal::sighandler_function};
pub use redox_rt::proc::*;
-139
View File
@@ -135,7 +135,6 @@ impl PalSignal for Sys {
-1
}
}
pub(crate) fn sigaction_impl(
sig: i32,
act: Option<&sigaction>,
@@ -167,141 +166,3 @@ pub(crate) unsafe fn sigprocmask_impl(
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
} else {
__relibc_internal_sigentry_fxsave as usize
}
#[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,
}
#[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
fxrstor [esp]
mov eax, {SYS_SIGRETURN}
int 0x80
"] <= [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]);
+1 -1
View File
@@ -183,7 +183,7 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
platform::environ = platform::OUR_ENVIRON.as_mut_ptr();
}
#[cfg(target_os = "redox")]
platform::sys::signal::setup_sighandler();
redox_rt::signal::setup_sighandler();
let auxvs = get_auxvs(sp.auxv().cast());
crate::platform::init(auxvs);