diff --git a/cranelift/codegen/src/isa/fde.rs b/cranelift/codegen/src/isa/fde.rs new file mode 100644 index 0000000000..acb7a01d43 --- /dev/null +++ b/cranelift/codegen/src/isa/fde.rs @@ -0,0 +1,14 @@ +//! Support for FDE data generation. +use thiserror::Error; + +/// Enumerate the errors possible in mapping Cranelift registers to their DWARF equivalent. +#[allow(missing_docs)] +#[derive(Error, Debug)] +pub enum RegisterMappingError { + #[error("unable to find bank for register info")] + MissingBank, + #[error("register mapping is currently only implemented for x86_64")] + UnsupportedArchitecture, + #[error("unsupported register bank: {0}")] + UnsupportedRegisterBank(&'static str), +} diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index f6cf9148d9..9c91d42193 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -56,6 +56,8 @@ use crate::binemit; use crate::flowgraph; use crate::ir; use crate::isa::enc_tables::Encodings; +#[cfg(feature = "unwind")] +use crate::isa::fde::RegisterMappingError; use crate::regalloc; use crate::result::CodegenResult; use crate::settings; @@ -74,11 +76,8 @@ mod riscv; #[cfg(feature = "x86")] mod x86; -#[cfg(all(feature = "x86", feature = "unwind"))] -/// Expose the register-mapping functionality necessary for exception handling, debug, etc. -pub mod fde { - pub use super::x86::map_reg; -} +#[cfg(feature = "unwind")] +pub mod fde; #[cfg(feature = "arm32")] mod arm32; @@ -260,6 +259,12 @@ pub trait TargetIsa: fmt::Display + Send + Sync { /// Get a data structure describing the registers in this ISA. fn register_info(&self) -> RegInfo; + #[cfg(feature = "unwind")] + /// Map a Cranelift register to its corresponding DWARF register. + fn map_dwarf_register(&self, _: RegUnit) -> Result { + Err(RegisterMappingError::UnsupportedArchitecture) + } + /// Returns an iterator over legal encodings for the instruction. fn legal_encodings<'a>( &'a self, diff --git a/cranelift/codegen/src/isa/x86/fde.rs b/cranelift/codegen/src/isa/x86/fde.rs index 17dee88cb3..9d6e38de31 100644 --- a/cranelift/codegen/src/isa/x86/fde.rs +++ b/cranelift/codegen/src/isa/x86/fde.rs @@ -2,6 +2,7 @@ use crate::binemit::{FrameUnwindOffset, FrameUnwindSink, Reloc}; use crate::ir::{FrameLayoutChange, Function}; +use crate::isa::fde::RegisterMappingError; use crate::isa::{CallConv, RegUnit, TargetIsa}; use alloc::vec::Vec; use core::convert::TryInto; @@ -10,7 +11,6 @@ use gimli::write::{ FrameDescriptionEntry, FrameTable, Result, Writer, }; use gimli::{Encoding, Format, LittleEndian, Register, X86_64}; -use thiserror::Error; pub type FDERelocEntry = (FrameUnwindOffset, Reloc); @@ -137,16 +137,6 @@ pub fn map_reg( } } -#[derive(Error, Debug)] -pub enum RegisterMappingError { - #[error("unable to find bank for register info")] - MissingBank, - #[error("register mapping is currently only implemented for x86_64")] - UnsupportedArchitecture, - #[error("unsupported register bank: {0}")] - UnsupportedRegisterBank(&'static str), -} - fn to_cfi( isa: &dyn TargetIsa, change: &FrameLayoutChange, diff --git a/cranelift/codegen/src/isa/x86/mod.rs b/cranelift/codegen/src/isa/x86/mod.rs index f7c49cd21b..042874ea69 100644 --- a/cranelift/codegen/src/isa/x86/mod.rs +++ b/cranelift/codegen/src/isa/x86/mod.rs @@ -22,6 +22,8 @@ use crate::binemit::{FrameUnwindKind, FrameUnwindSink}; use crate::ir; use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings}; use crate::isa::Builder as IsaBuilder; +#[cfg(feature = "unwind")] +use crate::isa::{fde::RegisterMappingError, RegUnit}; use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa}; use crate::regalloc; use crate::result::CodegenResult; @@ -91,6 +93,11 @@ impl TargetIsa for Isa { registers::INFO.clone() } + #[cfg(feature = "unwind")] + fn map_dwarf_register(&self, reg: RegUnit) -> Result { + map_reg(self, reg).map(|r| r.0) + } + fn encoding_info(&self) -> EncInfo { enc_tables::INFO.clone() } diff --git a/crates/debug/src/frame.rs b/crates/debug/src/frame.rs index 566dc6d1a7..ab5b60de84 100644 --- a/crates/debug/src/frame.rs +++ b/crates/debug/src/frame.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; use wasmtime_environ::entity::EntityRef; -use wasmtime_environ::isa::fde::map_reg; use wasmtime_environ::isa::{CallConv, TargetIsa}; use wasmtime_environ::wasm::DefinedFuncIndex; use wasmtime_environ::{FrameLayoutChange, FrameLayouts}; @@ -19,8 +18,8 @@ fn to_cfi( ) -> Option { Some(match change { FrameLayoutChange::CallFrameAddressAt { reg, offset } => { - let mapped = match map_reg(isa, *reg) { - Ok(r) => r, + let mapped = match isa.map_dwarf_register(*reg) { + Ok(r) => Register(r), Err(_) => return None, }; let offset = (*offset) as i32; @@ -41,8 +40,8 @@ fn to_cfi( FrameLayoutChange::RegAt { reg, cfa_offset } => { assert!(cfa_offset % -8 == 0); let cfa_offset = *cfa_offset as i32; - let mapped = match map_reg(isa, *reg) { - Ok(r) => r, + let mapped = match isa.map_dwarf_register(*reg) { + Ok(r) => Register(r), Err(_) => return None, }; CallFrameInstruction::Offset(mapped, cfa_offset) diff --git a/crates/debug/src/transform/expression.rs b/crates/debug/src/transform/expression.rs index f901b03575..81394f8371 100644 --- a/crates/debug/src/transform/expression.rs +++ b/crates/debug/src/transform/expression.rs @@ -5,7 +5,6 @@ use more_asserts::{assert_le, assert_lt}; use std::collections::{HashMap, HashSet}; use wasmtime_environ::entity::EntityRef; use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc}; -use wasmtime_environ::isa::fde::map_reg; use wasmtime_environ::isa::TargetIsa; use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex}; use wasmtime_environ::ModuleMemoryOffset; @@ -79,7 +78,7 @@ fn translate_loc( use gimli::write::Writer; Ok(match loc { ValueLoc::Reg(reg) => { - let machine_reg = map_reg(isa, reg)?.0 as u8; + let machine_reg = isa.map_dwarf_register(reg)? as u8; Some(if machine_reg < 32 { vec![gimli::constants::DW_OP_reg0.0 + machine_reg] } else { @@ -120,8 +119,8 @@ fn append_memory_deref( // FIXME for imported memory match vmctx_loc { ValueLoc::Reg(vmctx_reg) => { - let reg = map_reg(isa, vmctx_reg)?; - writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?; + 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() { Some(offset) => offset, None => { diff --git a/crates/environ/src/data_structures.rs b/crates/environ/src/data_structures.rs index 59e5d60410..08bb5b6453 100755 --- a/crates/environ/src/data_structures.rs +++ b/crates/environ/src/data_structures.rs @@ -14,9 +14,6 @@ pub mod settings { pub mod isa { pub use cranelift_codegen::isa::{CallConv, RegUnit, TargetFrontendConfig, TargetIsa}; - pub mod fde { - pub use cranelift_codegen::isa::fde::map_reg; - } } pub mod entity {