From 4eb20628f355dd9dab54efc012bf76818071d972 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Wed, 19 Jun 2024 13:18:08 +0200 Subject: [PATCH] Move some of signal config to redox-rt. --- redox-rt/src/arch/aarch64.rs | 28 +++---- redox-rt/src/arch/x86.rs | 34 ++++----- redox-rt/src/arch/x86_64.rs | 61 ++++++++++----- redox-rt/src/lib.rs | 23 +++++- redox-rt/src/proc.rs | 2 +- redox-rt/src/signal.rs | 73 ++++++++++++++++++ src/macros.rs | 19 ----- src/platform/redox/clone.rs | 5 +- src/platform/redox/signal.rs | 139 ----------------------------------- src/start.rs | 2 +- 10 files changed, 166 insertions(+), 220 deletions(-) create mode 100644 redox-rt/src/signal.rs diff --git a/redox-rt/src/arch/aarch64.rs b/redox-rt/src/arch/aarch64.rs index 058ba028..8550bea9 100644 --- a/redox-rt/src/arch/aarch64.rs +++ b/redox-rt/src/arch/aarch64.rs @@ -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]); diff --git a/redox-rt/src/arch/x86.rs b/redox-rt/src/arch/x86.rs index c6addedb..56797839 100644 --- a/redox-rt/src/arch/x86.rs +++ b/redox-rt/src/arch/x86.rs @@ -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]); diff --git a/redox-rt/src/arch/x86_64.rs b/redox-rt/src/arch/x86_64.rs index 00bb7253..542b751d 100644 --- a/redox-rt/src/arch/x86_64.rs +++ b/redox-rt/src/arch/x86_64.rs @@ -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]); diff --git a/redox-rt/src/lib.rs b/redox-rt/src/lib.rs index 2bf6f31e..421695e1 100644 --- a/redox-rt/src/lib.rs +++ b/redox-rt/src/lib.rs @@ -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; diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index c6a82074..a01200fc 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -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")] diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs new file mode 100644 index 00000000..19932ec8 --- /dev/null +++ b/redox-rt/src/signal.rs @@ -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)) +} diff --git a/src/macros.rs b/src/macros.rs index 9e94e9e4..23f6809d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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(); - } - } -); diff --git a/src/platform/redox/clone.rs b/src/platform/redox/clone.rs index 408e117e..5ec6f778 100644 --- a/src/platform/redox/clone.rs +++ b/src/platform/redox/clone.rs @@ -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::*; diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index 25254ff2..3fa3c81e 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -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]); diff --git a/src/start.rs b/src/start.rs index 13528e99..dc0e3e26 100644 --- a/src/start.rs +++ b/src/start.rs @@ -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); -- GitLab