dynlink/context/
runtime.rs1use std::alloc::Layout;
2
3use tinyvec::TinyVec;
4use twizzler_abi::object::MAX_SIZE;
5use twizzler_rt_abi::core::CtorSet;
6
7use super::{Context, LoadedOrUnloaded};
8use crate::{
9 compartment::CompartmentId, context::LoadIds, library::LibraryId, tls::TlsRegion, DynlinkError,
10};
11
12#[repr(C)]
13pub struct RuntimeInitInfo {
14 pub tls_region: TlsRegion,
15 pub ctx: *const u8,
16 pub root_name: String,
17 pub used_slots: Vec<usize>,
18 pub ctors: Vec<CtorSet>,
19 pub bootstrap_alloc_slot: usize,
20}
21
22unsafe impl Send for RuntimeInitInfo {}
24unsafe impl Sync for RuntimeInitInfo {}
25
26impl RuntimeInitInfo {
27 pub(crate) fn new(
28 tls_region: TlsRegion,
29 ctx: &Context,
30 root_name: String,
31 ctors: Vec<CtorSet>,
32 ) -> Self {
33 let alloc_test = unsafe { std::alloc::alloc(Layout::from_size_align(16, 8).unwrap()) }
34 as usize
35 / MAX_SIZE;
36 Self {
37 tls_region,
38 ctx: ctx as *const _ as *const u8,
39 root_name,
40 used_slots: vec![],
41 ctors,
42 bootstrap_alloc_slot: alloc_test,
43 }
44 }
45}
46
47impl Context {
48 pub fn build_ctors_list<const N: usize>(
50 &self,
51 root_id: LibraryId,
52 comp: Option<CompartmentId>,
53 loads: Option<TinyVec<[LoadIds; N]>>,
54 ) -> Result<Vec<CtorSet>, DynlinkError> {
55 let mut ctors = vec![];
56 self.with_dfs_postorder(root_id, |lib| match lib {
57 LoadedOrUnloaded::Unloaded(_) => {}
58 LoadedOrUnloaded::Loaded(lib) => {
59 if let Some(ref loads) = loads {
60 if !loads.iter().any(|load| load.lib == lib.id()) {
61 return;
62 }
63 }
64 if let Some(comp) = comp {
65 if comp == lib.comp_id {
66 ctors.push(lib.ctors);
67 }
68 } else {
69 ctors.push(lib.ctors);
70 }
71 }
72 });
73 Ok(ctors)
74 }
75
76 pub fn build_runtime_info(
78 &self,
79 root_id: LibraryId,
80 tls: TlsRegion,
81 ) -> Result<RuntimeInitInfo, DynlinkError> {
82 let ctors = self.build_ctors_list::<32>(root_id, None, None)?;
83 Ok(RuntimeInitInfo::new(
84 tls,
85 self,
86 self.get_library(root_id)?.name.to_string(),
87 ctors,
88 ))
89 }
90}