diff --git a/examples/dwarfdump.rs b/examples/dwarfdump.rs index 98ad2276..a11f298f 100644 --- a/examples/dwarfdump.rs +++ b/examples/dwarfdump.rs @@ -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; } } diff --git a/src/read/dwarf.rs b/src/read/dwarf.rs index cce364c2..43239665 100644 --- a/src/read/dwarf.rs +++ b/src/read/dwarf.rs @@ -571,6 +571,21 @@ impl Dwarf { } } +impl Dwarf { + /// 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) { + 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 { @@ -996,6 +1011,25 @@ impl Unit { 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>> { + 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 UnitSectionOffset {