Skip to content

Commit

Permalink
read: add helper methods for working with split DWARF (#637)
Browse files Browse the repository at this point in the history
* Add a helper to get the DWO name.

* Add a helper to blend two Dwarf<T>s appropriately for the unpacked split DWARF case.
  • Loading branch information
khuey authored Jan 16, 2023
1 parent 0f80a02 commit fd6692a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
8 changes: 3 additions & 5 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,10 @@ where

let mut dwarf = gimli::Dwarf::load(&mut load_section)?;
if flags.dwo {
dwarf.file_type = gimli::DwarfFileType::Dwo;
if let Some(dwo_parent) = dwo_parent {
dwarf.debug_addr = dwo_parent.debug_addr.clone();
dwarf
.ranges
.set_debug_ranges(dwo_parent.ranges.debug_ranges().clone());
dwarf.make_dwo(&dwo_parent);
} else {
dwarf.file_type = gimli::DwarfFileType::Dwo;
}
}

Expand Down
34 changes: 34 additions & 0 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,21 @@ impl<R: Reader> Dwarf<R> {
}
}

impl<R: Clone> Dwarf<R> {
/// Assuming `self` was loaded from a .dwo, take the appropriate
/// sections from `parent` (which contains the skeleton unit for this
/// dwo) such as `.debug_addr` and merge them into this `Dwarf`.
pub fn make_dwo(&mut self, parent: &Dwarf<R>) {
self.file_type = DwarfFileType::Dwo;
// These sections are always taken from the parent file and not the dwo.
self.debug_addr = parent.debug_addr.clone();
// .debug_rnglists comes from the DWO, .debug_ranges comes from the
// parent file.
self.ranges
.set_debug_ranges(parent.ranges.debug_ranges().clone());
}
}

/// The sections from a `.dwp` file.
#[derive(Debug)]
pub struct DwarfPackage<R: Reader> {
Expand Down Expand Up @@ -996,6 +1011,25 @@ impl<R: Reader> Unit<R> {
self.rnglists_base = other.rnglists_base;
}
}

/// Find the dwo name (if any) for this unit, automatically handling the differences
/// between the standardized DWARF 5 split DWARF format and the pre-DWARF 5 GNU
/// extension.
///
/// The returned value is relative to this unit's `comp_dir`.
pub fn dwo_name(&self) -> Result<Option<AttributeValue<R>>> {
let mut entries = self.entries();
if let None = entries.next_entry()? {
return Ok(None);
}

let entry = entries.current().unwrap();
if self.header.version() < 5 {
entry.attr_value(constants::DW_AT_GNU_dwo_name)
} else {
entry.attr_value(constants::DW_AT_dwo_name)
}
}
}

impl<T: ReaderOffset> UnitSectionOffset<T> {
Expand Down

0 comments on commit fd6692a

Please sign in to comment.