sel4_panicking/
lib.rs
1#![no_std]
8#![feature(cfg_target_thread_local)]
9#![feature(core_intrinsics)]
10#![feature(lang_items)]
11#![feature(panic_can_unwind)]
12#![feature(thread_local)]
13#![allow(internal_features)]
14
15#[cfg(feature = "alloc")]
16extern crate alloc;
17
18use core::intrinsics::catch_unwind as catch_unwind_intrinsic;
19use core::mem::ManuallyDrop;
20use core::panic::{PanicInfo, UnwindSafe};
21
22use sel4_panicking_env::{abort, debug_println};
23
24mod count;
25mod hook;
26mod strategy;
27
28use count::{count_panic, count_panic_caught};
29use hook::get_hook;
30use strategy::{panic_cleanup, start_panic};
31
32pub use hook::{set_hook, PanicHook};
33
34#[panic_handler]
35fn panic(info: &PanicInfo) -> ! {
36 if let Some(must_abort) = count_panic() {
37 debug_println!("{}", info);
38 abort!("{}", must_abort);
39 }
40 (get_hook())(info);
41 if info.can_unwind() {
42 let code = start_panic();
43 abort!("failed to initiate panic, error {}", code)
44 } else {
45 abort!("can't unwind this panic")
46 }
47}
48
49#[allow(clippy::result_unit_err)]
51pub fn catch_unwind<R, F: FnOnce() -> R + UnwindSafe>(f: F) -> Result<R, ()> {
52 union Data<F, R> {
53 f: ManuallyDrop<F>,
54 r: ManuallyDrop<R>,
55 }
56
57 let mut data = Data {
58 f: ManuallyDrop::new(f),
59 };
60
61 let data_ptr = (&raw mut data) as *mut u8;
62 unsafe {
63 return if catch_unwind_intrinsic(do_call::<F, R>, data_ptr, do_catch) == 0 {
64 Ok(ManuallyDrop::into_inner(data.r))
65 } else {
66 Err(())
67 };
68 }
69
70 #[inline]
71 fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
72 unsafe {
73 let data = data as *mut Data<F, R>;
74 let data = &mut (*data);
75 let f = ManuallyDrop::take(&mut data.f);
76 data.r = ManuallyDrop::new(f());
77 }
78 }
79
80 #[inline]
81 fn do_catch(_data: *mut u8, exception: *mut u8) {
82 panic_cleanup(exception);
83 count_panic_caught();
84 }
85}
86
87pub fn abort_unwind<F, R>(f: F) -> R
89where
90 F: FnOnce() -> R,
91{
92 extern "C" fn wrap<F, R>(f: F) -> R
93 where
94 F: FnOnce() -> R,
95 {
96 f()
97 }
98
99 wrap(f)
100}