Remove the debug crate's hard-coded dependency on register ordering
This commit is contained in:
@@ -64,6 +64,7 @@ use crate::timing;
|
|||||||
use alloc::borrow::Cow;
|
use alloc::borrow::Cow;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
use core::fmt::{Debug, Formatter};
|
||||||
use target_lexicon::{triple, Architecture, PointerWidth, Triple};
|
use target_lexicon::{triple, Architecture, PointerWidth, Triple};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@@ -390,3 +391,14 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
|
|||||||
// No-op by default
|
// No-op by default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for &dyn TargetIsa {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"TargetIsa {{ triple: {:?}, pointer_width: {:?}}}",
|
||||||
|
self.triple(),
|
||||||
|
self.pointer_width()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use faerie::{Artifact, Decl};
|
use faerie::{Artifact, Decl};
|
||||||
use more_asserts::assert_gt;
|
use more_asserts::assert_gt;
|
||||||
use target_lexicon::{BinaryFormat, Triple};
|
use target_lexicon::BinaryFormat;
|
||||||
use wasmtime_environ::isa::TargetFrontendConfig;
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
|
use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
|
||||||
|
|
||||||
pub use crate::read_debuginfo::{read_debuginfo, DebugInfoData, WasmFileInfo};
|
pub use crate::read_debuginfo::{read_debuginfo, DebugInfoData, WasmFileInfo};
|
||||||
@@ -29,13 +29,13 @@ impl SymbolResolver for FunctionRelocResolver {
|
|||||||
pub fn emit_debugsections(
|
pub fn emit_debugsections(
|
||||||
obj: &mut Artifact,
|
obj: &mut Artifact,
|
||||||
vmctx_info: &ModuleVmctxInfo,
|
vmctx_info: &ModuleVmctxInfo,
|
||||||
target_config: TargetFrontendConfig,
|
isa: &dyn TargetIsa,
|
||||||
debuginfo_data: &DebugInfoData,
|
debuginfo_data: &DebugInfoData,
|
||||||
at: &ModuleAddressMap,
|
at: &ModuleAddressMap,
|
||||||
ranges: &ValueLabelsRanges,
|
ranges: &ValueLabelsRanges,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let resolver = FunctionRelocResolver {};
|
let resolver = FunctionRelocResolver {};
|
||||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at, vmctx_info, ranges)?;
|
let dwarf = transform_dwarf(isa, debuginfo_data, at, vmctx_info, ranges)?;
|
||||||
emit_dwarf(obj, dwarf, &resolver)?;
|
emit_dwarf(obj, dwarf, &resolver)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -52,8 +52,7 @@ impl<'a> SymbolResolver for ImageRelocResolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_debugsections_image(
|
pub fn emit_debugsections_image(
|
||||||
triple: Triple,
|
isa: &dyn TargetIsa,
|
||||||
target_config: TargetFrontendConfig,
|
|
||||||
debuginfo_data: &DebugInfoData,
|
debuginfo_data: &DebugInfoData,
|
||||||
vmctx_info: &ModuleVmctxInfo,
|
vmctx_info: &ModuleVmctxInfo,
|
||||||
at: &ModuleAddressMap,
|
at: &ModuleAddressMap,
|
||||||
@@ -64,9 +63,9 @@ pub fn emit_debugsections_image(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(ptr, _)| *ptr as u64)
|
.map(|(ptr, _)| *ptr as u64)
|
||||||
.collect::<Vec<u64>>();
|
.collect::<Vec<u64>>();
|
||||||
let mut obj = Artifact::new(triple, String::from("module"));
|
let mut obj = Artifact::new(isa.triple().clone(), String::from("module"));
|
||||||
let resolver = ImageRelocResolver { func_offsets };
|
let resolver = ImageRelocResolver { func_offsets };
|
||||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at, vmctx_info, ranges)?;
|
let dwarf = transform_dwarf(isa, debuginfo_data, at, vmctx_info, ranges)?;
|
||||||
|
|
||||||
// Assuming all functions in the same code block, looking min/max of its range.
|
// Assuming all functions in the same code block, looking min/max of its range.
|
||||||
assert_gt!(funcs.len(), 0);
|
assert_gt!(funcs.len(), 0);
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ use super::refs::{PendingDebugInfoRefs, PendingUnitRefs};
|
|||||||
use super::{DebugInputContext, Reader, TransformError};
|
use super::{DebugInputContext, Reader, TransformError};
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use gimli::{write, AttributeValue, DebugLineOffset, DebugStr, DebuggingInformationEntry};
|
use gimli::{write, AttributeValue, DebugLineOffset, DebugStr, DebuggingInformationEntry};
|
||||||
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
|
|
||||||
pub(crate) enum FileAttributeContext<'a> {
|
pub(crate) enum FileAttributeContext<'a> {
|
||||||
Root(Option<DebugLineOffset>),
|
Root(Option<DebugLineOffset>),
|
||||||
Children(&'a Vec<write::FileId>, Option<&'a CompiledExpression>),
|
Children(&'a Vec<write::FileId>, Option<&'a CompiledExpression<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_exprloc_to_loclist_allowed(attr_name: gimli::constants::DwAt) -> bool {
|
fn is_exprloc_to_loclist_allowed(attr_name: gimli::constants::DwAt) -> bool {
|
||||||
@@ -41,6 +42,7 @@ pub(crate) fn clone_die_attributes<'a, R>(
|
|||||||
pending_die_refs: &mut PendingUnitRefs,
|
pending_die_refs: &mut PendingUnitRefs,
|
||||||
pending_di_refs: &mut PendingDebugInfoRefs,
|
pending_di_refs: &mut PendingDebugInfoRefs,
|
||||||
file_context: FileAttributeContext<'a>,
|
file_context: FileAttributeContext<'a>,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
R: Reader,
|
R: Reader,
|
||||||
@@ -130,7 +132,9 @@ where
|
|||||||
};
|
};
|
||||||
let mut result = None;
|
let mut result = None;
|
||||||
while let Some(loc) = locs.next()? {
|
while let Some(loc) = locs.next()? {
|
||||||
if let Some(expr) = compile_expression(&loc.data, unit_encoding, frame_base)? {
|
if let Some(expr) =
|
||||||
|
compile_expression(&loc.data, unit_encoding, frame_base, isa)?
|
||||||
|
{
|
||||||
if result.is_none() {
|
if result.is_none() {
|
||||||
result = Some(Vec::new());
|
result = Some(Vec::new());
|
||||||
}
|
}
|
||||||
@@ -168,7 +172,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
if let Some(expr) = compile_expression(expr, unit_encoding, frame_base)? {
|
if let Some(expr) = compile_expression(expr, unit_encoding, frame_base, isa)? {
|
||||||
if expr.is_simple() {
|
if expr.is_simple() {
|
||||||
if let Some(expr) = expr.build() {
|
if let Some(expr) = expr.build() {
|
||||||
write::AttributeValue::Exprloc(expr)
|
write::AttributeValue::Exprloc(expr)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use more_asserts::{assert_le, assert_lt};
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use wasmtime_environ::entity::EntityRef;
|
use wasmtime_environ::entity::EntityRef;
|
||||||
use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
|
use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
|
||||||
use wasmtime_environ::isa::RegUnit;
|
use wasmtime_environ::isa::{RegUnit, TargetIsa};
|
||||||
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
|
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
|
||||||
use wasmtime_environ::ModuleMemoryOffset;
|
use wasmtime_environ::ModuleMemoryOffset;
|
||||||
|
|
||||||
@@ -37,9 +37,10 @@ enum CompiledExpressionPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CompiledExpression {
|
pub struct CompiledExpression<'a> {
|
||||||
parts: Vec<CompiledExpressionPart>,
|
parts: Vec<CompiledExpressionPart>,
|
||||||
need_deref: bool,
|
need_deref: bool,
|
||||||
|
isa: &'a dyn TargetIsa,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for CompiledExpressionPart {
|
impl Clone for CompiledExpressionPart {
|
||||||
@@ -52,77 +53,87 @@ impl Clone for CompiledExpressionPart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompiledExpression {
|
impl<'a> CompiledExpression<'a> {
|
||||||
pub fn vmctx() -> CompiledExpression {
|
pub fn vmctx(isa: &'a dyn TargetIsa) -> CompiledExpression {
|
||||||
CompiledExpression::from_label(get_vmctx_value_label())
|
CompiledExpression::from_label(get_vmctx_value_label(), isa)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_label(label: ValueLabel) -> CompiledExpression {
|
pub fn from_label(label: ValueLabel, isa: &'a dyn TargetIsa) -> CompiledExpression<'a> {
|
||||||
CompiledExpression {
|
CompiledExpression {
|
||||||
parts: vec![
|
parts: vec![
|
||||||
CompiledExpressionPart::Local(label),
|
CompiledExpressionPart::Local(label),
|
||||||
CompiledExpressionPart::Code(vec![gimli::constants::DW_OP_stack_value.0 as u8]),
|
CompiledExpressionPart::Code(vec![gimli::constants::DW_OP_stack_value.0 as u8]),
|
||||||
],
|
],
|
||||||
need_deref: false,
|
need_deref: false,
|
||||||
|
isa,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_reg(reg: RegUnit) -> Register {
|
fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Register {
|
||||||
static mut REG_X86_MAP: Option<HashMap<RegUnit, Register>> = None;
|
// TODO avoid duplication with fde.rs
|
||||||
// FIXME lazy initialization?
|
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
|
||||||
unsafe {
|
// Mapping from https://github.com/bytecodealliance/cranelift/pull/902 by @iximeow
|
||||||
if REG_X86_MAP.is_none() {
|
const X86_GP_REG_MAP: [gimli::Register; 16] = [
|
||||||
REG_X86_MAP = Some(HashMap::new());
|
X86_64::RAX,
|
||||||
|
X86_64::RCX,
|
||||||
|
X86_64::RDX,
|
||||||
|
X86_64::RBX,
|
||||||
|
X86_64::RSP,
|
||||||
|
X86_64::RBP,
|
||||||
|
X86_64::RSI,
|
||||||
|
X86_64::RDI,
|
||||||
|
X86_64::R8,
|
||||||
|
X86_64::R9,
|
||||||
|
X86_64::R10,
|
||||||
|
X86_64::R11,
|
||||||
|
X86_64::R12,
|
||||||
|
X86_64::R13,
|
||||||
|
X86_64::R14,
|
||||||
|
X86_64::R15,
|
||||||
|
];
|
||||||
|
const X86_XMM_REG_MAP: [gimli::Register; 16] = [
|
||||||
|
X86_64::XMM0,
|
||||||
|
X86_64::XMM1,
|
||||||
|
X86_64::XMM2,
|
||||||
|
X86_64::XMM3,
|
||||||
|
X86_64::XMM4,
|
||||||
|
X86_64::XMM5,
|
||||||
|
X86_64::XMM6,
|
||||||
|
X86_64::XMM7,
|
||||||
|
X86_64::XMM8,
|
||||||
|
X86_64::XMM9,
|
||||||
|
X86_64::XMM10,
|
||||||
|
X86_64::XMM11,
|
||||||
|
X86_64::XMM12,
|
||||||
|
X86_64::XMM13,
|
||||||
|
X86_64::XMM14,
|
||||||
|
X86_64::XMM15,
|
||||||
|
];
|
||||||
|
let reg_info = isa.register_info();
|
||||||
|
let bank = reg_info.bank_containing_regunit(reg).unwrap();
|
||||||
|
match bank.name {
|
||||||
|
"IntRegs" => {
|
||||||
|
// x86 GP registers have a weird mapping to DWARF registers, so we use a
|
||||||
|
// lookup table.
|
||||||
|
X86_GP_REG_MAP[(reg - bank.first_unit) as usize]
|
||||||
}
|
}
|
||||||
if let Some(val) = REG_X86_MAP.as_mut().unwrap().get(®) {
|
"FloatRegs" => X86_XMM_REG_MAP[(reg - bank.first_unit) as usize],
|
||||||
return *val;
|
_ => {
|
||||||
|
panic!("unsupported register bank: {}", bank.name);
|
||||||
}
|
}
|
||||||
let result = match reg {
|
|
||||||
0 => X86_64::RAX,
|
|
||||||
1 => X86_64::RCX,
|
|
||||||
2 => X86_64::RDX,
|
|
||||||
3 => X86_64::RBX,
|
|
||||||
4 => X86_64::RSP,
|
|
||||||
5 => X86_64::RBP,
|
|
||||||
6 => X86_64::RSI,
|
|
||||||
7 => X86_64::RDI,
|
|
||||||
8 => X86_64::R8,
|
|
||||||
9 => X86_64::R9,
|
|
||||||
10 => X86_64::R10,
|
|
||||||
11 => X86_64::R11,
|
|
||||||
12 => X86_64::R12,
|
|
||||||
13 => X86_64::R13,
|
|
||||||
14 => X86_64::R14,
|
|
||||||
15 => X86_64::R15,
|
|
||||||
16 => X86_64::XMM0,
|
|
||||||
17 => X86_64::XMM1,
|
|
||||||
18 => X86_64::XMM2,
|
|
||||||
19 => X86_64::XMM3,
|
|
||||||
20 => X86_64::XMM4,
|
|
||||||
21 => X86_64::XMM5,
|
|
||||||
22 => X86_64::XMM6,
|
|
||||||
23 => X86_64::XMM7,
|
|
||||||
24 => X86_64::XMM8,
|
|
||||||
25 => X86_64::XMM9,
|
|
||||||
26 => X86_64::XMM10,
|
|
||||||
27 => X86_64::XMM11,
|
|
||||||
28 => X86_64::XMM12,
|
|
||||||
29 => X86_64::XMM13,
|
|
||||||
30 => X86_64::XMM14,
|
|
||||||
31 => X86_64::XMM15,
|
|
||||||
_ => panic!("unknown x86_64 register {}", reg),
|
|
||||||
};
|
|
||||||
REG_X86_MAP.as_mut().unwrap().insert(reg, result);
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_loc(loc: ValueLoc, frame_info: Option<&FunctionFrameInfo>) -> Option<Vec<u8>> {
|
fn translate_loc(
|
||||||
|
loc: ValueLoc,
|
||||||
|
frame_info: Option<&FunctionFrameInfo>,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
|
) -> Option<Vec<u8>> {
|
||||||
use gimli::write::Writer;
|
use gimli::write::Writer;
|
||||||
match loc {
|
match loc {
|
||||||
ValueLoc::Reg(reg) => {
|
ValueLoc::Reg(reg) => {
|
||||||
let machine_reg = map_reg(reg).0 as u8;
|
let machine_reg = map_reg(isa, reg).0 as u8;
|
||||||
Some(if machine_reg < 32 {
|
Some(if machine_reg < 32 {
|
||||||
vec![gimli::constants::DW_OP_reg0.0 + machine_reg]
|
vec![gimli::constants::DW_OP_reg0.0 + machine_reg]
|
||||||
} else {
|
} else {
|
||||||
@@ -164,13 +175,14 @@ fn append_memory_deref(
|
|||||||
frame_info: &FunctionFrameInfo,
|
frame_info: &FunctionFrameInfo,
|
||||||
vmctx_loc: ValueLoc,
|
vmctx_loc: ValueLoc,
|
||||||
endian: gimli::RunTimeEndian,
|
endian: gimli::RunTimeEndian,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) -> write::Result<bool> {
|
) -> write::Result<bool> {
|
||||||
use gimli::write::Writer;
|
use gimli::write::Writer;
|
||||||
let mut writer = write::EndianVec::new(endian);
|
let mut writer = write::EndianVec::new(endian);
|
||||||
// FIXME for imported memory
|
// FIXME for imported memory
|
||||||
match vmctx_loc {
|
match vmctx_loc {
|
||||||
ValueLoc::Reg(vmctx_reg) => {
|
ValueLoc::Reg(vmctx_reg) => {
|
||||||
let reg = map_reg(vmctx_reg);
|
let reg = map_reg(isa, vmctx_reg);
|
||||||
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?;
|
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?;
|
||||||
let memory_offset = match frame_info.vmctx_memory_offset() {
|
let memory_offset = match frame_info.vmctx_memory_offset() {
|
||||||
Some(offset) => offset,
|
Some(offset) => offset,
|
||||||
@@ -213,7 +225,7 @@ fn append_memory_deref(
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompiledExpression {
|
impl<'a> CompiledExpression<'a> {
|
||||||
pub fn is_simple(&self) -> bool {
|
pub fn is_simple(&self) -> bool {
|
||||||
if let [CompiledExpressionPart::Code(_)] = self.parts.as_slice() {
|
if let [CompiledExpressionPart::Code(_)] = self.parts.as_slice() {
|
||||||
true
|
true
|
||||||
@@ -284,7 +296,7 @@ impl CompiledExpression {
|
|||||||
CompiledExpressionPart::Code(c) => code_buf.extend_from_slice(c.as_slice()),
|
CompiledExpressionPart::Code(c) => code_buf.extend_from_slice(c.as_slice()),
|
||||||
CompiledExpressionPart::Local(label) => {
|
CompiledExpressionPart::Local(label) => {
|
||||||
let loc = *label_location.get(&label).expect("loc");
|
let loc = *label_location.get(&label).expect("loc");
|
||||||
if let Some(expr) = translate_loc(loc, frame_info) {
|
if let Some(expr) = translate_loc(loc, frame_info, self.isa) {
|
||||||
code_buf.extend_from_slice(&expr)
|
code_buf.extend_from_slice(&expr)
|
||||||
} else {
|
} else {
|
||||||
continue 'range;
|
continue 'range;
|
||||||
@@ -294,7 +306,13 @@ impl CompiledExpression {
|
|||||||
if let (Some(vmctx_loc), Some(frame_info)) =
|
if let (Some(vmctx_loc), Some(frame_info)) =
|
||||||
(label_location.get(&vmctx_label), frame_info)
|
(label_location.get(&vmctx_label), frame_info)
|
||||||
{
|
{
|
||||||
if !append_memory_deref(&mut code_buf, frame_info, *vmctx_loc, endian)
|
if !append_memory_deref(
|
||||||
|
&mut code_buf,
|
||||||
|
frame_info,
|
||||||
|
*vmctx_loc,
|
||||||
|
endian,
|
||||||
|
self.isa,
|
||||||
|
)
|
||||||
.expect("append_memory_deref")
|
.expect("append_memory_deref")
|
||||||
{
|
{
|
||||||
continue 'range;
|
continue 'range;
|
||||||
@@ -309,7 +327,7 @@ impl CompiledExpression {
|
|||||||
if let (Some(vmctx_loc), Some(frame_info)) =
|
if let (Some(vmctx_loc), Some(frame_info)) =
|
||||||
(label_location.get(&vmctx_label), frame_info)
|
(label_location.get(&vmctx_label), frame_info)
|
||||||
{
|
{
|
||||||
if !append_memory_deref(&mut code_buf, frame_info, *vmctx_loc, endian)
|
if !append_memory_deref(&mut code_buf, frame_info, *vmctx_loc, endian, self.isa)
|
||||||
.expect("append_memory_deref")
|
.expect("append_memory_deref")
|
||||||
{
|
{
|
||||||
continue 'range;
|
continue 'range;
|
||||||
@@ -342,11 +360,12 @@ fn is_old_expression_format(buf: &[u8]) -> bool {
|
|||||||
buf.contains(&(gimli::constants::DW_OP_plus_uconst.0 as u8))
|
buf.contains(&(gimli::constants::DW_OP_plus_uconst.0 as u8))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_expression<R>(
|
pub fn compile_expression<'a, R>(
|
||||||
expr: &Expression<R>,
|
expr: &Expression<R>,
|
||||||
encoding: gimli::Encoding,
|
encoding: gimli::Encoding,
|
||||||
frame_base: Option<&CompiledExpression>,
|
frame_base: Option<&CompiledExpression>,
|
||||||
) -> Result<Option<CompiledExpression>, Error>
|
isa: &'a dyn TargetIsa,
|
||||||
|
) -> Result<Option<CompiledExpression<'a>>, Error>
|
||||||
where
|
where
|
||||||
R: Reader,
|
R: Reader,
|
||||||
{
|
{
|
||||||
@@ -437,7 +456,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(CompiledExpression { parts, need_deref }))
|
Ok(Some(CompiledExpression {
|
||||||
|
parts,
|
||||||
|
need_deref,
|
||||||
|
isa,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use gimli::{
|
|||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wasmtime_environ::isa::TargetFrontendConfig;
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
|
use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
|
||||||
|
|
||||||
pub use address_transform::AddressTransform;
|
pub use address_transform::AddressTransform;
|
||||||
@@ -47,7 +47,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_dwarf(
|
pub fn transform_dwarf(
|
||||||
target_config: TargetFrontendConfig,
|
isa: &dyn TargetIsa,
|
||||||
di: &DebugInfoData,
|
di: &DebugInfoData,
|
||||||
at: &ModuleAddressMap,
|
at: &ModuleAddressMap,
|
||||||
vmctx_info: &ModuleVmctxInfo,
|
vmctx_info: &ModuleVmctxInfo,
|
||||||
@@ -71,7 +71,7 @@ pub fn transform_dwarf(
|
|||||||
// TODO: this should be configurable
|
// TODO: this should be configurable
|
||||||
// macOS doesn't seem to support DWARF > 3
|
// macOS doesn't seem to support DWARF > 3
|
||||||
version: 3,
|
version: 3,
|
||||||
address_size: target_config.pointer_bytes(),
|
address_size: isa.pointer_bytes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut out_strings = write::StringTable::default();
|
let mut out_strings = write::StringTable::default();
|
||||||
@@ -95,6 +95,7 @@ pub fn transform_dwarf(
|
|||||||
&mut out_units,
|
&mut out_units,
|
||||||
&mut out_strings,
|
&mut out_strings,
|
||||||
&mut translated,
|
&mut translated,
|
||||||
|
isa,
|
||||||
)? {
|
)? {
|
||||||
di_ref_map.insert(&header, id, ref_map);
|
di_ref_map.insert(&header, id, ref_map);
|
||||||
pending_di_refs.push((id, pending_refs));
|
pending_di_refs.push((id, pending_refs));
|
||||||
@@ -111,6 +112,7 @@ pub fn transform_dwarf(
|
|||||||
out_encoding,
|
out_encoding,
|
||||||
&mut out_units,
|
&mut out_units,
|
||||||
&mut out_strings,
|
&mut out_strings,
|
||||||
|
isa,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(write::Dwarf {
|
Ok(write::Dwarf {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use wasmtime_environ::wasm::get_vmctx_value_label;
|
|||||||
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};
|
||||||
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
|
|
||||||
const PRODUCER_NAME: &str = "wasmtime";
|
const PRODUCER_NAME: &str = "wasmtime";
|
||||||
|
|
||||||
@@ -175,6 +176,7 @@ fn generate_vars(
|
|||||||
func_meta: &FunctionMetadata,
|
func_meta: &FunctionMetadata,
|
||||||
locals_names: Option<&HashMap<u32, String>>,
|
locals_names: Option<&HashMap<u32, String>>,
|
||||||
out_strings: &mut write::StringTable,
|
out_strings: &mut write::StringTable,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let vmctx_label = get_vmctx_value_label();
|
let vmctx_label = get_vmctx_value_label();
|
||||||
|
|
||||||
@@ -192,6 +194,7 @@ fn generate_vars(
|
|||||||
Some(frame_info),
|
Some(frame_info),
|
||||||
scope_ranges,
|
scope_ranges,
|
||||||
out_strings,
|
out_strings,
|
||||||
|
isa,
|
||||||
)
|
)
|
||||||
.expect("append_vmctx_info success");
|
.expect("append_vmctx_info success");
|
||||||
} else {
|
} else {
|
||||||
@@ -207,7 +210,7 @@ fn generate_vars(
|
|||||||
let loc_list_id = {
|
let loc_list_id = {
|
||||||
let endian = gimli::RunTimeEndian::Little;
|
let endian = gimli::RunTimeEndian::Little;
|
||||||
|
|
||||||
let expr = CompiledExpression::from_label(*label);
|
let expr = CompiledExpression::from_label(*label, isa);
|
||||||
let mut locs = Vec::new();
|
let mut locs = Vec::new();
|
||||||
for (begin, length, data) in
|
for (begin, length, data) in
|
||||||
expr.build_with_locals(scope_ranges, addr_tr, Some(frame_info), endian)
|
expr.build_with_locals(scope_ranges, addr_tr, Some(frame_info), endian)
|
||||||
@@ -258,6 +261,7 @@ pub fn generate_simulated_dwarf(
|
|||||||
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,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let path = di
|
let path = di
|
||||||
.wasm_file
|
.wasm_file
|
||||||
@@ -365,6 +369,7 @@ pub fn generate_simulated_dwarf(
|
|||||||
&di.wasm_file.funcs[index],
|
&di.wasm_file.funcs[index],
|
||||||
locals_names.and_then(|m| m.get(&(index as u32))),
|
locals_names.and_then(|m| m.get(&(index as u32))),
|
||||||
out_strings,
|
out_strings,
|
||||||
|
isa,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ 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::entity::EntityRef;
|
||||||
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges};
|
use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges};
|
||||||
|
|
||||||
struct InheritedAttr<T> {
|
struct InheritedAttr<T> {
|
||||||
@@ -148,6 +149,7 @@ pub(crate) fn clone_unit<'a, R>(
|
|||||||
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<u32>,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) -> Result<Option<(write::UnitId, UnitRefsMap, PendingDebugInfoRefs)>, Error>
|
) -> Result<Option<(write::UnitId, UnitRefsMap, PendingDebugInfoRefs)>, Error>
|
||||||
where
|
where
|
||||||
R: Reader,
|
R: Reader,
|
||||||
@@ -203,6 +205,7 @@ where
|
|||||||
&mut pending_die_refs,
|
&mut pending_die_refs,
|
||||||
&mut pending_di_refs,
|
&mut pending_di_refs,
|
||||||
FileAttributeContext::Root(Some(debug_line_offset)),
|
FileAttributeContext::Root(Some(debug_line_offset)),
|
||||||
|
isa,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (wp_die_id, vmctx_die_id) =
|
let (wp_die_id, vmctx_die_id) =
|
||||||
@@ -296,7 +299,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(AttributeValue::Exprloc(expr)) = entry.attr_value(gimli::DW_AT_frame_base)? {
|
if let Some(AttributeValue::Exprloc(expr)) = entry.attr_value(gimli::DW_AT_frame_base)? {
|
||||||
if let Some(expr) = compile_expression(&expr, unit.encoding(), None)? {
|
if let Some(expr) = compile_expression(&expr, unit.encoding(), None, isa)? {
|
||||||
current_frame_base.push(new_stack_len, expr);
|
current_frame_base.push(new_stack_len, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,6 +346,7 @@ where
|
|||||||
&mut pending_die_refs,
|
&mut pending_die_refs,
|
||||||
&mut pending_di_refs,
|
&mut pending_di_refs,
|
||||||
FileAttributeContext::Children(&file_map, current_frame_base.top()),
|
FileAttributeContext::Children(&file_map, current_frame_base.top()),
|
||||||
|
isa,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if entry.tag() == gimli::DW_TAG_subprogram && !current_scope_ranges.is_empty() {
|
if entry.tag() == gimli::DW_TAG_subprogram && !current_scope_ranges.is_empty() {
|
||||||
@@ -354,6 +358,7 @@ where
|
|||||||
current_value_range.top(),
|
current_value_range.top(),
|
||||||
current_scope_ranges.top().expect("range"),
|
current_scope_ranges.top().expect("range"),
|
||||||
out_strings,
|
out_strings,
|
||||||
|
isa,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use super::address_transform::AddressTransform;
|
|||||||
use super::expression::{CompiledExpression, FunctionFrameInfo};
|
use super::expression::{CompiledExpression, FunctionFrameInfo};
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use gimli::write;
|
use gimli::write;
|
||||||
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||||
use wasmtime_environ::{ModuleMemoryOffset, ModuleVmctxInfo, ValueLabelsRanges};
|
use wasmtime_environ::{ModuleMemoryOffset, ModuleVmctxInfo, ValueLabelsRanges};
|
||||||
|
|
||||||
@@ -109,11 +110,12 @@ pub(crate) fn append_vmctx_info(
|
|||||||
frame_info: Option<&FunctionFrameInfo>,
|
frame_info: Option<&FunctionFrameInfo>,
|
||||||
scope_ranges: &[(u64, u64)],
|
scope_ranges: &[(u64, u64)],
|
||||||
out_strings: &mut write::StringTable,
|
out_strings: &mut write::StringTable,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let loc = {
|
let loc = {
|
||||||
let endian = gimli::RunTimeEndian::Little;
|
let endian = gimli::RunTimeEndian::Little;
|
||||||
|
|
||||||
let expr = CompiledExpression::vmctx();
|
let expr = CompiledExpression::vmctx(isa);
|
||||||
let mut locs = Vec::new();
|
let mut locs = Vec::new();
|
||||||
for (begin, length, data) in
|
for (begin, length, data) in
|
||||||
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian)
|
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian)
|
||||||
|
|||||||
@@ -174,8 +174,7 @@ impl Compiler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let bytes = emit_debugsections_image(
|
let bytes = emit_debugsections_image(
|
||||||
self.isa.triple().clone(),
|
&*self.isa,
|
||||||
target_config,
|
|
||||||
debug_data.as_ref().unwrap(),
|
debug_data.as_ref().unwrap(),
|
||||||
&module_vmctx_info,
|
&module_vmctx_info,
|
||||||
&address_transform,
|
&address_transform,
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ pub fn compile_to_obj(
|
|||||||
emit_debugsections(
|
emit_debugsections(
|
||||||
&mut obj,
|
&mut obj,
|
||||||
&module_vmctx_info,
|
&module_vmctx_info,
|
||||||
target_config,
|
&*isa,
|
||||||
&debug_data,
|
&debug_data,
|
||||||
&address_transform,
|
&address_transform,
|
||||||
&value_ranges,
|
&value_ranges,
|
||||||
|
|||||||
Reference in New Issue
Block a user