Reach init fork
This commit is contained in:
@@ -95,7 +95,7 @@ pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe extern "sysv64" fn fork_impl(initial_rsp: *mut usize, args: &ForkArgs) -> usize {
|
||||
unsafe extern "sysv64" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) -> usize {
|
||||
Error::mux(fork_inner(initial_rsp, args))
|
||||
}
|
||||
|
||||
@@ -131,8 +131,8 @@ asmfunction!(__relibc_internal_fork_wrapper (usize) -> usize: ["
|
||||
stmxcsr [rsp+32]
|
||||
fnstcw [rsp+40]
|
||||
|
||||
mov rdi, rsp
|
||||
// rsi: &ForkArgs
|
||||
// rdi: &ForkArgs
|
||||
mov rsi, rsp
|
||||
call {fork_impl}
|
||||
|
||||
add rsp, 96
|
||||
|
||||
+2
-8
@@ -183,15 +183,9 @@ pub(crate) fn read_proc_meta(proc: &FdGuard) -> syscall::Result<ProcMeta> {
|
||||
let _ = syscall::read(**proc, &mut bytes)?;
|
||||
Ok(*plain::from_bytes::<ProcMeta>(&bytes).unwrap())
|
||||
}
|
||||
pub unsafe fn initialize(
|
||||
#[cfg(feature = "proc")] proc_fd: FdGuard,
|
||||
#[cfg(feature = "proc")] thr_fd: FdGuard,
|
||||
) {
|
||||
pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
|
||||
#[cfg(feature = "proc")]
|
||||
let metadata = {
|
||||
RtTcb::current().thr_fd.get().write(Some(thr_fd));
|
||||
read_proc_meta(&proc_fd).unwrap()
|
||||
};
|
||||
let metadata = read_proc_meta(&proc_fd).unwrap();
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
// Bootstrap mode, don't associate proc fds with PIDs
|
||||
|
||||
+10
-1
@@ -55,6 +55,10 @@ pub struct ExtraInfo<'a> {
|
||||
pub sigprocmask: u64,
|
||||
/// File mode creation mask (POSIX)
|
||||
pub umask: u32,
|
||||
/// Thread handle
|
||||
pub thr_fd: usize,
|
||||
/// Process handle
|
||||
pub proc_fd: usize,
|
||||
}
|
||||
|
||||
pub fn fexec_impl<A, E>(
|
||||
@@ -373,7 +377,12 @@ where
|
||||
push(AT_REDOX_INHERITED_SIGPROCMASK)?;
|
||||
|
||||
push(extrainfo.umask as usize)?;
|
||||
push(AT_REDOX_UMASK);
|
||||
push(AT_REDOX_UMASK)?;
|
||||
|
||||
push(extrainfo.thr_fd as usize)?;
|
||||
push(AT_REDOX_THR_FD)?;
|
||||
push(extrainfo.proc_fd as usize)?;
|
||||
push(AT_REDOX_PROC_FD)?;
|
||||
|
||||
push(0)?;
|
||||
|
||||
|
||||
+4
-1
@@ -692,7 +692,10 @@ impl Linker {
|
||||
tcb.append_masters(tcb_masters);
|
||||
// Copy the master data into the static TLS block.
|
||||
tcb.copy_masters().map_err(|_| DlError::Malformed)?;
|
||||
tcb.activate();
|
||||
tcb.activate(
|
||||
#[cfg(target_os = "redox")]
|
||||
todo!(),
|
||||
);
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
|
||||
+21
-14
@@ -41,7 +41,10 @@ static mut STATIC_TCB_MASTER: Master = Master {
|
||||
};
|
||||
|
||||
#[inline(never)]
|
||||
pub fn static_init(sp: &'static Stack) {
|
||||
pub fn static_init(
|
||||
sp: &'static Stack,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard,
|
||||
) {
|
||||
const SIZEOF_PHDR64: usize = mem::size_of::<ProgramHeader64<Endianness>>();
|
||||
const SIZEOF_PHDR32: usize = mem::size_of::<ProgramHeader32<Endianness>>();
|
||||
|
||||
@@ -120,7 +123,10 @@ pub fn static_init(sp: &'static Stack) {
|
||||
tcb.masters_len = mem::size_of::<Master>();
|
||||
tcb.copy_masters()
|
||||
.expect_notls("failed to copy TLS master data");
|
||||
tcb.activate();
|
||||
tcb.activate(
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: Warning on multiple TLS sections?
|
||||
@@ -130,7 +136,10 @@ pub fn static_init(sp: &'static Stack) {
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "redox"))]
|
||||
pub unsafe fn init(sp: &'static Stack) {
|
||||
pub unsafe fn init(
|
||||
sp: &'static Stack,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard,
|
||||
) {
|
||||
let tp: usize;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -151,11 +160,8 @@ pub unsafe fn init(sp: &'static Stack) {
|
||||
{
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = syscall::open(
|
||||
"/scheme/thisproc/current/regs/env",
|
||||
syscall::O_CLOEXEC | syscall::O_RDONLY,
|
||||
)
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
let file = syscall::dup(*thr_fd, b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
let _ = syscall::read(file, &mut env).expect_notls("failed to read gsbase");
|
||||
|
||||
@@ -167,11 +173,8 @@ pub unsafe fn init(sp: &'static Stack) {
|
||||
{
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = syscall::open(
|
||||
"/scheme/thisproc/current/regs/env",
|
||||
syscall::O_CLOEXEC | syscall::O_RDONLY,
|
||||
)
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
let file = syscall::dup(*thr_fd, b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
let _ = syscall::read(file, &mut env).expect_notls("failed to read fsbase");
|
||||
|
||||
@@ -188,7 +191,11 @@ pub unsafe fn init(sp: &'static Stack) {
|
||||
}
|
||||
|
||||
if tp == 0 {
|
||||
static_init(sp);
|
||||
static_init(
|
||||
sp,
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -202,8 +202,14 @@ impl Tcb {
|
||||
}
|
||||
|
||||
/// Activate TLS
|
||||
pub unsafe fn activate(&mut self) {
|
||||
Self::os_arch_activate(&self.os_specific, self.tls_end as usize, self.tls_len);
|
||||
pub unsafe fn activate(&mut self, #[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard) {
|
||||
Self::os_arch_activate(
|
||||
&self.os_specific,
|
||||
self.tls_end as usize,
|
||||
self.tls_len,
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn setup_dtv(&mut self, n: usize) {
|
||||
@@ -327,7 +333,13 @@ impl Tcb {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
unsafe fn os_arch_activate(os: &OsSpecific, tls_end: usize, tls_len: usize) {
|
||||
unsafe fn os_arch_activate(
|
||||
os: &OsSpecific,
|
||||
tls_end: usize,
|
||||
tls_len: usize,
|
||||
thr_fd: redox_rt::proc::FdGuard,
|
||||
) {
|
||||
os.thr_fd.get().write(Some(thr_fd));
|
||||
redox_rt::tcb_activate(os, tls_end, tls_len)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ pub const AT_REDOX_INITIAL_DEFAULT_SCHEME_PTR: usize = 38;
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_INITIAL_DEFAULT_SCHEME_LEN: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_PROC_FD: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_THR_FD: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_UMASK: usize = 40;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_PROC_FD: usize = 41;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_THR_FD: usize = 42;
|
||||
|
||||
+30
-14
@@ -280,21 +280,40 @@ impl<T: Write> Write for CountingWriter<T> {
|
||||
// get_auxv.
|
||||
|
||||
#[cold]
|
||||
pub unsafe fn get_auxvs(mut ptr: *const usize) -> Box<[[usize; 2]]> {
|
||||
//traverse the stack and collect argument environment variables
|
||||
let mut auxvs = Vec::new();
|
||||
unsafe fn auxv_iter<'a>(ptr: *const usize) -> impl Iterator<Item = [usize; 2]> + 'a {
|
||||
struct St(*const usize);
|
||||
impl Iterator for St {
|
||||
type Item = [usize; 2];
|
||||
|
||||
while *ptr != self::auxv_defs::AT_NULL {
|
||||
let kind = ptr.read();
|
||||
ptr = ptr.add(1);
|
||||
let value = ptr.read();
|
||||
ptr = ptr.add(1);
|
||||
auxvs.push([kind, value]);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
if self.0.read() == self::auxv_defs::AT_NULL {
|
||||
return None;
|
||||
}
|
||||
let kind = self.0.read();
|
||||
let value = self.0.add(1).read();
|
||||
self.0 = self.0.add(2);
|
||||
|
||||
Some([kind, value])
|
||||
}
|
||||
}
|
||||
}
|
||||
St(ptr)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub unsafe fn get_auxvs(ptr: *const usize) -> Box<[[usize; 2]]> {
|
||||
//traverse the stack and collect argument environment variables
|
||||
let mut auxvs = auxv_iter(ptr).collect::<Vec<_>>();
|
||||
|
||||
auxvs.sort_unstable_by_key(|[kind, _]| *kind);
|
||||
auxvs.into_boxed_slice()
|
||||
}
|
||||
// TODO: Find an auxv replacement for Redox's execv protocol
|
||||
#[cold]
|
||||
pub unsafe fn get_auxv_raw(ptr: *const usize, requested_kind: usize) -> Option<usize> {
|
||||
auxv_iter(ptr).find_map(|[kind, value]| Some(value).filter(|_| kind == requested_kind))
|
||||
}
|
||||
pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
|
||||
auxvs
|
||||
.binary_search_by_key(&key, |[entry_key, _]| *entry_key)
|
||||
@@ -311,13 +330,10 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) {
|
||||
use redox_rt::proc::FdGuard;
|
||||
use syscall::MODE_PERM;
|
||||
|
||||
let (Some(thr_fd), Some(proc_fd)) = (
|
||||
get_auxv(&auxvs, AT_REDOX_THR_FD),
|
||||
get_auxv(&auxvs, AT_REDOX_PROC_FD),
|
||||
) else {
|
||||
let Some(proc_fd) = get_auxv(&auxvs, AT_REDOX_PROC_FD) else {
|
||||
panic!("Missing proc and thread fd!");
|
||||
};
|
||||
redox_rt::initialize(FdGuard::new(proc_fd), FdGuard::new(thr_fd));
|
||||
redox_rt::initialize(FdGuard::new(proc_fd));
|
||||
|
||||
if let (Some(cwd_ptr), Some(cwd_len)) = (
|
||||
get_auxv(&auxvs, AT_REDOX_INITIAL_CWD_PTR),
|
||||
|
||||
@@ -319,6 +319,8 @@ pub fn execve(
|
||||
sigignmask: 0,
|
||||
sigprocmask,
|
||||
umask: redox_rt::sys::get_umask(),
|
||||
thr_fd: **RtTcb::current().thread_fd(),
|
||||
proc_fd: **redox_rt::current_proc_fd(),
|
||||
};
|
||||
fexec_impl(
|
||||
exec_fd_guard,
|
||||
|
||||
+6
-9
@@ -210,19 +210,16 @@ unsafe extern "C" fn new_thread_shim(
|
||||
mutex1: *const Mutex<MaybeUninit<OsTid>>,
|
||||
mutex2: *const Mutex<u64>,
|
||||
) -> ! {
|
||||
let tid = (*(&*mutex1).lock()).assume_init();
|
||||
|
||||
if let Some(tcb) = tcb.as_mut() {
|
||||
tcb.activate();
|
||||
tcb.activate(
|
||||
#[cfg(target_os = "redox")]
|
||||
redox_rt::proc::FdGuard::new(tid.thread_fd),
|
||||
);
|
||||
}
|
||||
|
||||
let procmask = (&*mutex2).as_ptr().read();
|
||||
let tid = (*(&*mutex1).lock()).assume_init();
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
(*tcb)
|
||||
.os_specific
|
||||
.thr_fd
|
||||
.get()
|
||||
.write(Some(redox_rt::proc::FdGuard::new(tid.thread_fd)));
|
||||
|
||||
if let Some(tcb) = tcb.as_mut() {
|
||||
tcb.copy_masters().unwrap();
|
||||
|
||||
+12
-1
@@ -2,6 +2,7 @@
|
||||
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use core::{intrinsics, ptr};
|
||||
use generic_rt::ExpectTlsFree;
|
||||
|
||||
use crate::{
|
||||
header::{libgen, stdio, stdlib},
|
||||
@@ -141,8 +142,18 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
|
||||
// Ensure correct host system before executing more system calls
|
||||
relibc_verify_host();
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
let thr_fd = redox_rt::proc::FdGuard::new(
|
||||
crate::platform::get_auxv_raw(sp.auxv().cast(), redox_rt::auxv_defs::AT_REDOX_THR_FD)
|
||||
.expect_notls("no thread fd present"),
|
||||
);
|
||||
|
||||
// Initialize TLS, if necessary
|
||||
ld_so::init(sp);
|
||||
ld_so::init(
|
||||
sp,
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
);
|
||||
|
||||
// Set up the right allocator...
|
||||
// if any memory rust based memory allocation happen before this step .. we are doomed.
|
||||
|
||||
Reference in New Issue
Block a user