From 6a496b01b3e8a85c8231c949a306933e7ad58bfc Mon Sep 17 00:00:00 2001 From: Josh Ferrell Date: Thu, 18 Jul 2024 14:05:23 -0400 Subject: Support loading supplementary DWARF files --- .../dwarf/dwarf_import/src/dwarfdebuginfo.rs | 43 +++++++++++++++------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs') diff --git a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs index 0e0e8f53..4cb64138 100644 --- a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs +++ b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::helpers::{get_uid, resolve_specification, DieReference}; +use crate::{helpers::{get_uid, resolve_specification, DieReference}, ReaderType}; use binaryninja::{ binaryview::{BinaryView, BinaryViewBase, BinaryViewExt}, @@ -25,7 +25,7 @@ use binaryninja::{ binaryninjacore_sys::BNVariableSourceType, }; -use gimli::{DebuggingInformationEntry, Dwarf, Reader, Unit}; +use gimli::{DebuggingInformationEntry, Dwarf, Unit}; use log::{debug, error, warn}; use std::{ @@ -111,16 +111,17 @@ impl DebugType { } } -pub(crate) struct DebugInfoBuilderContext> { - dwarf: Dwarf, +pub(crate) struct DebugInfoBuilderContext { units: Vec>, + sup_units: Vec>, names: HashMap, default_address_size: usize, pub(crate) total_die_count: usize, } -impl> DebugInfoBuilderContext { - pub(crate) fn new(view: &BinaryView, dwarf: Dwarf) -> Option { +impl DebugInfoBuilderContext { + pub(crate) fn new(view: &BinaryView, dwarf: &Dwarf) -> Option { + let mut units = vec![]; let mut iter = dwarf.units(); while let Ok(Some(header)) = iter.next() { @@ -132,40 +133,56 @@ impl> DebugInfoBuilderContext { } } + let mut sup_units = vec![]; + if let Some(sup_dwarf) = dwarf.sup() { + let mut sup_iter = sup_dwarf.units(); + while let Ok(Some(header)) = sup_iter.next() { + if let Ok(unit) = sup_dwarf.unit(header) { + sup_units.push(unit); + } else { + error!("Unable to read supplementary DWARF information. File may be malformed or corrupted. Not applying debug info."); + return None; + } + } + } + Some(Self { - dwarf, units, + sup_units, names: HashMap::new(), default_address_size: view.address_size(), total_die_count: 0, }) } - pub(crate) fn dwarf(&self) -> &Dwarf { - &self.dwarf - } - pub(crate) fn units(&self) -> &[Unit] { &self.units } + pub(crate) fn sup_units(&self) -> &[Unit] { + &self.sup_units + } + pub(crate) fn default_address_size(&self) -> usize { self.default_address_size } pub(crate) fn set_name(&mut self, die_uid: TypeUID, name: String) { + // die_uids need to be unique here assert!(self.names.insert(die_uid, name).is_none()); } pub(crate) fn get_name( &self, + dwarf: &Dwarf, unit: &Unit, entry: &DebuggingInformationEntry, ) -> Option { - match resolve_specification(unit, entry, self) { - DieReference::UnitAndOffset((entry_unit, entry_offset)) => self + match resolve_specification(dwarf, unit, entry, self) { + DieReference::UnitAndOffset((dwarf, entry_unit, entry_offset)) => self .names .get(&get_uid( + dwarf, entry_unit, &entry_unit.entry(entry_offset).unwrap(), )) -- cgit v1.3.1