1use dynlink::context::NewCompartmentFlags;
2use monitor_api::{
3 CompartmentInfoRaw, LibraryInfoRaw, MonitorCompControlCmd, MonitorStats, PostSignalFlags,
4 ThreadInfo, MONITOR_INSTANCE_ID,
5};
6use secgate::util::Descriptor;
7use twizzler_rt_abi::{
8 error::{ArgumentError, ResourceError, TwzError},
9 object::ObjID,
10 thread::ThreadSpawnArgs,
11};
12
13extern "C-unwind" {
14 fn __is_monitor_ready() -> bool;
15}
16
17#[secgate::entry(lib = "monitor-api")]
18pub fn monitor_rt_spawn_thread(
19 args: ThreadSpawnArgs,
20 thread_pointer: usize,
21 stack_pointer: usize,
22) -> Result<ObjID, TwzError> {
23 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
24 let monitor = crate::mon::get_monitor();
25 monitor.spawn_compartment_thread(
26 info.source_context().unwrap_or(0.into()),
27 args,
28 stack_pointer,
29 thread_pointer,
30 )
31}
32
33#[secgate::entry(lib = "monitor-api")]
34pub fn monitor_rt_get_comp_config() -> Result<usize, TwzError> {
35 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
36 let monitor = crate::mon::get_monitor();
37 Ok(monitor
38 .get_comp_config(info.source_context().unwrap_or(MONITOR_INSTANCE_ID))
39 .map(|ptr| ptr as usize)
40 .unwrap_or(0))
41}
42
43#[secgate::entry(lib = "monitor-api")]
44pub fn monitor_rt_get_library_info(desc: Descriptor) -> Result<LibraryInfoRaw, TwzError> {
45 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
46 let monitor = crate::mon::get_monitor();
47 let instance = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
48 let thread = info.thread_id();
49 monitor.get_library_info(instance, thread, desc)
50}
51
52#[secgate::entry(lib = "monitor-api")]
53pub fn monitor_rt_get_library_handle(
54 compartment: Option<Descriptor>,
55 lib_n: usize,
56) -> Result<Descriptor, TwzError> {
57 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
58 let monitor = crate::mon::get_monitor();
59 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
60 monitor.get_library_handle(caller, compartment, lib_n)
61}
62
63#[secgate::entry(lib = "monitor-api")]
64pub fn monitor_rt_get_compartment_handle(compartment: ObjID) -> Result<Descriptor, TwzError> {
65 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
66 let monitor = crate::mon::get_monitor();
67 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
68 let compartment = if compartment.raw() == 0 {
69 caller
70 } else {
71 compartment
72 };
73 monitor.get_compartment_handle(caller, compartment)
74}
75
76#[secgate::entry(lib = "monitor-api")]
77pub fn monitor_rt_get_compartment_info(
78 desc: Option<Descriptor>,
79) -> Result<CompartmentInfoRaw, TwzError> {
80 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
81 let monitor = crate::mon::get_monitor();
82 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
83 monitor.get_compartment_info(caller, info.thread_id(), desc)
84}
85
86#[secgate::entry(lib = "monitor-api")]
87pub fn monitor_rt_compartment_dynamic_gate(
88 desc: Option<Descriptor>,
89 name_len: usize,
90) -> Result<usize, TwzError> {
91 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
92 let monitor = crate::mon::get_monitor();
93 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
94 monitor.get_compartment_gate_address(caller, info.thread_id(), desc, name_len)
95}
96
97#[secgate::entry(lib = "monitor-api")]
98pub fn monitor_rt_get_compartment_deps(
99 desc: Option<Descriptor>,
100 dep_n: usize,
101) -> Result<Descriptor, TwzError> {
102 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
103 let monitor = crate::mon::get_monitor();
104 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
105 monitor.get_compartment_deps(caller, desc, dep_n)
106}
107
108#[secgate::entry(lib = "monitor-api")]
109pub fn monitor_rt_get_compartment_thread(
110 desc: Option<Descriptor>,
111 dep_n: usize,
112) -> Result<ThreadInfo, TwzError> {
113 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
114 let monitor = crate::mon::get_monitor();
115 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
116 monitor.get_compartment_thread_info(caller, desc, dep_n)
117}
118
119#[secgate::entry(lib = "monitor-api")]
120pub fn monitor_rt_lookup_compartment(name_len: usize) -> Result<Descriptor, TwzError> {
121 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
122 let monitor = crate::mon::get_monitor();
123 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
124 monitor.lookup_compartment(caller, info.thread_id(), name_len)
125}
126
127#[secgate::entry(lib = "monitor-api")]
128pub fn monitor_rt_load_compartment(
129 root_obj: ObjID,
130 name_len: u64,
131 args_len: u64,
132 env_len: u64,
133 flags: u32,
134 config: u64,
135) -> Result<Descriptor, TwzError> {
136 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
137 let monitor = crate::mon::get_monitor();
138 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
139 monitor.load_compartment(
140 caller,
141 info.thread_id(),
142 root_obj,
143 name_len as usize,
144 args_len as usize,
145 env_len as usize,
146 NewCompartmentFlags::from_bits(flags).ok_or(ArgumentError::InvalidArgument)?,
147 config as usize as *const _,
148 )
149}
150
151#[secgate::entry(lib = "monitor-api")]
152pub fn monitor_rt_compartment_wait(desc: Option<Descriptor>, flags: u64) -> Result<u64, TwzError> {
153 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
154 let monitor = crate::mon::get_monitor();
155 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
156 Ok(monitor.compartment_wait(caller, desc, flags))
157}
158
159#[secgate::entry(lib = "monitor-api")]
160pub fn monitor_rt_drop_compartment_handle(desc: Descriptor) -> Result<(), TwzError> {
161 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
162 let monitor = crate::mon::get_monitor();
163 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
164 monitor.drop_compartment_handle(caller, desc);
165 Ok(())
166}
167
168#[secgate::entry(lib = "monitor-api")]
169pub fn monitor_rt_load_library(
170 _compartment: Option<Descriptor>,
171 id: Option<ObjID>,
172 name_len: usize,
173) -> Result<(Descriptor, usize), TwzError> {
174 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
175 let monitor = crate::mon::get_monitor();
176 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
177 monitor.load_library_by_name(caller, info.thread_id(), name_len, id)
178}
179
180#[secgate::entry(lib = "monitor-api")]
181pub fn monitor_rt_drop_library_handle(desc: Descriptor) -> Result<(), TwzError> {
182 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
183 let monitor = crate::mon::get_monitor();
184 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
185 monitor.drop_library_handle(caller, desc);
186 Ok(())
187}
188
189#[secgate::entry(lib = "monitor-api")]
190pub fn monitor_rt_object_map(
191 id: ObjID,
192 flags: twizzler_rt_abi::object::MapFlags,
193) -> Result<crate::MappedObjectAddrs, TwzError> {
194 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
195 use crate::mon::space::MapInfo;
196 if unsafe { __is_monitor_ready() } {
197 let is_monitor_recursed =
202 { happylock::ThreadKey::get().is_none() && info.source_context().is_none() };
203 if is_monitor_recursed {
204 tracing::debug!(
205 "performing early object mapping (recursed), {} {:?}",
206 id,
207 flags
208 );
209 return Ok(crate::mon::early_object_map(MapInfo { id, flags }));
210 }
211 let monitor = crate::mon::get_monitor();
212 monitor
213 .map_object(
214 info.source_context().unwrap_or(MONITOR_INSTANCE_ID),
215 MapInfo { id, flags },
216 )
217 .map(|handle| handle.addrs())
218 } else {
219 tracing::debug!("performing early object mapping, {} {:?}", id, flags);
222 Ok(crate::mon::early_object_map(MapInfo { id, flags }))
223 }
224}
225
226#[secgate::entry(lib = "monitor-api")]
227pub fn monitor_rt_object_pair_map(
228 id: ObjID,
229 flags: twizzler_rt_abi::object::MapFlags,
230 id2: ObjID,
231 flags2: twizzler_rt_abi::object::MapFlags,
232) -> Result<(crate::MappedObjectAddrs, crate::MappedObjectAddrs), TwzError> {
233 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
234 use crate::mon::space::MapInfo;
235 if unsafe { !__is_monitor_ready() } {
236 return Err(ResourceError::Unavailable.into());
237 }
238 let monitor = crate::mon::get_monitor();
239 monitor
240 .map_pair(
241 info.source_context().unwrap_or(MONITOR_INSTANCE_ID),
242 MapInfo { id, flags },
243 MapInfo {
244 id: id2,
245 flags: flags2,
246 },
247 )
248 .map(|(one, two)| (one.addrs(), two.addrs()))
249}
250
251#[secgate::entry(lib = "monitor-api")]
252pub fn monitor_rt_object_unmap(
253 id: ObjID,
254 flags: twizzler_rt_abi::object::MapFlags,
255) -> Result<(), TwzError> {
256 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
257 if unsafe { __is_monitor_ready() } {
258 let monitor = crate::mon::get_monitor();
259 monitor.unmap_object(
260 info.source_context().unwrap_or(MONITOR_INSTANCE_ID),
261 crate::mon::space::MapInfo { id, flags },
262 );
263 }
264 Ok(())
265}
266
267#[secgate::entry(lib = "monitor-api")]
268pub fn monitor_rt_get_thread_simple_buffer() -> Result<ObjID, TwzError> {
269 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
270 let monitor = crate::mon::get_monitor();
271 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
272 monitor.get_thread_simple_buffer(caller, info.thread_id())
273}
274
275#[secgate::entry(lib = "monitor-api")]
276pub fn monitor_rt_comp_ctrl(cmd: MonitorCompControlCmd) -> Result<Option<i32>, TwzError> {
277 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
278 let monitor = crate::mon::get_monitor();
279 Ok(monitor.compartment_ctrl(&info, cmd))
280}
281
282#[secgate::entry(lib = "monitor-api")]
283pub fn monitor_rt_stats() -> Result<MonitorStats, TwzError> {
284 let monitor = crate::mon::get_monitor();
285 Ok(monitor.stats())
286}
287
288#[secgate::entry(lib = "monitor-api")]
289pub fn monitor_rt_post_signal(
290 comp: Option<ObjID>,
291 signal: u64,
292 flags: PostSignalFlags,
293) -> Result<(), TwzError> {
294 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
295 let monitor = crate::mon::get_monitor();
296 monitor.post_signal(&info, comp, signal, flags)
297}
298
299#[secgate::entry(lib = "monitor-api")]
300pub fn monitor_rt_set_controller(comp: ObjID, controller: ObjID) -> Result<(), TwzError> {
301 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
302 let monitor = crate::mon::get_monitor();
303 let comp = if comp.raw() == 0 {
304 info.source_context().unwrap_or(MONITOR_INSTANCE_ID)
305 } else {
306 comp
307 };
308 monitor.set_controller(&info, comp, controller)
309}
310
311#[secgate::entry(lib = "monitor-api")]
312pub fn monitor_rt_lookup_compartment_id(id: ObjID) -> Result<Descriptor, TwzError> {
313 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
314 let monitor = crate::mon::get_monitor();
315 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
316 monitor.lookup_compartment_id(caller, info.thread_id(), id)
317}
318
319#[secgate::entry(lib = "monitor-api")]
320pub fn monitor_rt_libname_map(namelen: usize, id: ObjID) -> Result<(), TwzError> {
321 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
322 let monitor = crate::mon::get_monitor();
323 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
324 monitor.libname_map(caller, info.thread_id(), namelen, id)
325}
326
327#[secgate::entry(lib = "monitor-api")]
328pub fn monitor_rt_libname_unmap(namelen: Option<usize>, id: Option<ObjID>) -> Result<(), TwzError> {
329 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
330 let monitor = crate::mon::get_monitor();
331 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
332 monitor.libname_unmap(caller, info.thread_id(), namelen, id)
333}
334
335#[secgate::entry(lib = "monitor-api")]
336pub fn monitor_rt_lookup_symbol(
337 lib_desc: Option<Descriptor>,
338 name_len: usize,
339) -> Result<usize, TwzError> {
340 let info = secgate::get_caller().ok_or(TwzError::NOT_SUPPORTED)?;
341 let monitor = crate::mon::get_monitor();
342 let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
343 monitor.lookup_symbol(caller, info.thread_id(), lib_desc, name_len)
344}