Skip to content

Commit

Permalink
wip(panic): replace libunwind with unwinding
Browse files Browse the repository at this point in the history
  • Loading branch information
SK83RJOSH committed Jan 15, 2024
1 parent 693423a commit d6c609f
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 298 deletions.
1 change: 1 addition & 0 deletions psp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bitflags = "1.2.1"
libm = "0.2.1"
embedded-graphics = { version = "0.7.1", optional = true, features = ["fixed_point"] }
unstringify = "0.1.4"
unwinding = { path = "../../unwinding", default-features = false, features = ["unwinder", "fde-custom", "personality", "panic", "dwarf-expr", "hide-trace"] }

[dependencies.num_enum]
version = "0.5.0"
Expand Down
26 changes: 7 additions & 19 deletions psp/build.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
use std::{env, path::Path};
use std::env;
use std::path::Path;

fn main() {
println!("cargo:rerun-if-changed=psp.ld");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=libunwind.a");
println!("cargo:rerun-if-env-changed=RUSTFLAGS");

if env::var("CARGO_FEATURE_STUB_ONLY").is_ok() {
return;
}

// Figure out whether to use the LTO libunwind, or the regular one.
let libunwind = if env::var("CARGO_ENCODED_RUSTFLAGS")
.unwrap()
.split('\x1f')
.any(|flags| flags.starts_with("-Clinker-plugin-lto"))
{
"./libunwind_lto.a"
} else {
"./libunwind.a"
};

// TODO: Do we even need to copy the library over? Maybe we can just link
// directly from the current directory.
let out_dir = env::var("OUT_DIR").unwrap();
let out_file = Path::new(&out_dir).join("libunwind.a");
std::fs::copy(libunwind, out_file).unwrap();
let out_file = Path::new(&out_dir).join("psp.ld");
std::fs::copy("psp.ld", out_file).unwrap();

println!("cargo:rustc-link-lib=static=unwind");
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-arg=-Tpsp.ld");
println!("cargo:rustc-link-search={}", out_dir);
}
Binary file removed psp/libunwind.a
Binary file not shown.
Binary file removed psp/libunwind_lto.a
Binary file not shown.
37 changes: 37 additions & 0 deletions psp/psp.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ENTRY(module_start)
SECTIONS
{
/* PRX format requires text to begin at 0 */
.text 0 : { KEEP(*(.text .text.*)) }
PROVIDE(__text = ADDR(.text));

/* Sort stubs for convenient ordering */
.sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) }

/* Keep these sections around, even though they may appear unused to the linker */
.lib.ent.top : { KEEP(*(.lib.ent.top)) }
.lib.ent : { KEEP(*(.lib.ent)) }
.lib.ent.btm : { KEEP(*(.lib.ent.btm)) }
.lib.stub.top : { KEEP(*(.lib.stub.top)) }
.lib.stub : { KEEP(*(.lib.stub)) }
.lib.stub.btm : { KEEP(*(.lib.stub.btm)) }

/* Exception support */
.eh_frame_hdr : { KEEP(*(.eh_frame_hdr .eh_frame_hdr.*)) }
PROVIDE(__eh_frame_hdr = ADDR(.eh_frame_hdr));
.eh_frame : { KEEP(*(.eh_frame .eh_frame.*)) }
PROVIDE(__eh_frame = ADDR(.eh_frame));

/* These are explicitly listed to avoid being merged into .rodata */
.rodata.sceResident : { *(.rodata.sceResident) *(.rodata.sceResident.*) }
.rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) }
/* Sort NIDs for convenient ordering */
.rodata.sceNid : { *(.rodata.sceNid) *(SORT(.rodata.sceNid.*)) }

.rodata : { *(.rodata .rodata.*) }
.data : { *(.data .data.*) }
.gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) }
.bss : { *(.bss .bss.*) }

/DISCARD/ : { *(.rel.sceStub.text .MIPS.abiflags .reginfo) }
}
42 changes: 35 additions & 7 deletions psp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
c_variadic,
lang_items
)]
// For unwinding support
#![feature(std_internals, panic_info_message, panic_internals, c_unwind)]
#![cfg_attr(not(feature = "stub-only"), feature(panic_unwind))]
#![cfg_attr(feature = "std", feature(psp_std))]
// For the `const_generics` feature.
#![allow(incomplete_features)]
Expand All @@ -22,7 +19,7 @@ extern crate paste;
#[cfg(not(feature = "stub-only"))]
extern crate alloc;
#[cfg(not(feature = "stub-only"))]
extern crate panic_unwind;
extern crate unwinding;

#[macro_use]
#[doc(hidden)]
Expand All @@ -41,8 +38,9 @@ pub mod vram_alloc;

#[cfg(not(feature = "stub-only"))]
mod alloc_impl;

#[cfg(not(feature = "stub-only"))]
pub mod panic;
mod panic;

#[cfg(not(feature = "stub-only"))]
mod screenshot;
Expand Down Expand Up @@ -83,7 +81,35 @@ extern "C" fn __rust_foreign_exception() -> ! {
pub use std::panic::catch_unwind;

#[cfg(all(not(feature = "std"), not(feature = "stub-only")))]
pub use panic::catch_unwind;
pub use unwinding::panic::catch_unwind;

#[cfg(all(not(feature = "std"), not(feature = "stub-only")))]
pub mod eh_unwinding {
use unwinding::custom_eh_frame_finder::*;

extern "C" {
static __text: u8;
static __eh_frame_hdr: u8;
}

pub struct EhFrameFinderImpl;

unsafe impl EhFrameFinder for EhFrameFinderImpl {
fn find(&self, _pc: usize) -> Option<FrameInfo> {
unsafe {
Some(FrameInfo {
text_base: Some(&__text as *const _ as usize),
kind: FrameInfoKind::EhFrameHdr(&__eh_frame_hdr as *const _ as usize),
})
}
}
}

pub fn set_eh_frame_finder() -> Result<(), SetCustomEhFrameFinderError> {
static EH_FRAME_FINDER: &(dyn EhFrameFinder + Sync) = &EhFrameFinderImpl;
set_custom_eh_frame_finder(EH_FRAME_FINDER)
}
}

#[cfg(feature = "embedded-graphics")]
pub mod embedded_graphics;
Expand Down Expand Up @@ -164,7 +190,9 @@ macro_rules! _start {
unsafe { init_cwd($argv as *mut u8) };
}

// TODO: Maybe print any error to debug screen?
#[cfg(all(not(feature = "std"), not(feature = "stub-only")))]
$crate::eh_unwinding::set_eh_frame_finder();

let _ = $crate::catch_unwind($psp_main);

0
Expand Down

0 comments on commit d6c609f

Please sign in to comment.