diff --git a/Cargo.toml b/Cargo.toml index 756070a..225f23d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ smallvec = "1.7" rayon = "1.5" lazy_static = "1.4" libc = "0.2" +addr2line = "0.19" diff --git a/src/frontend.rs b/src/frontend.rs index 57b4dbb..7a5bf97 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -7,6 +7,7 @@ use crate::errors::FrontendError; use crate::ir::*; use crate::op_traits::{op_inputs, op_outputs}; use crate::ops::Operator; +use addr2line::gimli; use anyhow::{bail, Result}; use fxhash::{FxHashMap, FxHashSet}; use log::trace; @@ -19,10 +20,13 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result> { let mut module = Module::with_orig_bytes(bytes); let parser = Parser::new(0); let mut next_func = 0; + let mut dwarf = gimli::Dwarf::default(); for payload in parser.parse_all(bytes) { let payload = payload?; - handle_payload(&mut module, payload, &mut next_func)?; + handle_payload(&mut module, payload, &mut next_func, &mut dwarf)?; } + let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug); + module.debug_map = debug_map; Ok(module) } @@ -57,6 +61,7 @@ fn handle_payload<'a>( module: &mut Module<'a>, payload: Payload<'a>, next_func: &mut usize, + dwarf: &mut gimli::Dwarf>, ) -> Result<()> { trace!("Wasm parser item: {:?}", payload); match payload { @@ -213,6 +218,38 @@ fn handle_payload<'a>( } } } + Payload::CustomSection(reader) if reader.name() == ".debug_info" => { + dwarf.debug_info = gimli::DebugInfo::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_abbrev" => { + dwarf.debug_abbrev = gimli::DebugAbbrev::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_addr" => { + dwarf.debug_addr = + gimli::DebugAddr::from(gimli::EndianSlice::new(reader.data(), gimli::LittleEndian)); + } + Payload::CustomSection(reader) if reader.name() == ".debug_aranges" => { + dwarf.debug_aranges = gimli::DebugAranges::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_line" => { + dwarf.debug_line = gimli::DebugLine::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_line_str" => { + dwarf.debug_line_str = gimli::DebugLineStr::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_str" => { + dwarf.debug_str = gimli::DebugStr::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(reader) if reader.name() == ".debug_str_offsets" => { + dwarf.debug_str_offsets = gimli::DebugStrOffsets::from(gimli::EndianSlice::new( + reader.data(), + gimli::LittleEndian, + )); + } + Payload::CustomSection(reader) if reader.name() == ".debug_types" => { + dwarf.debug_types = gimli::DebugTypes::new(reader.data(), gimli::LittleEndian); + } + Payload::CustomSection(_) => {} Payload::CodeSectionStart { .. } => {} Payload::Version { .. } => {} Payload::ElementSection(reader) => { diff --git a/src/ir.rs b/src/ir.rs index 5fafc10..c7d10ad 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -69,3 +69,5 @@ mod value; pub use value::*; mod display; pub use display::*; +mod debug; +pub use debug::*; diff --git a/src/ir/module.rs b/src/ir/module.rs index 077248c..ae2e75c 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -1,6 +1,6 @@ use super::{Func, FuncDecl, Global, Memory, ModuleDisplay, Signature, Table, Type}; use crate::entity::{EntityRef, EntityVec}; -use crate::ir::FunctionBody; +use crate::ir::{Debug, DebugMap, FunctionBody}; use crate::{backend, frontend}; use anyhow::Result; @@ -15,6 +15,8 @@ pub struct Module<'a> { pub exports: Vec, pub memories: EntityVec, pub start_func: Option, + pub debug: Debug, + pub debug_map: DebugMap, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -137,6 +139,8 @@ impl<'a> Module<'a> { exports: vec![], memories: EntityVec::default(), start_func: None, + debug: Debug::default(), + debug_map: DebugMap::default(), } } }