Propertly simulate DWARF information when imports present (#1452)

* Ignore complex LLVM10 expressions.

* Propery function name when imports are present
This commit is contained in:
Yury Delendik
2020-03-31 18:33:35 -05:00
committed by GitHub
parent d3df275003
commit e64668776a
6 changed files with 52 additions and 11 deletions

View File

@@ -26,6 +26,7 @@ pub struct FunctionMetadata {
pub struct WasmFileInfo { pub struct WasmFileInfo {
pub path: Option<PathBuf>, pub path: Option<PathBuf>,
pub code_section_offset: u64, pub code_section_offset: u64,
pub imported_func_count: u32,
pub funcs: Box<[FunctionMetadata]>, pub funcs: Box<[FunctionMetadata]>,
} }
@@ -164,6 +165,7 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
let mut sections = HashMap::new(); let mut sections = HashMap::new();
let mut name_section = None; let mut name_section = None;
let mut code_section_offset = 0; let mut code_section_offset = 0;
let mut imported_func_count = 0;
let mut signatures_params: Vec<Box<[WasmType]>> = Vec::new(); let mut signatures_params: Vec<Box<[WasmType]>> = Vec::new();
let mut func_params_refs: Vec<usize> = Vec::new(); let mut func_params_refs: Vec<usize> = Vec::new();
@@ -193,6 +195,13 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
.map(|ft| Ok(ft?.params)) .map(|ft| Ok(ft?.params))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
} }
SectionCode::Import => {
for i in section.get_import_section_reader()? {
if let wasmparser::ImportSectionEntryType::Function(_) = i?.ty {
imported_func_count += 1;
}
}
}
SectionCode::Function => { SectionCode::Function => {
func_params_refs = section func_params_refs = section
.get_function_section_reader()? .get_function_section_reader()?
@@ -234,6 +243,7 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
wasm_file: WasmFileInfo { wasm_file: WasmFileInfo {
path: None, path: None,
code_section_offset, code_section_offset,
imported_func_count,
funcs: func_meta.into_boxed_slice(), funcs: func_meta.into_boxed_slice(),
}, },
}) })

View File

@@ -737,6 +737,7 @@ mod tests {
&WasmFileInfo { &WasmFileInfo {
path: None, path: None,
code_section_offset: 1, code_section_offset: 1,
imported_func_count: 0,
funcs: Box::new([]), funcs: Box::new([]),
}, },
); );

View File

@@ -333,7 +333,14 @@ where
return Ok(None); return Ok(None);
} }
let index = pc.read_sleb128()?; 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() { if !code_chunk.is_empty() {
parts.push(CompiledExpressionPart::Code(code_chunk)); parts.push(CompiledExpressionPart::Code(code_chunk));
code_chunk = Vec::new(); code_chunk = Vec::new();

View File

@@ -8,7 +8,7 @@ use gimli::{self, LineEncoding};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::path::PathBuf; use std::path::PathBuf;
use wasmtime_environ::entity::EntityRef; 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}; use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges};
pub use crate::read_debuginfo::{DebugInfoData, FunctionMetadata, WasmType}; pub use crate::read_debuginfo::{DebugInfoData, FunctionMetadata, WasmType};
@@ -18,7 +18,7 @@ const PRODUCER_NAME: &str = "wasmtime";
fn generate_line_info( fn generate_line_info(
addr_tr: &AddressTransform, addr_tr: &AddressTransform,
translated: &HashSet<u32>, translated: &HashSet<DefinedFuncIndex>,
out_encoding: gimli::Encoding, out_encoding: gimli::Encoding,
w: &WasmFileInfo, w: &WasmFileInfo,
comp_dir_id: write::StringId, comp_dir_id: write::StringId,
@@ -46,7 +46,7 @@ fn generate_line_info(
for (i, map) in addr_tr.map() { for (i, map) in addr_tr.map() {
let symbol = i.index(); let symbol = i.index();
if translated.contains(&(symbol as u32)) { if translated.contains(&i) {
continue; continue;
} }
@@ -257,7 +257,7 @@ pub fn generate_simulated_dwarf(
di: &DebugInfoData, di: &DebugInfoData,
vmctx_info: &ModuleVmctxInfo, vmctx_info: &ModuleVmctxInfo,
ranges: &ValueLabelsRanges, ranges: &ValueLabelsRanges,
translated: &HashSet<u32>, translated: &HashSet<DefinedFuncIndex>,
out_encoding: gimli::Encoding, out_encoding: gimli::Encoding,
out_units: &mut write::UnitTable, out_units: &mut write::UnitTable,
out_strings: &mut write::StringTable, out_strings: &mut write::StringTable,
@@ -277,6 +277,7 @@ pub fn generate_simulated_dwarf(
} else { } else {
(None, None) (None, None)
}; };
let imported_func_count = di.wasm_file.imported_func_count;
let (unit, root_id, name_id) = { let (unit, root_id, name_id) = {
let comp_dir_id = out_strings.add( let comp_dir_id = out_strings.add(
@@ -326,7 +327,7 @@ pub fn generate_simulated_dwarf(
for (i, map) in addr_tr.map().iter() { for (i, map) in addr_tr.map().iter() {
let index = i.index(); let index = i.index();
if translated.contains(&(index as u32)) { if translated.contains(&i) {
continue; continue;
} }
@@ -346,9 +347,10 @@ pub fn generate_simulated_dwarf(
write::AttributeValue::Udata((end - start) as u64), 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()), 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)); die.set(gimli::DW_AT_name, write::AttributeValue::StringRef(id));

View File

@@ -10,8 +10,8 @@ use anyhow::{Context, Error};
use gimli::write; use gimli::write;
use gimli::{AttributeValue, DebuggingInformationEntry, Unit}; use gimli::{AttributeValue, DebuggingInformationEntry, Unit};
use std::collections::HashSet; use std::collections::HashSet;
use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::isa::TargetIsa; use wasmtime_environ::isa::TargetIsa;
use wasmtime_environ::wasm::DefinedFuncIndex;
use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges}; use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges};
struct InheritedAttr<T> { struct InheritedAttr<T> {
@@ -148,7 +148,7 @@ pub(crate) fn clone_unit<'a, R>(
module_info: &ModuleVmctxInfo, module_info: &ModuleVmctxInfo,
out_units: &mut write::UnitTable, out_units: &mut write::UnitTable,
out_strings: &mut write::StringTable, out_strings: &mut write::StringTable,
translated: &mut HashSet<u32>, translated: &mut HashSet<DefinedFuncIndex>,
isa: &dyn TargetIsa, isa: &dyn TargetIsa,
) -> Result<Option<(write::UnitId, UnitRefsMap, PendingDebugInfoRefs)>, Error> ) -> Result<Option<(write::UnitId, UnitRefsMap, PendingDebugInfoRefs)>, Error>
where where
@@ -270,7 +270,7 @@ where
{ {
current_value_range.push(new_stack_len, frame_info); 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)); current_scope_ranges.push(new_stack_len, range_builder.get_ranges(addr_tr));
Some(range_builder) Some(range_builder)
} else { } else {

View File

@@ -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
)
)"#,
)
}