Browse Source

Add TargetIsa::map_dwarf_register; fixes #1471

This exposes the functionality of `fde::map_reg` on the `TargetIsa` trait, avoiding compilation errors on architectures where register mapping is not yet supported. The change is conditially compiled under the `unwind` feature.
pull/1492/head
Andrew Brown 5 years ago
parent
commit
6fd0451bc3
  1. 14
      cranelift/codegen/src/isa/fde.rs
  2. 15
      cranelift/codegen/src/isa/mod.rs
  3. 12
      cranelift/codegen/src/isa/x86/fde.rs
  4. 7
      cranelift/codegen/src/isa/x86/mod.rs
  5. 9
      crates/debug/src/frame.rs
  6. 7
      crates/debug/src/transform/expression.rs
  7. 3
      crates/environ/src/data_structures.rs

14
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),
}

15
cranelift/codegen/src/isa/mod.rs

@ -56,6 +56,8 @@ use crate::binemit;
use crate::flowgraph; use crate::flowgraph;
use crate::ir; use crate::ir;
use crate::isa::enc_tables::Encodings; use crate::isa::enc_tables::Encodings;
#[cfg(feature = "unwind")]
use crate::isa::fde::RegisterMappingError;
use crate::regalloc; use crate::regalloc;
use crate::result::CodegenResult; use crate::result::CodegenResult;
use crate::settings; use crate::settings;
@ -74,11 +76,8 @@ mod riscv;
#[cfg(feature = "x86")] #[cfg(feature = "x86")]
mod x86; mod x86;
#[cfg(all(feature = "x86", feature = "unwind"))] #[cfg(feature = "unwind")]
/// Expose the register-mapping functionality necessary for exception handling, debug, etc. pub mod fde;
pub mod fde {
pub use super::x86::map_reg;
}
#[cfg(feature = "arm32")] #[cfg(feature = "arm32")]
mod arm32; mod arm32;
@ -260,6 +259,12 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
/// Get a data structure describing the registers in this ISA. /// Get a data structure describing the registers in this ISA.
fn register_info(&self) -> RegInfo; fn register_info(&self) -> RegInfo;
#[cfg(feature = "unwind")]
/// Map a Cranelift register to its corresponding DWARF register.
fn map_dwarf_register(&self, _: RegUnit) -> Result<u16, RegisterMappingError> {
Err(RegisterMappingError::UnsupportedArchitecture)
}
/// Returns an iterator over legal encodings for the instruction. /// Returns an iterator over legal encodings for the instruction.
fn legal_encodings<'a>( fn legal_encodings<'a>(
&'a self, &'a self,

12
cranelift/codegen/src/isa/x86/fde.rs

@ -2,6 +2,7 @@
use crate::binemit::{FrameUnwindOffset, FrameUnwindSink, Reloc}; use crate::binemit::{FrameUnwindOffset, FrameUnwindSink, Reloc};
use crate::ir::{FrameLayoutChange, Function}; use crate::ir::{FrameLayoutChange, Function};
use crate::isa::fde::RegisterMappingError;
use crate::isa::{CallConv, RegUnit, TargetIsa}; use crate::isa::{CallConv, RegUnit, TargetIsa};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::convert::TryInto; use core::convert::TryInto;
@ -10,7 +11,6 @@ use gimli::write::{
FrameDescriptionEntry, FrameTable, Result, Writer, FrameDescriptionEntry, FrameTable, Result, Writer,
}; };
use gimli::{Encoding, Format, LittleEndian, Register, X86_64}; use gimli::{Encoding, Format, LittleEndian, Register, X86_64};
use thiserror::Error;
pub type FDERelocEntry = (FrameUnwindOffset, Reloc); 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( fn to_cfi(
isa: &dyn TargetIsa, isa: &dyn TargetIsa,
change: &FrameLayoutChange, change: &FrameLayoutChange,

7
cranelift/codegen/src/isa/x86/mod.rs

@ -22,6 +22,8 @@ use crate::binemit::{FrameUnwindKind, FrameUnwindSink};
use crate::ir; use crate::ir;
use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings}; use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
use crate::isa::Builder as IsaBuilder; use crate::isa::Builder as IsaBuilder;
#[cfg(feature = "unwind")]
use crate::isa::{fde::RegisterMappingError, RegUnit};
use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa}; use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa};
use crate::regalloc; use crate::regalloc;
use crate::result::CodegenResult; use crate::result::CodegenResult;
@ -91,6 +93,11 @@ impl TargetIsa for Isa {
registers::INFO.clone() registers::INFO.clone()
} }
#[cfg(feature = "unwind")]
fn map_dwarf_register(&self, reg: RegUnit) -> Result<u16, RegisterMappingError> {
map_reg(self, reg).map(|r| r.0)
}
fn encoding_info(&self) -> EncInfo { fn encoding_info(&self) -> EncInfo {
enc_tables::INFO.clone() enc_tables::INFO.clone()
} }

