use std::{ops::Deref, sync::Arc};
use gimli::{EndianReader, LittleEndian};
use object::ObjectSection;
pub fn load(file: &'_ object::File<'static>) -> gimli::Result<Dwarf> {
let load = |id: gimli::SectionId| {
Ok(gimli::EndianReader::new(
object::Object::section_by_name(file, id.name())
.map(|s| match s.uncompressed_data().unwrap() {
std::borrow::Cow::Borrowed(b) => OwnedOrBorrowed::Borrowed(b),
std::borrow::Cow::Owned(v) => OwnedOrBorrowed::Owned(Arc::new(v)),
})
.unwrap_or(OwnedOrBorrowed::Borrowed(&[])),
gimli::LittleEndian,
))
};
gimli::Dwarf::load(&load)
}
#[derive(Clone, Debug)]
pub enum OwnedOrBorrowed {
Borrowed(&'static [u8]),
Owned(Arc<Vec<u8>>),
}
impl Deref for OwnedOrBorrowed {
type Target = [u8];
fn deref(&self) -> &[u8] {
match self {
OwnedOrBorrowed::Borrowed(slice) => slice,
OwnedOrBorrowed::Owned(arc) => arc,
}
}
}
unsafe impl gimli::StableDeref for OwnedOrBorrowed {}
unsafe impl gimli::CloneStableDeref for OwnedOrBorrowed {}
pub type DwarfReader = EndianReader<LittleEndian, OwnedOrBorrowed>;
pub type Dwarf = gimli::Dwarf<DwarfReader>;
pub type RawDie<'a> = gimli::DebuggingInformationEntry<'a, 'a, DwarfReader>;
pub type Offset = gimli::UnitOffset<usize>;