#![no_std]
#![feature(core_intrinsics)]
#![feature(linkage)]
#![allow(internal_features)]
use core::fmt;
use core::panic::Location;
use core::str;
extern "Rust" {
fn __sel4_panicking_env__debug_put_char(c: u8);
fn __sel4_panicking_env__abort_hook(info: Option<&AbortInfo>);
}
#[macro_export]
macro_rules! register_debug_put_char {
($(#[$attrs:meta])* $path:path) => {
#[allow(non_snake_case)]
const _: () = {
$(#[$attrs])*
#[no_mangle]
fn __sel4_panicking_env__debug_put_char(c: u8) {
const F: fn(u8) = $path;
F(c)
}
};
};
}
#[macro_export]
macro_rules! register_abort_hook {
($(#[$attrs:meta])* $path:path) => {
#[allow(non_snake_case)]
const _: () = {
$(#[$attrs])*
#[no_mangle]
fn __sel4_panicking_env__abort_hook(info: ::core::option::Option<&$crate::AbortInfo>) {
const F: fn(::core::option::Option<&$crate::AbortInfo>) = $path;
F(info)
}
};
};
}
register_abort_hook!(
#[linkage = "weak"]
default_abort_hook
);
fn default_abort_hook(info: Option<&AbortInfo>) {
match info {
Some(info) => debug_println!("{}", info),
None => debug_println!("(aborted)"),
}
}
pub fn debug_put_char(c: u8) {
unsafe { __sel4_panicking_env__debug_put_char(c) }
}
struct DebugWrite;
impl fmt::Write for DebugWrite {
fn write_str(&mut self, s: &str) -> fmt::Result {
for &c in s.as_bytes() {
debug_put_char(c)
}
Ok(())
}
}
#[doc(hidden)]
pub fn __debug_print_macro_helper(args: fmt::Arguments) {
fmt::write(&mut DebugWrite, args).unwrap_or_else(|err| {
let _ = fmt::write(&mut DebugWrite, format_args!("({err})"));
})
}
#[macro_export]
macro_rules! debug_print {
($($arg:tt)*) => ($crate::__debug_print_macro_helper(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! debug_println {
() => ($crate::debug_println!(""));
($($arg:tt)*) => ($crate::debug_print!("{}\n", format_args!($($arg)*)));
}
pub struct AbortInfo<'a> {
message: Option<&'a fmt::Arguments<'a>>,
location: Option<&'a Location<'a>>,
}
impl<'a> AbortInfo<'a> {
pub fn message(&self) -> Option<&fmt::Arguments> {
self.message
}
pub fn location(&self) -> Option<&Location> {
self.location
}
}
impl fmt::Display for AbortInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("aborted at ")?;
if let Some(location) = self.location {
location.fmt(f)?;
} else {
f.write_str("unknown location")?;
}
if let Some(message) = self.message {
f.write_str(":\n")?;
f.write_fmt(*message)?;
}
Ok(())
}
}
fn abort(info: Option<&AbortInfo>) -> ! {
unsafe {
__sel4_panicking_env__abort_hook(info);
}
core::intrinsics::abort()
}
pub fn abort_without_info() -> ! {
abort(None)
}
#[doc(hidden)]
#[track_caller]
pub fn __abort_macro_helper(message: Option<fmt::Arguments>) -> ! {
abort(Some(&AbortInfo {
message: message.as_ref(),
location: Some(Location::caller()),
}))
}
#[macro_export]
macro_rules! abort {
() => ($crate::__abort_macro_helper(::core::option::Option::None));
($($arg:tt)*) => ($crate::__abort_macro_helper(::core::option::Option::Some(format_args!($($arg)*))));
}