Merge pull request #2565 from cfallin/debug-value-labels

Detailed debug-info (DWARF) support in new backends (initially x64).
This commit is contained in:
Chris Fallin
2021-01-22 17:22:13 -08:00
committed by GitHub
23 changed files with 958 additions and 94 deletions

View File

@@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
use wasmtime_environ::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
use wasmtime_environ::isa::TargetIsa;
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
use wasmtime_environ::ModuleMemoryOffset;
@@ -131,27 +131,24 @@ impl CompiledExpression {
const X86_64_STACK_OFFSET: i64 = 16;
fn translate_loc(
loc: ValueLoc,
loc: LabelValueLoc,
frame_info: Option<&FunctionFrameInfo>,
isa: &dyn TargetIsa,
add_stack_value: bool,
) -> Result<Option<Vec<u8>>> {
Ok(match loc {
ValueLoc::Reg(reg) if add_stack_value => {
LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => {
let machine_reg = isa.map_dwarf_register(reg)?;
let mut writer = ExpressionWriter::new();
writer.write_op_reg(machine_reg)?;
if add_stack_value {
writer.write_op_reg(machine_reg)?;
} else {
writer.write_op_breg(machine_reg)?;
writer.write_sleb128(0)?;
}
Some(writer.into_vec())
}
ValueLoc::Reg(reg) => {
assert!(!add_stack_value);
let machine_reg = isa.map_dwarf_register(reg)?;
let mut writer = ExpressionWriter::new();
writer.write_op_breg(machine_reg)?;
writer.write_sleb128(0)?;
Some(writer.into_vec())
}
ValueLoc::Stack(ss) => {
LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
if let Some(frame_info) = frame_info {
if let Some(ss_offset) = frame_info.stack_slots[ss].offset {
let mut writer = ExpressionWriter::new();
@@ -165,6 +162,27 @@ fn translate_loc(
}
None
}
LabelValueLoc::Reg(r) => {
let machine_reg = isa.map_regalloc_reg_to_dwarf(r)?;
let mut writer = ExpressionWriter::new();
if add_stack_value {
writer.write_op_reg(machine_reg)?;
} else {
writer.write_op_breg(machine_reg)?;
writer.write_sleb128(0)?;
}
Some(writer.into_vec())
}
LabelValueLoc::SPOffset(off) => {
let mut writer = ExpressionWriter::new();
writer.write_op_breg(X86_64::RSP.0)?;
writer.write_sleb128(off)?;
if !add_stack_value {
writer.write_op(gimli::constants::DW_OP_deref)?;
}
return Ok(Some(writer.into_vec()));
}
_ => None,
})
}
@@ -172,13 +190,13 @@ fn translate_loc(
fn append_memory_deref(
buf: &mut Vec<u8>,
frame_info: &FunctionFrameInfo,
vmctx_loc: ValueLoc,
vmctx_loc: LabelValueLoc,
isa: &dyn TargetIsa,
) -> Result<bool> {
let mut writer = ExpressionWriter::new();
// FIXME for imported memory
match vmctx_loc {
ValueLoc::Reg(vmctx_reg) => {
LabelValueLoc::ValueLoc(ValueLoc::Reg(vmctx_reg)) => {
let reg = isa.map_dwarf_register(vmctx_reg)? as u8;
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg)?;
let memory_offset = match frame_info.vmctx_memory_offset() {
@@ -189,7 +207,7 @@ fn append_memory_deref(
};
writer.write_sleb128(memory_offset)?;
}
ValueLoc::Stack(ss) => {
LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
if let Some(ss_offset) = frame_info.stack_slots[ss].offset {
writer.write_op_breg(X86_64::RBP.0)?;
writer.write_sleb128(ss_offset as i64 + X86_64_STACK_OFFSET)?;
@@ -207,6 +225,31 @@ fn append_memory_deref(
return Ok(false);
}
}
LabelValueLoc::Reg(r) => {
let reg = isa.map_regalloc_reg_to_dwarf(r)?;
writer.write_op_breg(reg)?;
let memory_offset = match frame_info.vmctx_memory_offset() {
Some(offset) => offset,
None => {
return Ok(false);
}
};
writer.write_sleb128(memory_offset)?;
}
LabelValueLoc::SPOffset(off) => {
writer.write_op_breg(X86_64::RSP.0)?;
writer.write_sleb128(off)?;
writer.write_op(gimli::constants::DW_OP_deref)?;
writer.write_op(gimli::constants::DW_OP_consts)?;
let memory_offset = match frame_info.vmctx_memory_offset() {
Some(offset) => offset,
None => {
return Ok(false);
}
};
writer.write_sleb128(memory_offset)?;
writer.write_op(gimli::constants::DW_OP_plus)?;
}
_ => {
return Ok(false);
}
@@ -468,7 +511,7 @@ where
let _ = code_chunk; // suppresses warning for final flush
}
};
};
}
// Find all landing pads by scanning bytes, do not care about
// false location at this moment.
// Looks hacky but it is fast; does not need to be really exact.
@@ -653,7 +696,7 @@ struct CachedValueLabelRange {
func_index: DefinedFuncIndex,
start: usize,
end: usize,
label_location: HashMap<ValueLabel, ValueLoc>,
label_location: HashMap<ValueLabel, LabelValueLoc>,
}
struct ValueLabelRangesBuilder<'a, 'b> {
@@ -1179,7 +1222,7 @@ mod tests {
fn create_mock_value_ranges() -> (ValueLabelsRanges, (ValueLabel, ValueLabel, ValueLabel)) {
use std::collections::HashMap;
use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::ir::{ValueLoc, ValueLocRange};
use wasmtime_environ::ir::{LabelValueLoc, ValueLoc, ValueLocRange};
let mut value_ranges = HashMap::new();
let value_0 = ValueLabel::new(0);
let value_1 = ValueLabel::new(1);
@@ -1187,7 +1230,7 @@ mod tests {
value_ranges.insert(
value_0,
vec![ValueLocRange {
loc: ValueLoc::Unassigned,
loc: LabelValueLoc::ValueLoc(ValueLoc::Unassigned),
start: 0,
end: 25,
}],
@@ -1195,7 +1238,7 @@ mod tests {
value_ranges.insert(
value_1,
vec![ValueLocRange {
loc: ValueLoc::Unassigned,
loc: LabelValueLoc::ValueLoc(ValueLoc::Unassigned),
start: 5,
end: 30,
}],
@@ -1204,12 +1247,12 @@ mod tests {
value_2,
vec![
ValueLocRange {
loc: ValueLoc::Unassigned,
loc: LabelValueLoc::ValueLoc(ValueLoc::Unassigned),
start: 0,
end: 10,
},
ValueLocRange {
loc: ValueLoc::Unassigned,
loc: LabelValueLoc::ValueLoc(ValueLoc::Unassigned),
start: 20,
end: 30,
},

View File

@@ -3,8 +3,8 @@
pub mod ir {
pub use cranelift_codegen::binemit::{Reloc, StackMap};
pub use cranelift_codegen::ir::{
types, AbiParam, ArgumentPurpose, JumpTableOffsets, LibCall, Signature, SourceLoc,
StackSlots, TrapCode, Type, ValueLabel, ValueLoc,
types, AbiParam, ArgumentPurpose, JumpTableOffsets, LabelValueLoc, LibCall, Signature,
SourceLoc, StackSlots, TrapCode, Type, ValueLabel, ValueLoc,
};
pub use cranelift_codegen::{ValueLabelsRanges, ValueLocRange};
}