diff --git a/src/platform/redox/clone.rs b/src/platform/redox/clone.rs index 4500712fa615b28caf1447289d7fedf177426362..43d8dcadf89189513b5af17e159347bd78ebbead 100644 --- a/src/platform/redox/clone.rs +++ b/src/platform/redox/clone.rs @@ -68,6 +68,23 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> { Ok(0) } +//TODO +#[cfg(target_arch = "x86")] +core::arch::global_asm!(" + .globl __relibc_internal_pte_clone_ret + .type __relibc_internal_pte_clone_ret, @function + .p2align 6 +__relibc_internal_pte_clone_ret: + ud2 + + .size __relibc_internal_pte_clone_ret, . - __relibc_internal_pte_clone_ret +"); + +#[cfg(target_arch = "x86")] +extern "cdecl" { + fn __relibc_internal_pte_clone_ret(); +} + #[cfg(target_arch = "x86_64")] core::arch::global_asm!(" .globl __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 index 0561095fc2bf45cc63ae6a4721e8da3e2a17fb88..5a2e7325598ee9570191d5d9b973029ce630ba9d 100644 --- a/src/platform/redox/redox-exec/src/arch/mod.rs +++ b/src/platform/redox/redox-exec/src/arch/mod.rs @@ -1,3 +1,8 @@ +#[cfg(target_arch = "x86")] +pub use self::x86::*; +#[cfg(target_arch = "x86")] +pub mod x86; + #[cfg(target_arch = "x86_64")] pub use self::x86_64::*; #[cfg(target_arch = "x86_64")] diff --git a/src/platform/redox/redox-exec/src/arch/x86.rs b/src/platform/redox/redox-exec/src/arch/x86.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1700a85d024686cd5a1f066b8a46ad9d92fa752 --- /dev/null +++ b/src/platform/redox/redox-exec/src/arch/x86.rs @@ -0,0 +1,70 @@ +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 << 31; +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 "cdecl" fn __relibc_internal_fork_impl(initial_rsp: *mut usize) -> usize { + Error::mux(fork_inner(initial_rsp)) +} + +#[no_mangle] +unsafe extern "cdecl" 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); +} + +//TODO +core::arch::global_asm!(" + .p2align 6 + .globl __relibc_internal_fork_wrapper + .type __relibc_internal_fork_wrapper, @function +__relibc_internal_fork_wrapper: + ud2 + + .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: + ud2 + + .size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret" +); + +extern "cdecl" { + pub(crate) fn __relibc_internal_fork_wrapper() -> usize; + pub(crate) fn __relibc_internal_fork_ret(); +}