monitor/
init.rs

1use std::ffi::c_void;
2
3use dynlink::context::{runtime::RuntimeInitInfo, Context};
4
5pub(crate) struct InitDynlinkContext {
6    pub ctx: *mut Context,
7}
8
9impl InitDynlinkContext {
10    pub fn get_safe_context(&self) -> &'static mut Context {
11        let ctx = self.ctx;
12        // Safety: the engine is the only thing that can't cross API boundary coming from bootstrap.
13        // Replace it, and we're good to go.
14        unsafe {
15            (*ctx).replace_engine(Box::new(crate::dlengine::Engine));
16            &mut (*ctx)
17        }
18    }
19}
20
21extern "C-unwind" {
22    // Defined by the runtime. Returns a pointer to the runtime init info struct if the runtime is
23    // in monitor mode, otherwise returns null.
24    fn __is_monitor() -> *mut c_void;
25}
26pub(crate) fn bootstrap_dynlink_context() -> Option<InitDynlinkContext> {
27    let info = unsafe { __is_monitor().cast::<RuntimeInitInfo>().as_mut().unwrap() };
28    let ctx = info.ctx as *mut Context;
29
30    Some(InitDynlinkContext { ctx })
31}