Propertly simulate DWARF information when imports present (#1452)
* Ignore complex LLVM10 expressions. * Propery function name when imports are present
This commit is contained in:
@@ -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(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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([]),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
|
)"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user