From 5930de7038d31bb07046c78c2d37c38e921df432 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Mon, 20 Jul 2020 17:25:38 -0400 Subject: [PATCH] Support Linkle's DWARF implementation for target_env = "devkita64" (#361) * Disable libbacktrace on DevkitA64 * Force noop symbolizer on DevkitA64 (for now) * Add support for linkle's DWARF format to gimli symbolizer * fmt * Address review * Subtract bias from len, revert back to wrapping_add * Use Vec::with_capacity in mmap_fake * fmt --- src/symbolize/gimli.rs | 48 ++++++++++++++++++++++++++++---- src/symbolize/gimli/mmap_fake.rs | 25 +++++++++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 src/symbolize/gimli/mmap_fake.rs diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs index 1bb972992..82c758b43 100644 --- a/src/symbolize/gimli.rs +++ b/src/symbolize/gimli.rs @@ -28,12 +28,19 @@ mod mystd { #[cfg(not(backtrace_in_libstd))] extern crate std as mystd; -#[cfg(windows)] -#[path = "gimli/mmap_windows.rs"] -mod mmap; -#[cfg(unix)] -#[path = "gimli/mmap_unix.rs"] -mod mmap; +cfg_if::cfg_if! { + if #[cfg(windows)] { + #[path = "gimli/mmap_windows.rs"] + mod mmap; + } else if #[cfg(target_env = "devkita64")] { + #[path = "gimli/mmap_fake.rs"] + mod mmap; + } else { + #[path = "gimli/mmap_unix.rs"] + mod mmap; + } +} + mod stash; const MAPPINGS_CACHE_SIZE: usize = 4; @@ -386,6 +393,35 @@ cfg_if::cfg_if! { }); 0 } + } else if #[cfg(target_env = "devkita64")] { + // DevkitA64 doesn't natively support debug info, but the build system will place debug + // info at the path `romfs:/debug_info.elf`. + mod elf; + use self::elf::Object; + + fn native_libraries() -> Vec { + extern "C" { + static __start__: u8; + } + + let bias = unsafe { &__start__ } as *const u8 as usize; + + let mut ret = Vec::new(); + let mut segments = Vec::new(); + segments.push(LibrarySegment { + stated_virtual_memory_address: 0, + len: usize::max_value() - bias, + }); + + let path = "romfs:/debug_info.elf"; + ret.push(Library { + name: path.into(), + segments, + bias, + }); + + ret + } } else { // Everything else should use ELF, but doesn't know how to load native // libraries. diff --git a/src/symbolize/gimli/mmap_fake.rs b/src/symbolize/gimli/mmap_fake.rs new file mode 100644 index 000000000..ce5096415 --- /dev/null +++ b/src/symbolize/gimli/mmap_fake.rs @@ -0,0 +1,25 @@ +use super::{mystd::io::Read, File}; +use alloc::vec::Vec; +use core::ops::Deref; + +pub struct Mmap { + vec: Vec, +} + +impl Mmap { + pub unsafe fn map(mut file: &File, len: usize) -> Option { + let mut mmap = Mmap { + vec: Vec::with_capacity(len), + }; + file.read_to_end(&mut mmap.vec).ok()?; + Some(mmap) + } +} + +impl Deref for Mmap { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.vec[..] + } +}