Skip to content

Commit

Permalink
Adds panic_handler macro
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed May 26, 2024
1 parent 06fca21 commit f989661
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
4 changes: 3 additions & 1 deletion kernel-1100/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::ffi::{c_char, c_int};
use okf::malloc::MallocFlags;
use okf::socket::SockAddr;
use okf::uio::UioSeg;
use okf::{offset, MappedKernel, StaticMut};
use okf::{offset, panic_handler, MappedKernel, StaticMut};

mod file;
mod lock;
Expand Down Expand Up @@ -121,3 +121,5 @@ impl okf::Kernel for Kernel {

unsafe impl Send for Kernel {}
unsafe impl Sync for Kernel {}

panic_handler!(0x1987C0);
10 changes: 10 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use syn::{parse_macro_input, Error, ItemStruct, LitInt, TraitItem};

mod derive;
mod offset;
mod panic_handler;

#[proc_macro_derive(MappedKernel)]
pub fn derive_mapped_kernel(item: TokenStream) -> TokenStream {
Expand All @@ -22,3 +23,12 @@ pub fn offset(args: TokenStream, item: TokenStream) -> TokenStream {
.unwrap_or_else(Error::into_compile_error)
.into()
}

#[proc_macro]
pub fn panic_handler(args: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as LitInt);

self::panic_handler::transform(args)
.unwrap_or_else(Error::into_compile_error)
.into()
}
53 changes: 53 additions & 0 deletions macros/src/panic_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::LitInt;

pub fn transform(arg: LitInt) -> syn::Result<TokenStream> {
let off: usize = arg.base10_parse()?;

Ok(quote! {
#[cfg(feature = "panic-handler")]
struct PanicMsg<const L: usize> {
buf: [u8; L],
pos: usize,
}

#[cfg(feature = "panic-handler")]
impl<const L: usize> core::fmt::Write for PanicMsg<L> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
// This method need to be careful not to cause any panic so we don't end up nested panic.
let str = s.as_bytes();
let end = core::cmp::min(self.pos.saturating_add(str.len()), self.buf.len() - 1);
let buf = unsafe { self.buf.get_unchecked_mut(self.pos..end) };

buf.copy_from_slice(unsafe { str.get_unchecked(..buf.len()) });
self.pos = end;

Ok(())
}
}

#[cfg(feature = "panic-handler")]
#[panic_handler]
fn panic(i: &core::panic::PanicInfo) -> ! {
use core::fmt::Write;
use okf::MappedKernel;

// Write panic message.
let mut m = PanicMsg {
buf: [0; 1024],
pos: 0,
};

write!(m, "{i}").unwrap();

// Invoke panic function.
let k = Kernel::default();
let f = unsafe { k.addr().add(#off) };
let f: unsafe extern "C" fn(fmt: *const core::ffi::c_char, ...) -> ! =
unsafe { core::mem::transmute(f) };

unsafe { f(c"%s".as_ptr(), m.buf.as_ptr()) };
}
})
}

0 comments on commit f989661

Please sign in to comment.