diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 69db3aa1a0..df3542506f 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -16,6 +16,7 @@ use core::{ }; use crate::{ + ALLOCATOR, c_str::{CStr, CString}, error::Errno, header::{ @@ -700,6 +701,7 @@ impl Linker { #[cfg(target_os = "redox")] Some(thr_fd), ); + tcb.mspace = ALLOCATOR.get(); #[cfg(target_os = "redox")] { diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs index 814a84498d..d59fa44a76 100644 --- a/src/ld_so/start.rs +++ b/src/ld_so/start.rs @@ -9,7 +9,6 @@ use alloc::{ }; use crate::{ - ALLOCATOR, c_str::CStr, header::{ sys_auxv::{AT_ENTRY, AT_PHDR}, @@ -247,7 +246,7 @@ pub unsafe extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: us let (path, _name) = match resolve_path_name(&name_or_path, &envs) { Some((p, n)) => (p, n), None => { - eprintln!("ld.so: failed to locate '{}'", name_or_path); + eprintln!("[ld.so]: failed to locate '{name_or_path}'"); unistd::_exit(1); } }; @@ -269,17 +268,16 @@ pub unsafe extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: us let entry = match linker.load_program(&path, base_addr) { Ok(entry) => entry, Err(err) => { - eprintln!("[ld.so]: failed to link '{}': {:?}", path, err); + eprintln!("[ld.so]: failed to link '{path}': {err:?}"); eprintln!("[ld.so]: enable debug output with `LD_DEBUG=all` for more information"); unistd::_exit(1); } }; if let Some(tcb) = unsafe { Tcb::current() } { tcb.linker_ptr = Box::into_raw(Box::new(Mutex::new(linker))); - tcb.mspace = ALLOCATOR.get(); } if is_manual { - eprintln!("[ld.so]: entry '{}': {:#x}", path, entry); + eprintln!("[ld.so]: entry '{path}': {entry:#x}"); } entry } diff --git a/src/platform/allocator/mod.rs b/src/platform/allocator/mod.rs index 1febb92f09..002c6082a1 100644 --- a/src/platform/allocator/mod.rs +++ b/src/platform/allocator/mod.rs @@ -3,7 +3,8 @@ use core::{ cell::SyncUnsafeCell, cmp, mem::align_of, - ptr::{copy_nonoverlapping, write_bytes}, + ptr::{self, copy_nonoverlapping, write_bytes}, + sync::atomic::{AtomicPtr, Ordering}, }; mod sys; @@ -15,17 +16,30 @@ pub type Dlmalloc = DlmallocCApi; pub const NEWALLOCATOR: Allocator = Allocator::new(); -pub struct Allocator(SyncUnsafeCell>); +pub struct Allocator { + inner: SyncUnsafeCell>, + pub ptr: AtomicPtr>, +} impl Allocator { pub const fn new() -> Self { - Allocator(SyncUnsafeCell::new(Mutex::new(Dlmalloc::new( - sys::System::new(), - )))) + Allocator { + inner: SyncUnsafeCell::new(Mutex::new(Dlmalloc::new(sys::System::new()))), + ptr: AtomicPtr::new(ptr::null_mut()), + } } - pub fn get(&self) -> *mut Mutex { - self.0.get() + pub fn get(&self) -> *const Mutex { + let ptr = self.ptr.load(Ordering::Acquire); + if !ptr.is_null() { + return ptr; + } + + self.inner.get() + } + + pub fn set(&self, mspace: *const Mutex) { + self.ptr.store(mspace.cast_mut(), Ordering::Release); } } diff --git a/src/start.rs b/src/start.rs index eb72e34ce6..0e272b3940 100644 --- a/src/start.rs +++ b/src/start.rs @@ -85,7 +85,7 @@ fn alloc_init() { unsafe { if let Some(tcb) = ld_so::tcb::Tcb::current() { if !tcb.mspace.is_null() { - ALLOCATOR.get().write(tcb.mspace.read()); + ALLOCATOR.set(tcb.mspace); } } } @@ -174,7 +174,9 @@ pub unsafe extern "C" fn relibc_start_v1( if let Some(tcb) = unsafe { ld_so::tcb::Tcb::current() } { // Update TCB mspace - tcb.mspace = ALLOCATOR.get(); + if tcb.mspace.is_null() { + tcb.mspace = ALLOCATOR.get(); + } // Set linker pointer if necessary if tcb.linker_ptr.is_null() {