From 75a6f9a8ce4b1eda1d47c6e2b22deab626820301 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Fri, 10 Feb 2023 21:04:01 -0800 Subject: [PATCH] Add missing ir/debug.rs. --- src/ir/debug.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/ir/debug.rs diff --git a/src/ir/debug.rs b/src/ir/debug.rs new file mode 100644 index 0000000..5602cca --- /dev/null +++ b/src/ir/debug.rs @@ -0,0 +1,78 @@ +//! Debug info (currently, source-location maps). + +use crate::declare_entity; +use crate::entity::EntityVec; +use addr2line::gimli; +use std::collections::hash_map::Entry as HashEntry; +use std::collections::HashMap; + +declare_entity!(SourceFile, "file"); +declare_entity!(SourceLoc, "loc"); + +#[derive(Clone, Debug, Default)] +pub struct Debug { + source_files: EntityVec, + source_file_dedup: HashMap, + source_locs: EntityVec, + source_loc_dedup: HashMap, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SourceLocData { + file: SourceFile, + line: u32, + col: u32, +} + +impl Debug { + pub fn intern_file(&mut self, path: &str) -> SourceFile { + if let Some(id) = self.source_file_dedup.get(path) { + return *id; + } + let id = self.source_files.push(path.to_owned()); + self.source_file_dedup.insert(path.to_owned(), id); + id + } + + pub fn intern_loc(&mut self, file: SourceFile, line: u32, col: u32) -> SourceLoc { + let data = SourceLocData { file, line, col }; + match self.source_loc_dedup.entry(data) { + HashEntry::Vacant(v) => { + let id = self.source_locs.push(data); + *v.insert(id) + } + HashEntry::Occupied(o) => *o.get(), + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct DebugMap { + tuples: Vec<(u32, u32, SourceLoc)>, +} + +impl DebugMap { + pub(crate) fn from_dwarf( + dwarf: gimli::Dwarf, + debug: &mut Debug, + ) -> DebugMap { + let ctx = addr2line::Context::from_dwarf(dwarf).unwrap(); + let mut tuples = vec![]; + + let mut locs = ctx.find_location_range(0, u64::MAX).unwrap(); + while let Some((start, end, loc)) = locs.next() { + let file = debug.intern_file(loc.file.unwrap_or("")); + let loc = debug.intern_loc(file, loc.line.unwrap_or(0), loc.column.unwrap_or(0)); + tuples.push((start as u32, end as u32, loc)); + } + + log::trace!("tuples:"); + for &(start, end, loc) in &tuples { + log::trace!(" {:x} - {:x}: {}", start, end, loc); + } + log::trace!("files: {:?}", debug.source_files); + log::trace!("locs: {:?}", debug.source_locs); + + DebugMap { tuples } + } +}