pub mod twizzler;
use elf::{endian::NativeEndian, ParseError};
use twizzler_abi::object::{MAX_SIZE, NULLPAGE_SIZE};
use twizzler_runtime_api::ObjectHandle;
use crate::{compartment::CompartmentId, library::UnloadedLibrary, DynlinkError};
pub trait ContextEngine {
fn load_segments(
&mut self,
src: &Backing,
ld: &[LoadDirective],
) -> Result<Vec<Backing>, DynlinkError>;
fn load_object(&mut self, unlib: &UnloadedLibrary) -> Result<Backing, DynlinkError>;
fn select_compartment(&mut self, unlib: &UnloadedLibrary) -> Option<CompartmentId>;
}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
pub struct LoadDirective {
pub load_flags: LoadFlags,
pub vaddr: usize,
pub memsz: usize,
pub offset: usize,
pub align: usize,
pub filesz: usize,
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
pub struct LoadFlags: u32 {
const TARGETS_DATA = 1;
}
}
#[derive(Clone)]
pub struct Backing {
obj: twizzler_runtime_api::ObjectHandle,
}
impl Backing {
pub fn new(inner: twizzler_runtime_api::ObjectHandle) -> Self {
Self { obj: inner }
}
}
impl Backing {
pub(crate) fn data(&self) -> (*mut u8, usize) {
(
unsafe { self.obj.start.add(NULLPAGE_SIZE) },
MAX_SIZE - NULLPAGE_SIZE * 2,
)
}
pub fn object(&self) -> &ObjectHandle {
&self.obj
}
pub(crate) fn load_addr(&self) -> usize {
self.obj.start as usize
}
pub(crate) fn slice(&self) -> &[u8] {
let data = self.data();
unsafe { core::slice::from_raw_parts(data.0, data.1) }
}
pub(crate) fn get_elf(&self) -> Result<elf::ElfBytes<'_, NativeEndian>, ParseError> {
elf::ElfBytes::minimal_parse(self.slice())
}
}