redox-exec: Move x86_64 specific things to arch module
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use self::x86_64::*;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod x86_64;
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user