sel4_root_task/
entry.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
// Copyright 2024, Colias Group, LLC
//
// SPDX-License-Identifier: BSD-2-Clause
//

use core::panic::UnwindSafe;

use crate::{abort, panicking::catch_unwind, Termination};

#[cfg(target_thread_local)]
#[no_mangle]
unsafe extern "C" fn sel4_runtime_rust_entry(bootinfo: *const sel4::BootInfo) -> ! {
    fn cont_fn(cont_arg: *mut sel4_runtime_common::ContArg) -> ! {
        inner_entry(cont_arg.cast_const().cast())
    }

    sel4_runtime_common::initialize_tls_on_stack_and_continue(cont_fn, bootinfo.cast_mut().cast())
}

#[cfg(not(target_thread_local))]
#[no_mangle]
unsafe extern "C" fn sel4_runtime_rust_entry(bootinfo: *const sel4::BootInfo) -> ! {
    inner_entry(bootinfo)
}

#[allow(unreachable_code)]
fn inner_entry(bootinfo: *const sel4::BootInfo) -> ! {
    #[cfg(panic = "unwind")]
    {
        sel4_runtime_common::set_eh_frame_finder().unwrap();
    }

    let bootinfo = unsafe { sel4::BootInfoPtr::new(bootinfo) };

    let ipc_buffer = unsafe { bootinfo.ipc_buffer().as_mut().unwrap() };
    sel4::set_ipc_buffer(ipc_buffer);

    sel4_ctors_dtors::run_ctors();

    unsafe {
        __sel4_root_task__main(&bootinfo);
    }

    abort!("__sel4_root_task__main returned")
}

extern "Rust" {
    fn __sel4_root_task__main(bootinfo: &sel4::BootInfoPtr) -> !;
}

#[doc(hidden)]
#[macro_export]
macro_rules! declare_main {
    ($main:expr) => {
        #[allow(non_snake_case)]
        #[no_mangle]
        fn __sel4_root_task__main(bootinfo: &$crate::_private::BootInfoPtr) -> ! {
            $crate::_private::run_main($main, bootinfo);
        }
    };
}

#[doc(hidden)]
#[allow(clippy::missing_safety_doc)]
pub fn run_main<F, T>(f: F, bootinfo: &sel4::BootInfoPtr) -> !
where
    F: FnOnce(&sel4::BootInfoPtr) -> T + UnwindSafe,
    T: Termination,
{
    let result = catch_unwind(move || f(bootinfo).report());
    match result {
        Ok(err) => abort!("main thread terminated with error: {err:?}"),
        Err(_) => abort!("uncaught panic in main thread"),
    }
}