diff options
| author | KyleMiles <krm504@nyu.edu> | 2023-08-22 13:01:09 -0400 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2023-08-22 13:01:09 -0400 |
| commit | 5b73fb82d272aa32ff124a69e96579679e7d3580 (patch) | |
| tree | 182844e264b4c9ae5727a9a1c86aa7bf0fd462aa /rust/examples/dwarf/dwarf_import/src/helpers.rs | |
| parent | 02ea8d7309a0c0777ac8a07bfc1e0fd497e9f5f5 (diff) | |
DWARF Import : Improved Cross-Compilation-Unit Handling
Diffstat (limited to 'rust/examples/dwarf/dwarf_import/src/helpers.rs')
| -rw-r--r-- | rust/examples/dwarf/dwarf_import/src/helpers.rs | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/rust/examples/dwarf/dwarf_import/src/helpers.rs b/rust/examples/dwarf/dwarf_import/src/helpers.rs index 5ea35017..8670e6f4 100644 --- a/rust/examples/dwarf/dwarf_import/src/helpers.rs +++ b/rust/examples/dwarf/dwarf_import/src/helpers.rs @@ -13,8 +13,9 @@ // limitations under the License. use gimli::{ - constants, Attribute, AttributeValue, AttributeValue::UnitRef, DebuggingInformationEntry, - Dwarf, Operation, Reader, Unit, UnitOffset, UnitSectionOffset, + constants, Attribute, AttributeValue, + AttributeValue::{DebugInfoRef, DebugInfoRefSup, UnitRef}, + DebuggingInformationEntry, Dwarf, Operation, Reader, Unit, UnitOffset, UnitSectionOffset, }; use std::ffi::CString; @@ -32,16 +33,52 @@ pub(crate) fn get_uid<R: Reader<Offset = usize>>( //////////////////////////////////// // DIE attr convenience functions -pub fn resolve_specification<R: Reader<Offset = usize>>( - unit: &Unit<R>, - entry: &DebuggingInformationEntry<R>, -) -> UnitOffset { - if let Ok(Some(UnitRef(offset))) = entry.attr_value(constants::DW_AT_specification) { - resolve_specification(unit, &unit.entry(offset).unwrap()) - } else if let Ok(Some(UnitRef(offset))) = entry.attr_value(constants::DW_AT_abstract_origin) { - resolve_specification(unit, &unit.entry(offset).unwrap()) +fn get_unit_copy<'a, R: Reader<Offset = usize>>(dwarf: &'a Dwarf<R>, unit: &'a Unit<R>) -> Unit<R> { + let mut iter = dwarf.units(); + while let Ok(Some(header)) = iter.next() { + if header.offset() == unit.header.offset() { + return dwarf.unit(header).unwrap(); + } + } + unreachable!() +} + +pub(crate) fn get_attr_die<'a, R: Reader<Offset = usize>>( + dwarf: &'a Dwarf<R>, + unit: &'a Unit<R>, + entry: &'a DebuggingInformationEntry<R>, + attr: constants::DwAt, +) -> Option<(Unit<R>, UnitOffset)> { + match entry.attr_value(attr) { + Ok(Some(UnitRef(offset))) => Some((get_unit_copy(dwarf, unit), offset)), + Ok(Some(DebugInfoRef(offset))) | Ok(Some(DebugInfoRefSup(offset))) => { + let mut iter = dwarf.units(); + while let Ok(Some(header)) = iter.next() { + if let Some(new_offset) = offset.to_unit_offset(&header) { + return Some((dwarf.unit(header).unwrap(), new_offset)); + } + } + unreachable!() //None + } + _ => None, + } +} + +pub(crate) fn resolve_specification<'a, R: Reader<Offset = usize>>( + dwarf: &'a Dwarf<R>, + unit: &'a Unit<R>, + entry: &'a DebuggingInformationEntry<R>, +) -> (Unit<R>, UnitOffset) { + if let Some((entry_unit, entry_offset)) = + get_attr_die(dwarf, unit, entry, constants::DW_AT_specification) + { + resolve_specification(dwarf, &entry_unit, &entry_unit.entry(entry_offset).unwrap()) + } else if let Some((entry_unit, entry_offset)) = + get_attr_die(dwarf, unit, entry, constants::DW_AT_abstract_origin) + { + resolve_specification(dwarf, &entry_unit, &entry_unit.entry(entry_offset).unwrap()) } else { - entry.offset() + (get_unit_copy(dwarf, unit), entry.offset()) } } @@ -51,10 +88,11 @@ pub(crate) fn get_name<R: Reader<Offset = usize>>( unit: &Unit<R>, entry: &DebuggingInformationEntry<R>, ) -> Option<CString> { - let entry = unit.entry(resolve_specification(unit, entry)).unwrap(); + let (entry_unit, entry_offset) = resolve_specification(dwarf, unit, entry); + let entry = entry_unit.entry(entry_offset).unwrap(); if let Ok(Some(attr_val)) = entry.attr_value(constants::DW_AT_name) { - if let Ok(attr_string) = dwarf.attr_string(unit, attr_val) { + if let Ok(attr_string) = dwarf.attr_string(&entry_unit, attr_val) { if let Ok(attr_string) = attr_string.to_string() { return Some(CString::new(attr_string.to_string()).unwrap()); } |
