Reach init fork

This commit is contained in:
4lDO2
2024-12-27 16:32:19 +01:00
parent 26399569de
commit ad5efd0f11
11 changed files with 111 additions and 60 deletions
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}
}
+6 -6
View File
@@ -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
View File
@@ -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),
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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.