1 use syscall::error::*; 2 3 use crate::{fork_inner, FdGuard}; 4 5 // Setup a stack starting from the very end of the address space, and then growing downwards. 6 pub(crate) const STACK_TOP: usize = 1 << 31; 7 pub(crate) const STACK_SIZE: usize = 1024 * 1024; 8 9 /// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS 10 /// is already initialized as if it was a thread. 11 pub unsafe fn deactivate_tcb(open_via_dup: usize) -> Result<()> { 12 let mut env = syscall::EnvRegisters::default(); 13 14 let file = FdGuard::new(syscall::dup(open_via_dup, b"regs/env")?); 15 16 env.fsbase = 0; 17 env.gsbase = 0; 18 19 let _ = syscall::write(*file, &mut env)?; 20 Ok(()) 21 } 22 23 pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> { 24 // Copy environment registers. 25 { 26 let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?); 27 let new_env_regs_fd = FdGuard::new(syscall::dup(new_pid_fd, b"regs/env")?); 28 29 let mut env_regs = syscall::EnvRegisters::default(); 30 let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?; 31 let _ = syscall::write(*new_env_regs_fd, &env_regs)?; 32 } 33 34 Ok(()) 35 } 36 37 #[no_mangle] 38 unsafe extern "cdecl" fn __relibc_internal_fork_impl(initial_rsp: *mut usize) -> usize { 39 Error::mux(fork_inner(initial_rsp)) 40 } 41 42 #[no_mangle] 43 unsafe extern "cdecl" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pid_fd: usize) { 44 let _ = syscall::close(cur_filetable_fd); 45 let _ = syscall::close(new_pid_fd); 46 } 47 48 //TODO: x86 49 core::arch::global_asm!( 50 " 51 .p2align 6 52 .globl __relibc_internal_fork_wrapper 53 .type __relibc_internal_fork_wrapper, @function 54 __relibc_internal_fork_wrapper: 55 push ebp 56 mov ebp, esp 57 58 // Push preserved registers 59 push ebx 60 push edi 61 push esi 62 push ebp 63 64 sub esp, 32 65 66 //TODO stmxcsr [esp+16] 67 fnstcw [esp+24] 68 69 push esp 70 call __relibc_internal_fork_impl 71 pop esp 72 jmp 2f 73 74 .size __relibc_internal_fork_wrapper, . - __relibc_internal_fork_wrapper 75 76 .p2align 6 77 .globl __relibc_internal_fork_ret 78 .type __relibc_internal_fork_ret, @function 79 __relibc_internal_fork_ret: 80 // Arguments already on the stack 81 call __relibc_internal_fork_hook 82 83 //TODO ldmxcsr [esp+16] 84 fldcw [esp+24] 85 86 xor eax, eax 87 88 .p2align 4 89 2: 90 add esp, 32 91 92 // Pop preserved registers 93 pop ebp 94 pop esi 95 pop edi 96 pop ebx 97 98 pop ebp 99 ret 100 101 .size __relibc_internal_fork_ret, . - __relibc_internal_fork_ret" 102 ); 103 104 extern "cdecl" { 105 pub(crate) fn __relibc_internal_fork_wrapper() -> usize; 106 pub(crate) fn __relibc_internal_fork_ret(); 107 } 108