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 fn add_name_map(&mut self, _name: &str, _id: ObjID) {}
34 fn remove_name_map(&mut self, _name: Option<&str>, _id: Option<ObjID>) {}
35}
36
37#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
39pub struct LoadDirective {
40 pub load_flags: LoadFlags,
41 pub vaddr: usize,
42 pub memsz: usize,
43 pub offset: usize,
44 pub align: usize,
45 pub filesz: usize,
46}
47
48bitflags::bitflags! {
49 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
51 pub struct LoadFlags: u32 {
52 const TARGETS_DATA = 1;
54 }
55}
56
57#[derive(Clone)]
60pub struct Backing {
61 _owner: Arc<dyn Any>,
62 start: *mut u8,
63 len: usize,
64 id: ObjID,
65 full_name: String,
66}
67
68unsafe impl Send for Backing {}
69unsafe impl Sync for Backing {}
70
71impl Backing {
72 pub fn new(inner: ObjectHandle, full_name: &str) -> Self {
73 unsafe {
74 Self::new_owned(
75 inner.start(),
76 MAX_SIZE - NULLPAGE_SIZE * 2,
77 inner.id(),
78 Arc::new(inner),
79 full_name.to_string(),
80 )
81 }
82 }
83
84 pub unsafe fn new_owned(
85 start: *mut u8,
86 len: usize,
87 id: ObjID,
88 owner: Arc<dyn Any>,
89 full_name: String,
90 ) -> Self {
91 Self {
92 _owner: owner,
93 start,
94 len,
95 id,
96 full_name,
97 }
98 }
99
100 pub fn full_name(&self) -> &str {
101 &self.full_name
102 }
103}
104
105impl Backing {
106 pub(crate) fn data(&self) -> (*mut u8, usize) {
107 (unsafe { self.start.add(NULLPAGE_SIZE) }, self.len)
108 }
109
110 pub fn id(&self) -> ObjID {
112 self.id
113 }
114
115 pub fn load_addr(&self) -> usize {
116 self.start as usize
117 }
118
119 pub(crate) fn slice(&self) -> &[u8] {
120 let data = self.data();
121 unsafe { core::slice::from_raw_parts(data.0, data.1) }
123 }
124
125 pub(crate) fn get_elf(&self) -> Result<elf::ElfBytes<'_, NativeEndian>, ParseError> {
127 elf::ElfBytes::minimal_parse(self.slice())
128 }
129}