diff --git a/crates/debug/src/read_debuginfo.rs b/crates/debug/src/read_debuginfo.rs index 014e81fd65..9416799bc4 100644 --- a/crates/debug/src/read_debuginfo.rs +++ b/crates/debug/src/read_debuginfo.rs @@ -26,6 +26,7 @@ pub struct FunctionMetadata { pub struct WasmFileInfo { pub path: Option, pub code_section_offset: u64, + pub imported_func_count: u32, pub funcs: Box<[FunctionMetadata]>, } @@ -164,6 +165,7 @@ pub fn read_debuginfo(data: &[u8]) -> Result { let mut sections = HashMap::new(); let mut name_section = None; let mut code_section_offset = 0; + let mut imported_func_count = 0; let mut signatures_params: Vec> = Vec::new(); let mut func_params_refs: Vec = Vec::new(); @@ -193,6 +195,13 @@ pub fn read_debuginfo(data: &[u8]) -> Result { .map(|ft| Ok(ft?.params)) .collect::>>()?; } + SectionCode::Import => { + for i in section.get_import_section_reader()? { + if let wasmparser::ImportSectionEntryType::Function(_) = i?.ty { + imported_func_count += 1; + } + } + } SectionCode::Function => { func_params_refs = section .get_function_section_reader()? @@ -234,6 +243,7 @@ pub fn read_debuginfo(data: &[u8]) -> Result { wasm_file: WasmFileInfo { path: None, code_section_offset, + imported_func_count, funcs: func_meta.into_boxed_slice(), }, }) diff --git a/crates/debug/src/transform/address_transform.rs b/crates/debug/src/transform/address_transform.rs index c89c9ea92b..c134266675 100644 --- a/crates/debug/src/transform/address_transform.rs +++ b/crates/debug/src/transform/address_transform.rs @@ -737,6 +737,7 @@ mod tests { &WasmFileInfo { path: None, code_section_offset: 1, + imported_func_count: 0, funcs: Box::new([]), }, ); diff --git a/crates/debug/src/transform/expression.rs b/crates/debug/src/transform/expression.rs index d7c5d5aa31..f901b03575 100644 --- a/crates/debug/src/transform/expression.rs +++ b/crates/debug/src/transform/expression.rs @@ -333,7 +333,14 @@ where return Ok(None); } let index = pc.read_sleb128()?; - pc.read_u8()?; // consume 159 + if pc.read_u8()? != 159 { + // FIXME The following operator is not DW_OP_stack_value, e.g. : + // DW_AT_location (0x00000ea5: + // [0x00001e19, 0x00001e26): DW_OP_WASM_location 0x0 +1, DW_OP_plus_uconst 0x10, DW_OP_stack_value + // [0x00001e5a, 0x00001e72): DW_OP_WASM_location 0x0 +20, DW_OP_stack_value + // ) + return Ok(None); + } if !code_chunk.is_empty() { parts.push(CompiledExpressionPart::Code(code_chunk)); code_chunk = Vec::new(); diff --git a/crates/debug/src/transform/simulate.rs b/crates/debug/src/transform/simulate.rs index e4b7729c05..baf76e640b 100644 --- a/crates/debug/src/transform/simulate.rs +++ b/crates/debug/src/transform/simulate.rs @@ -8,7 +8,7 @@ use gimli::{self, LineEncoding}; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use wasmtime_environ::entity::EntityRef; -use wasmtime_environ::wasm::get_vmctx_value_label; +use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex}; use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges}; pub use crate::read_debuginfo::{DebugInfoData, FunctionMetadata, WasmType}; @@ -18,7 +18,7 @@ const PRODUCER_NAME: &str = "wasmtime"; fn generate_line_info( addr_tr: &AddressTransform, - translated: &HashSet, + translated: &HashSet, out_encoding: gimli::Encoding, w: &WasmFileInfo, comp_dir_id: write::StringId, @@ -46,7 +46,7 @@ fn generate_line_info( for (i, map) in addr_tr.map() { let symbol = i.index(); - if translated.contains(&(symbol as u32)) { + if translated.contains(&i) { continue; } @@ -257,7 +257,7 @@ pub fn generate_simulated_dwarf( di: &DebugInfoData, vmctx_info: &ModuleVmctxInfo, ranges: &ValueLabelsRanges, - translated: &HashSet, + translated: &HashSet, out_encoding: gimli::Encoding, out_units: &mut write::UnitTable, out_strings: &mut write::StringTable, @@ -277,6 +277,7 @@ pub fn generate_simulated_dwarf( } else { (None, None) }; + let imported_func_count = di.wasm_file.imported_func_count; let (unit, root_id, name_id) = { let comp_dir_id = out_strings.add( @@ -326,7 +327,7 @@ pub fn generate_simulated_dwarf( for (i, map) in addr_tr.map().iter() { let index = i.index(); - if translated.contains(&(index as u32)) { + if translated.contains(&i) { continue; } @@ -346,9 +347,10 @@ pub fn generate_simulated_dwarf( write::AttributeValue::Udata((end - start) as u64), ); - let id = match func_names.and_then(|m| m.get(&(index as u32))) { + let func_index = imported_func_count + (index as u32); + let id = match func_names.and_then(|m| m.get(&func_index)) { Some(n) => out_strings.add(n.to_owned()), - None => out_strings.add(format!("wasm-function[{}]", index)), + None => out_strings.add(format!("wasm-function[{}]", func_index)), }; die.set(gimli::DW_AT_name, write::AttributeValue::StringRef(id)); diff --git a/crates/debug/src/transform/unit.rs b/crates/debug/src/transform/unit.rs index c019fd944b..ca49a78aac 100644 --- a/crates/debug/src/transform/unit.rs +++ b/crates/debug/src/transform/unit.rs @@ -10,8 +10,8 @@ use anyhow::{Context, Error}; use gimli::write; use gimli::{AttributeValue, DebuggingInformationEntry, Unit}; use std::collections::HashSet; -use wasmtime_environ::entity::EntityRef; use wasmtime_environ::isa::TargetIsa; +use wasmtime_environ::wasm::DefinedFuncIndex; use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges}; struct InheritedAttr { @@ -148,7 +148,7 @@ pub(crate) fn clone_unit<'a, R>( module_info: &ModuleVmctxInfo, out_units: &mut write::UnitTable, out_strings: &mut write::StringTable, - translated: &mut HashSet, + translated: &mut HashSet, isa: &dyn TargetIsa, ) -> Result, Error> where @@ -270,7 +270,7 @@ where { current_value_range.push(new_stack_len, frame_info); } - translated.insert(func_index.index() as u32); + translated.insert(func_index); current_scope_ranges.push(new_stack_len, range_builder.get_ranges(addr_tr)); Some(range_builder) } else { diff --git a/tests/debug/simulate.rs b/tests/debug/simulate.rs index c6f11d5010..b727b46acd 100644 --- a/tests/debug/simulate.rs +++ b/tests/debug/simulate.rs @@ -54,3 +54,24 @@ fn test_debug_dwarf_simulate_simple_x86_64() -> Result<()> { )"#, ) } + +#[test] +#[ignore] +#[cfg(all( + any(target_os = "linux", target_os = "macos"), + target_pointer_width = "64" +))] +fn test_debug_dwarf_simulate_with_imports_x86_64() -> Result<()> { + check_wat( + r#" +;; check: DW_TAG_compile_unit +(module +;; check: DW_TAG_subprogram +;; check: DW_AT_name ("func1") + (import "foo" "bar" (func $import1) ) + (func $func1 (result i32) + i32.const 1 + ) +)"#, + ) +}