1pub mod twizzler;
2
3use std::{any::Any, collections::HashMap, sync::Arc};
4
5use elf::{endian::NativeEndian, ParseError};
6use twizzler_abi::object::{ObjID, MAX_SIZE, NULLPAGE_SIZE};
7use twizzler_rt_abi::object::ObjectHandle;
8
9use crate::{compartment::CompartmentId, library::UnloadedLibrary, DynlinkError};
10
11#[derive(Default)]
12pub struct LoadCtx {
13 pub set: HashMap<CompartmentId, ObjID>,
14}
15pub trait ContextEngine {
18 fn load_segments(
20 &mut self,
21 src: &Backing,
22 ld: &[LoadDirective],
23 comp_id: CompartmentId,
24 load_ctx: &mut LoadCtx,
25 ) -> Result<Vec<Backing>, DynlinkError>;
26
27 fn load_object(&mut self, unlib: &UnloadedLibrary) -> Result<Backing, DynlinkError>;
29
30 fn select_compartment(&mut self, unlib: &UnloadedLibrary) -> Option<CompartmentId>;
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
36pub struct LoadDirective {
37 pub load_flags: LoadFlags,
38 pub vaddr: usize,
39 pub memsz: usize,
40 pub offset: usize,
41 pub align: usize,
42 pub filesz: usize,
43}
44
45bitflags::bitflags! {
46 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
48 pub struct LoadFlags: u32 {
49 const TARGETS_DATA = 1;
51 }
52}
53
54#[derive(Clone)]
57pub struct Backing {
58 _owner: Arc<dyn Any>,
59 start: *mut u8,
60 len: usize,
61 id: ObjID,
62 full_name: String,
63}
64
65unsafe impl Send for Backing {}
66unsafe impl Sync for Backing {}
67
68impl Backing {
69 pub fn new(inner: ObjectHandle, full_name: String) -> Self {
70 unsafe {
71 Self::new_owned(
72 inner.start(),
73 MAX_SIZE - NULLPAGE_SIZE * 2,
74 inner.id(),
75 Arc::new(inner),
76 full_name,
77 )
78 }
79 }
80
81 pub unsafe fn new_owned(
82 start: *mut u8,
83 len: usize,
84 id: ObjID,
85 owner: Arc<dyn Any>,
86 full_name: String,
87 ) -> Self {
88 Self {
89 _owner: owner,
90 start,
91 len,
92 id,
93 full_name,
94 }
95 }
96
97 pub fn full_name(&self) -> &str {
98 &self.full_name
99 }
100}
101
102impl Backing {
103 pub(crate) fn data(&self) -> (*mut u8, usize) {
104 (unsafe { self.start.add(NULLPAGE_SIZE) }, self.len)
105 }
106
107 pub fn id(&self) -> ObjID {
109 self.id
110 }
111
112 pub fn load_addr(&self) -> usize {
113 self.start as usize
114 }
115
116 pub(crate) fn slice(&self) -> &[u8] {
117 let data = self.data();
118 unsafe { core::slice::from_raw_parts(data.0, data.1) }
120 }
121
122 pub(crate) fn get_elf(&self) -> Result<elf::ElfBytes<'_, NativeEndian>, ParseError> {
124 elf::ElfBytes::minimal_parse(self.slice())
125 }
126}