From 05e3a5ac8bd6335d97fded605eeaeea9a52715d0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Thu, 28 Jul 2022 08:08:01 -0600 Subject: [PATCH] redox-exec: Move x86_64 specific things to arch module --- src/platform/redox/clone.rs | 4 +- src/platform/redox/redox-exec/src/arch/mod.rs | 4 + .../redox/redox-exec/src/arch/x86_64.rs | 106 ++++++++++++++++++ src/platform/redox/redox-exec/src/lib.rs | 105 +---------------- 4 files changed, 116 insertions(+), 103 deletions(-) create mode 100644 src/platform/redox/redox-exec/src/arch/mod.rs create mode 100644 src/platform/redox/redox-exec/src/arch/x86_64.rs diff --git a/src/platform/redox/clone.rs b/src/platform/redox/clone.rs index ba5dcc49..4500712f 100644 --- a/src/platform/redox/clone.rs +++ b/src/platform/redox/clone.rs @@ -61,13 +61,14 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> { copy_env_regs(*cur_pid_fd, *new_pid_fd)?; - // Unblock context. + // Unblock context. syscall::kill(new_pid, SIGCONT)?; let _ = syscall::waitpid(new_pid, &mut 0, syscall::WUNTRACED | syscall::WCONTINUED); Ok(0) } +#[cfg(target_arch = "x86_64")] core::arch::global_asm!(" .globl __relibc_internal_pte_clone_ret .type __relibc_internal_pte_clone_ret, @function @@ -98,6 +99,7 @@ __relibc_internal_pte_clone_ret: .size __relibc_internal_pte_clone_ret, . - __relibc_internal_pte_clone_ret "); +#[cfg(target_arch = "x86_64")] extern "sysv64" { fn __relibc_internal_pte_clone_ret(); } diff --git a/src/platform/redox/redox-exec/src/arch/mod.rs b/src/platform/redox/redox-exec/src/arch/mod.rs new file mode 100644 index 00000000..0561095f --- /dev/null +++ b/src/platform/redox/redox-exec/src/arch/mod.rs @@ -0,0 +1,4 @@ +#[cfg(target_arch = "x86_64")] +pub use self::x86_64::*; +#[cfg(target_arch = "x86_64")] +pub mod x86_64; diff --git a/src/platform/redox/redox-exec/src/arch/x86_64.rs b/src/platform/redox/redox-exec/src/arch/x86_64.rs new file mode 100644 index 00000000..69e61aa7 --- /dev/null +++ b/src/platform/redox/redox-exec/src/arch/x86_64.rs @@ -0,0 +1,106 @@ +use syscall::error::*; + +use crate::{FdGuard, fork_inner}; + +// Setup a stack starting from the very end of the address space, and then growing downwards. +pub(crate) const STACK_TOP: usize = 1 << 47; +pub(crate) const STACK_SIZE: usize = 1024 * 1024; + +/// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS +/// is already initialized as if it was a thread. +pub unsafe fn deactivate_tcb(open_via_dup: usize) -> Result<()> { + let mut env = syscall::EnvRegisters::default(); + + let file = FdGuard::new(syscall::dup(open_via_dup, b"regs/env")?); + + env.fsbase = 0; + env.gsbase = 0; + + let _ = syscall::write(*file, &mut env)?; + Ok(()) +} + +pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> { + // Copy environment registers. + { + let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?); + let new_env_regs_fd = FdGuard::new(syscall::dup(new_pid_fd, b"regs/env")?); + + let mut env_regs = syscall::EnvRegisters::default(); + let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?; + let _ = syscall::write(*new_env_regs_fd, &env_regs)?; + } + + Ok(()) +} + +#[no_mangle] +unsafe extern "sysv64" fn __relibc_internal_fork_impl(initial_rsp: *mut usize) -> usize { + Error::mux(fork_inner(initial_rsp)) +} + +#[no_mangle] +unsafe extern "sysv64" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pid_fd: usize) { + let _ = syscall::close(cur_filetable_fd); + 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: + push rbp + mov rbp, rsp + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + sub rsp, 32 + + stmxcsr [rsp+16] + fnstcw [rsp+24] + + mov rdi, rsp + 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: + mov rdi, [rsp] + mov rsi, [rsp + 8] + call __relibc_internal_fork_hook + + ldmxcsr [rsp+16] + fldcw [rsp+24] + + xor rax, rax + + .p2align 4 +2: + add rsp, 32 + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + + pop rbp + ret + + .size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret" +); + +extern "sysv64" { + pub(crate) fn __relibc_internal_fork_wrapper() -> usize; + pub(crate) fn __relibc_internal_fork_ret(); +} diff --git a/src/platform/redox/redox-exec/src/lib.rs b/src/platform/redox/redox-exec/src/lib.rs index ffefb86a..99f08f5e 100644 --- a/src/platform/redox/redox-exec/src/lib.rs +++ b/src/platform/redox/redox-exec/src/lib.rs @@ -13,12 +13,13 @@ use alloc::{ }; use syscall::{ + PAGE_SIZE, error::*, flag::{MapFlags, SEEK_SET}, }; -#[cfg(target_arch = "x86_64")] -const PAGE_SIZE: usize = 4096; +pub use self::arch::*; +mod arch; pub enum FexecResult { Normal { addrspace_handle: FdGuard }, @@ -139,9 +140,6 @@ where _ => continue, } } - // Setup a stack starting from the very end of the address space, and then growing downwards. - const STACK_TOP: usize = 1 << 47; - const STACK_SIZE: usize = 1024 * 1024; allocate_remote(&grants_fd, memory_scheme_fd, STACK_TOP - STACK_SIZE, STACK_SIZE, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?; tree.insert(STACK_TOP - STACK_SIZE, STACK_SIZE); @@ -352,20 +350,6 @@ fn find_free_target_addr(tree: &BTreeMap<usize, usize>, size: usize) -> Option<u None } -/// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS -/// is already initialized as if it was a thread. -#[cfg(all(target_os = "redox", target_arch = "x86_64"))] -pub unsafe fn deactivate_tcb(open_via_dup: usize) -> Result<()> { - let mut env = syscall::EnvRegisters::default(); - - let file = FdGuard::new(syscall::dup(open_via_dup, b"regs/env")?); - - env.fsbase = 0; - env.gsbase = 0; - - let _ = syscall::write(*file, &mut env)?; - Ok(()) -} pub struct FdGuard { fd: usize, @@ -527,75 +511,7 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { Ok(new_pid) } -#[no_mangle] -unsafe extern "sysv64" fn __relibc_internal_fork_impl(initial_rsp: *mut usize) -> usize { - Error::mux(fork_inner(initial_rsp)) -} -#[no_mangle] -unsafe extern "sysv64" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pid_fd: usize) { - let _ = syscall::close(cur_filetable_fd); - let _ = syscall::close(new_pid_fd); -} -#[no_mangle] -core::arch::global_asm!(" - .p2align 6 - .globl __relibc_internal_fork_wrapper - .type __relibc_internal_fork_wrapper, @function -__relibc_internal_fork_wrapper: - push rbp - mov rbp, rsp - - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - - sub rsp, 32 - - stmxcsr [rsp+16] - fnstcw [rsp+24] - - mov rdi, rsp - call __relibc_internal_fork_impl - jmp 2f - - .size __relibc_internal_fork_wrapper, . - __relibc_internal_fork_wrapper - - .p2align 6 - .type __relibc_internal_fork_ret, @function -__relibc_internal_fork_ret: - mov rdi, [rsp] - mov rsi, [rsp + 8] - call __relibc_internal_fork_hook - - ldmxcsr [rsp+16] - fldcw [rsp+24] - - xor rax, rax - - .p2align 4 -2: - add rsp, 32 - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - - pop rbp - ret - - .size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret" -); - -extern "sysv64" { - fn __relibc_internal_fork_wrapper() -> usize; - fn __relibc_internal_fork_ret(); -} pub fn new_context() -> Result<(FdGuard, usize)> { // Create a new context (fields such as uid/gid will be inherited from the current context). let fd = FdGuard::new(syscall::open("thisproc:new/open_via_dup", syscall::O_CLOEXEC)?); @@ -627,18 +543,3 @@ pub fn copy_str(cur_pid_fd: usize, new_pid_fd: usize, key: &str) -> Result<()> { Ok(()) } -#[cfg(target_arch = "x86_64")] -pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> { - // Copy environment registers. - { - let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?); - let new_env_regs_fd = FdGuard::new(syscall::dup(new_pid_fd, b"regs/env")?); - - let mut env_regs = syscall::EnvRegisters::default(); - let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?; - let _ = syscall::write(*new_env_regs_fd, &env_regs)?; - } - - Ok(()) -} - -- GitLab