9
crates/debug/src/frame.rs

@ -1,6 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use wasmtime_environ::entity::EntityRef; use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::isa::fde::map_reg;
use wasmtime_environ::isa::{CallConv, TargetIsa}; use wasmtime_environ::isa::{CallConv, TargetIsa};
use wasmtime_environ::wasm::DefinedFuncIndex; use wasmtime_environ::wasm::DefinedFuncIndex;
use wasmtime_environ::{FrameLayoutChange, FrameLayouts}; use wasmtime_environ::{FrameLayoutChange, FrameLayouts};
@ -19,8 +18,8 @@ fn to_cfi(
) -> Option<CallFrameInstruction> { ) -> Option<CallFrameInstruction> {
Some(match change { Some(match change {
FrameLayoutChange::CallFrameAddressAt { reg, offset } => { FrameLayoutChange::CallFrameAddressAt { reg, offset } => {
let mapped = match map_reg(isa, *reg) { let mapped = match isa.map_dwarf_register(*reg) {
Ok(r) => r, Ok(r) => Register(r),
Err(_) => return None, Err(_) => return None,
}; };
let offset = (*offset) as i32; let offset = (*offset) as i32;
@ -41,8 +40,8 @@ fn to_cfi(
FrameLayoutChange::RegAt { reg, cfa_offset } => { FrameLayoutChange::RegAt { reg, cfa_offset } => {
assert!(cfa_offset % -8 == 0); assert!(cfa_offset % -8 == 0);
let cfa_offset = *cfa_offset as i32; let cfa_offset = *cfa_offset as i32;
let mapped = match map_reg(isa, *reg) { let mapped = match isa.map_dwarf_register(*reg) {
Ok(r) => r, Ok(r) => Register(r),
Err(_) => return None, Err(_) => return None,
}; };
CallFrameInstruction::Offset(mapped, cfa_offset) CallFrameInstruction::Offset(mapped, cfa_offset)

7
crates/debug/src/transform/expression.rs

@ -5,7 +5,6 @@ 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::fde::map_reg;
use wasmtime_environ::isa::TargetIsa; use wasmtime_environ::isa::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;
@ -79,7 +78,7 @@ fn translate_loc(
use gimli::write::Writer; use gimli::write::Writer;
Ok(match loc { Ok(match loc {
ValueLoc::Reg(reg) => { 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 { 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 {
@ -120,8 +119,8 @@ fn append_memory_deref(
// 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(isa, vmctx_reg)?; let reg = isa.map_dwarf_register(vmctx_reg)? as u8;
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?; writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg)?;
let memory_offset = match frame_info.vmctx_memory_offset() { let memory_offset = match frame_info.vmctx_memory_offset() {
Some(offset) => offset, Some(offset) => offset,
None => { None => {

3
crates/environ/src/data_structures.rs

@ -14,9 +14,6 @@ pub mod settings {
pub mod isa { pub mod isa {
pub use cranelift_codegen::isa::{CallConv, RegUnit, TargetFrontendConfig, TargetIsa}; pub use cranelift_codegen::isa::{CallConv, RegUnit, TargetFrontendConfig, TargetIsa};
pub mod fde {
pub use cranelift_codegen::isa::fde::map_reg;
}
} }
pub mod entity { pub mod entity {

Loading…
Cancel
Save