Add missing ir/debug.rs.
This commit is contained in:
parent
ceaa8acac6
commit
75a6f9a8ce
78
src/ir/debug.rs
Normal file
78
src/ir/debug.rs
Normal file
|
@ -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<SourceFile, String>,
|
||||||
|
source_file_dedup: HashMap<String, SourceFile>,
|
||||||
|
source_locs: EntityVec<SourceLoc, SourceLocData>,
|
||||||
|
source_loc_dedup: HashMap<SourceLocData, SourceLoc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<R: gimli::Reader>(
|
||||||
|
dwarf: gimli::Dwarf<R>,
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue