Skip to content

Commit

Permalink
Fix several recursions in monitor mapping.
Browse files Browse the repository at this point in the history
  • Loading branch information
dbittman committed Feb 21, 2025
1 parent 6d69ad5 commit aad81a0
Show file tree
Hide file tree
Showing 19 changed files with 256 additions and 154 deletions.
21 changes: 17 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 26 additions & 2 deletions src/bin/bootstrap/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ use dynlink::{
};
use tracing::{debug, info, warn, Level};
use tracing_subscriber::FmtSubscriber;
use twizzler_abi::{arch::SLOTS, object::ObjID, syscall::sys_object_read_map};
use twizzler_abi::{
arch::SLOTS,
object::{ObjID, MAX_SIZE},
syscall::sys_object_read_map,
};
use twizzler_rt_abi::{
core::{InitInfoPtrs, RuntimeInfo},
object::MapFlags,
Expand All @@ -36,7 +40,27 @@ impl ContextEngine for Engine {
_comp_id: CompartmentId,
_load_ctx: &mut LoadCtx,
) -> Result<Vec<Backing>, dynlink::DynlinkError> {
dynlink::engines::twizzler::load_segments(src, ld, 0.into())
let map = |text_id, data_id| {
#[allow(deprecated)]
let (text_handle, data_handle) = twizzler_rt_abi::object::twz_rt_map_two_objects(
text_id,
MapFlags::READ | MapFlags::EXEC,
data_id,
MapFlags::READ | MapFlags::WRITE,
)
.map_err(|_| DynlinkErrorKind::NewBackingFail)?;

if data_handle.start() as usize != text_handle.start() as usize + MAX_SIZE {
tracing::error!(
"internal runtime error: failed to map text and data adjacent and in-order ({:p} {:p})",
text_handle.start(),
data_handle.start()
);
return Err(DynlinkErrorKind::NewBackingFail.into());
}
Ok((Backing::new(text_handle), Backing::new(data_handle)))
};
dynlink::engines::twizzler::load_segments(src, ld, 0.into(), map)
}

fn load_object(&mut self, unlib: &UnloadedLibrary) -> Result<Backing, DynlinkError> {
Expand Down
19 changes: 12 additions & 7 deletions src/lib/dynlink/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,22 @@ impl Context {
self.add_dep(parent.0, dependee.0);
}

pub fn unload_compartment(&mut self, comp_id: CompartmentId) {
pub fn unload_compartment(
&mut self,
comp_id: CompartmentId,
) -> (Option<Compartment>, Vec<LoadedOrUnloaded>) {
let Ok(comp) = self.get_compartment(comp_id) else {
return;
return (None, vec![]);
};
let name = comp.name.clone();
let ids = comp.library_ids().collect::<Vec<_>>();
for lib in ids {
self.library_deps.remove_node(lib.0);
}
let ids = comp.library_ids();
let nodes = ids
.collect::<Vec<_>>()
.iter()
.filter_map(|id| self.library_deps.remove_node(id.0))
.collect();
self.compartment_names.remove(&name);
self.compartments.remove(comp_id.0);
(self.compartments.remove(comp_id.0), nodes)
}

/// Create a new compartment with a given name.
Expand Down
49 changes: 30 additions & 19 deletions src/lib/dynlink/src/engines/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
pub mod twizzler;

use std::collections::HashMap;
use std::{any::Any, collections::HashMap, sync::Arc};

use elf::{endian::NativeEndian, ParseError};
use twizzler_abi::object::{MAX_SIZE, NULLPAGE_SIZE};
use twizzler_object::ObjID;
use twizzler_rt_abi::object::{self, ObjectHandle};
use twizzler_rt_abi::object::ObjectHandle;

use crate::{compartment::CompartmentId, library::UnloadedLibrary, DynlinkError};

Expand Down Expand Up @@ -56,38 +56,49 @@ bitflags::bitflags! {
/// for treating Twizzler objects as object files.
#[derive(Clone)]
pub struct Backing {
obj: object::ObjectHandle,
_owner: Arc<dyn Any>,
start: *mut u8,
len: usize,
id: ObjID,
}

impl Drop for Backing {
fn drop(&mut self) {
tracing::debug!("drop backing: {:?}: {:p}", self.obj.id(), self.obj.start());
}
}
unsafe impl Send for Backing {}
unsafe impl Sync for Backing {}

impl Backing {
pub fn new(inner: ObjectHandle) -> Self {
tracing::debug!("new backing: {:?}: {:p}", inner.id(), inner.start());
Self { obj: inner }
unsafe {
Self::new_owned(
inner.start(),
MAX_SIZE - NULLPAGE_SIZE * 2,
inner.id(),
Arc::new(inner),
)
}
}

pub unsafe fn new_owned(start: *mut u8, len: usize, id: ObjID, owner: Arc<dyn Any>) -> Self {
Self {
_owner: owner,
start,
len,
id,
}
}
}

impl Backing {
pub(crate) fn data(&self) -> (*mut u8, usize) {
(
unsafe { self.obj.start().add(NULLPAGE_SIZE) },
// one null-page, one meta-page
MAX_SIZE - NULLPAGE_SIZE * 2,
)
(unsafe { self.start.add(NULLPAGE_SIZE) }, self.len)
}

/// Get the underlying object handle.
pub fn object(&self) -> &ObjectHandle {
&self.obj
pub fn id(&self) -> ObjID {
self.id
}

pub(crate) fn load_addr(&self) -> usize {
self.obj.start() as usize
pub fn load_addr(&self) -> usize {
self.start as usize
}

pub(crate) fn slice(&self) -> &[u8] {
Expand Down
25 changes: 4 additions & 21 deletions src/lib/dynlink/src/engines/twizzler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use twizzler_abi::{
},
};
use twizzler_object::ObjID;
use twizzler_rt_abi::object::MapFlags;

use super::{Backing, LoadDirective, LoadFlags};
use crate::{DynlinkError, DynlinkErrorKind};
Expand All @@ -24,6 +23,7 @@ pub fn load_segments(
src: &Backing,
ld: &[LoadDirective],
instance: ObjID,
map: impl FnOnce(ObjID, ObjID) -> Result<(Backing, Backing), DynlinkError>,
) -> Result<Vec<Backing>, DynlinkError> {
let create_spec = ObjectCreate::new(
BackingType::Normal,
Expand Down Expand Up @@ -93,7 +93,7 @@ pub fn load_segments(
}

Ok(ObjectSource::new_copy(
src.obj.id(),
src.id(),
src_start as u64,
dest_start as u64,
len,
Expand Down Expand Up @@ -133,23 +133,6 @@ pub fn load_segments(
data_id
);

#[allow(deprecated)]
let (text_handle, data_handle) = twizzler_rt_abi::object::twz_rt_map_two_objects(
text_id,
MapFlags::READ | MapFlags::EXEC,
data_id,
MapFlags::READ | MapFlags::WRITE,
)
.map_err(|_| DynlinkErrorKind::NewBackingFail)?;

if data_handle.start() as usize != text_handle.start() as usize + MAX_SIZE {
tracing::error!(
"internal runtime error: failed to map text and data adjacent and in-order ({:p} {:p})",
text_handle.start(),
data_handle.start()
);
return Err(DynlinkErrorKind::NewBackingFail.into());
}

Ok(vec![Backing::new(text_handle), Backing::new(data_handle)])
let (text, data) = map(text_id, data_id)?;
Ok(vec![text, data])
}
70 changes: 65 additions & 5 deletions src/rt/monitor/src/dlengine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use twizzler_abi::{
};
use twizzler_rt_abi::object::{MapFlags, ObjID};

use crate::mon::{get_monitor, space::MapInfo};

pub struct Engine;

fn get_new_sctx_instance(_sctx: ObjID) -> ObjID {
Expand Down Expand Up @@ -40,15 +42,73 @@ impl ContextEngine for Engine {
.set
.entry(comp_id)
.or_insert_with(|| get_new_sctx_instance(1.into()));
dynlink::engines::twizzler::load_segments(src, ld, instance)
let map = |text_id, data_id| {
#[allow(deprecated)]
let (text_handle, data_handle) = get_monitor()
.space
.lock()
.unwrap()
.map_pair(
MapInfo {
id: text_id,
flags: MapFlags::READ | MapFlags::EXEC,
},
MapInfo {
id: data_id,
flags: MapFlags::READ | MapFlags::WRITE,
},
)
.map_err(|_| DynlinkErrorKind::NewBackingFail)?;

if data_handle.monitor_data_start() as usize
!= text_handle.monitor_data_start() as usize + MAX_SIZE
{
tracing::error!(
"internal runtime error: failed to map text and data adjacent and in-order ({:p} {:p})",
text_handle.monitor_data_start(),
data_handle.monitor_data_start(),
);
return Err(DynlinkErrorKind::NewBackingFail.into());
}
unsafe {
Ok((
Backing::new_owned(
text_handle.monitor_data_start(),
MAX_SIZE - NULLPAGE_SIZE * 2,
text_id,
text_handle,
),
Backing::new_owned(
data_handle.monitor_data_start(),
MAX_SIZE - NULLPAGE_SIZE * 2,
data_id,
data_handle,
),
))
}
};
dynlink::engines::twizzler::load_segments(src, ld, instance, map)
}

fn load_object(&mut self, unlib: &UnloadedLibrary) -> Result<Backing, DynlinkError> {
let id = name_resolver(&unlib.name)?;
Ok(Backing::new(
twizzler_rt_abi::object::twz_rt_map_object(id, MapFlags::READ)
.map_err(|_err| DynlinkErrorKind::NewBackingFail)?,
))
let mapping = get_monitor()
.space
.lock()
.unwrap()
.map(MapInfo {
id,
flags: MapFlags::READ,
})
.map_err(|_err| DynlinkErrorKind::NewBackingFail)?;
Ok(unsafe {
Backing::new_owned(
mapping.monitor_data_start(),
MAX_SIZE - NULLPAGE_SIZE * 2,
id,
mapping,
)
})
}

fn select_compartment(
Expand Down
Loading

0 comments on commit aad81a0

Please sign in to comment.