Skip to content

Commit a91f55f

Browse files
committed
Adds panic handler
1 parent 47b28cb commit a91f55f

File tree

9 files changed

+88
-84
lines changed

9 files changed

+88
-84
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ jobs:
1616
- name: Check Rust styles
1717
run: cargo fmt --check
1818
- name: Lint
19-
run: cargo clippy -- -D warnings
19+
run: cargo clippy --workspace -- -D warnings
20+
- name: Run tests
21+
run: cargo test --workspace

Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ name = "okf"
33
version = "0.1.0"
44
edition = "2024"
55

6-
[lints.rust]
7-
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(fw, values("1100"))'] }
8-
96
[dependencies]
107
bitflags = "2.5.0"
118
okf-macros = { version = "0.1.0", path = "macros" }

macros/src/lib.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use syn::{Error, ItemStruct, LitInt, TraitItem, parse_macro_input};
33

44
mod derive;
55
mod offset;
6-
mod panic_handler;
76

87
#[proc_macro_derive(MappedKernel)]
98
pub fn derive_mapped_kernel(item: TokenStream) -> TokenStream {
@@ -23,12 +22,3 @@ pub fn offset(args: TokenStream, item: TokenStream) -> TokenStream {
2322
.unwrap_or_else(Error::into_compile_error)
2423
.into()
2524
}
26-
27-
#[proc_macro]
28-
pub fn panic_handler(args: TokenStream) -> TokenStream {
29-
let args = parse_macro_input!(args as LitInt);
30-
31-
self::panic_handler::transform(args)
32-
.unwrap_or_else(Error::into_compile_error)
33-
.into()
34-
}

macros/src/panic_handler.rs

Lines changed: 0 additions & 53 deletions
This file was deleted.

ps4-1100/build.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

ps4-1100/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use okf::malloc::MallocFlags;
1818
use okf::queue::TailQueue;
1919
use okf::socket::SockAddr;
2020
use okf::uio::UioSeg;
21-
use okf::{Function, MappedKernel, StaticMut, offset, panic_handler};
21+
use okf::{Function, MappedKernel, StaticMut, offset};
2222

2323
mod file;
2424
mod lock;
@@ -55,7 +55,7 @@ impl okf::Kernel for Kernel {
5555
const MOUNTLIST_MTX: StaticMut<Self::Mtx>;
5656
const NOCPU: u32 = 0xff;
5757
#[offset(0x1987C0)]
58-
const PANIC: Function<extern "C" fn(*const c_char, ...) -> !>;
58+
const PANIC: Function<unsafe extern "C" fn(*const c_char, ...) -> !>;
5959
const VDIR: c_int = 2;
6060
#[offset(0x15308F0)]
6161
const VOP_LOOKUP: StaticMut<Self::VnodeOp>;
@@ -221,5 +221,3 @@ impl okf::Kernel for Kernel {
221221

222222
unsafe impl Send for Kernel {}
223223
unsafe impl Sync for Kernel {}
224-
225-
panic_handler!(0x1987C0);

src/lib.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub mod malloc;
2929
pub mod mount;
3030
pub mod namei;
3131
pub mod notification;
32+
pub mod panic;
3233
pub mod pcpu;
3334
pub mod queue;
3435
pub mod socket;
@@ -37,14 +38,6 @@ pub mod ucred;
3738
pub mod uio;
3839
pub mod vnode;
3940

40-
#[cfg(fw = "1100")]
41-
#[macro_export]
42-
macro_rules! kernel {
43-
() => {
44-
okf_1100::Kernel
45-
};
46-
}
47-
4841
/// Provides methods to access the PS4 kernel for a specific version.
4942
///
5043
/// All methods here are a direct call to the kernel so most of them are unsafe and hard to use.
@@ -63,7 +56,7 @@ pub trait Kernel: MappedKernel {
6356
const MOUNTLIST: StaticMut<TailQueue<Self::Mount>>;
6457
const MOUNTLIST_MTX: StaticMut<Self::Mtx>;
6558
const NOCPU: u32;
66-
const PANIC: Function<extern "C" fn(*const c_char, ...) -> !>;
59+
const PANIC: Function<unsafe extern "C" fn(*const c_char, ...) -> !>;
6760
const VDIR: c_int;
6861
const VOP_LOOKUP: StaticMut<Self::VnodeOp>;
6962
const VOP_READ: StaticMut<Self::VnodeOp>;
@@ -397,7 +390,9 @@ impl<T> Offset for StaticMut<T> {
397390
}
398391
}
399392

400-
/// Implementation of [`StaticOps`] for [`StaticMut`].
393+
/// Implementation of [`OffsetOps`] for [`StaticMut`].
394+
///
395+
/// This type does not implement [DerefMut](core::ops::DerefMut) by design.
401396
pub struct MutableOps<T>(*mut T);
402397

403398
impl<T> MutableOps<T> {
@@ -462,7 +457,7 @@ impl<T: KernelFn> Clone for Function<T> {
462457
impl<T: KernelFn> Copy for Function<T> {}
463458

464459
impl<T: KernelFn> Offset for Function<T> {
465-
type Ops = ImmutableOps<T>;
460+
type Ops = FunctionOps<T>;
466461

467462
fn get(self) -> usize {
468463
self.off
@@ -506,7 +501,7 @@ pub trait KernelFn: Copy {
506501
unsafe fn from_addr(addr: *const u8) -> Self;
507502
}
508503

509-
impl<R, A1> KernelFn for extern "C" fn(A1, ...) -> R {
504+
impl<R, A1> KernelFn for unsafe extern "C" fn(A1, ...) -> R {
510505
unsafe fn from_addr(addr: *const u8) -> Self {
511506
unsafe { transmute(addr) }
512507
}

src/panic/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use self::msg::Message;
2+
use crate::Kernel;
3+
use core::fmt::Write;
4+
use core::panic::PanicInfo;
5+
6+
mod msg;
7+
8+
pub fn panic<K: Kernel>(k: K, i: &PanicInfo) -> ! {
9+
// Write panic message.
10+
let mut m = Message::default();
11+
let _ = write!(m, "{i}");
12+
13+
// Invoke panic function.
14+
let f = k.get(K::PANIC).as_ptr();
15+
16+
unsafe { f(c"%s".as_ptr(), m.as_ptr()) };
17+
}

src/panic/msg.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use core::cmp::min;
2+
use core::ffi::c_char;
3+
use core::fmt::Write;
4+
5+
/// Provides [`Write`] implementation backed by a fixed size buffer.
6+
pub struct Message {
7+
buf: [u8; 2048],
8+
pos: usize,
9+
}
10+
11+
impl Message {
12+
pub fn as_ptr(&self) -> *const c_char {
13+
self.buf.as_ptr().cast()
14+
}
15+
}
16+
17+
impl Default for Message {
18+
fn default() -> Self {
19+
Self {
20+
buf: [0; 2048],
21+
pos: 0,
22+
}
23+
}
24+
}
25+
26+
impl Write for Message {
27+
fn write_str(&mut self, s: &str) -> core::fmt::Result {
28+
// This method need to be careful not to cause any panic so we don't end up nested panic.
29+
let len = min(s.len(), (self.buf.len() - 1) - self.pos);
30+
let buf = unsafe { self.buf.as_mut_ptr().add(self.pos) };
31+
32+
unsafe { buf.copy_from_nonoverlapping(s.as_ptr(), len) };
33+
self.pos += len;
34+
35+
Ok(())
36+
}
37+
}
38+
39+
#[cfg(test)]
40+
mod tests {
41+
use super::*;
42+
43+
#[test]
44+
fn write_str() {
45+
let mut m = Message::default();
46+
47+
write!(m, "Hello, world!").unwrap();
48+
49+
assert!(m.buf.as_slice().starts_with(b"Hello, world!\0"));
50+
51+
// Make sure repeated write on a full buffer won't do anything.
52+
for _ in 0..m.buf.len() {
53+
write!(m, "Hello, world!").unwrap();
54+
}
55+
56+
assert!(m.buf.as_slice().starts_with(b"Hello, world!Hello"));
57+
assert_eq!(m.buf.last().copied().unwrap(), 0);
58+
}
59+
}

0 commit comments

Comments
 (0)