Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various cleanups for the singlepass backend on AArch64. #1068

Merged
merged 6 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [#1009](https://github.com/wasmerio/wasmer/pull/1009) Enable LLVM verifier for all tests, add new llvm-backend-tests crate.
- [#1022](https://github.com/wasmerio/wasmer/pull/1022) Add caching support for Singlepass backend.
- [#1004](https://github.com/wasmerio/wasmer/pull/1004) Add the Auto backend to enable to adapt backend usage depending on wasm file executed.
- [#1068](https://github.com/wasmerio/wasmer/pull/1068) Various cleanups for the singlepass backend on AArch64.

## 0.11.0 - 2019-11-22

Expand Down
67 changes: 48 additions & 19 deletions lib/runtime-core/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,34 +76,55 @@ impl std::str::FromStr for Backend {
}
}

/// The target architecture for code generation.
#[derive(Copy, Clone, Debug)]
pub enum Architecture {
/// x86-64.
X64,

/// Aarch64 (ARM64).
Aarch64,
}

/// The type of an inline breakpoint.
#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum InlineBreakpointType {
Trace,
/// A middleware invocation breakpoint.
Middleware,
Unknown,
}

/// Information of an inline breakpoint.
#[derive(Clone, Debug)]
pub struct InlineBreakpoint {
/// Size in bytes taken by this breakpoint's instruction sequence.
pub size: usize,

/// Type of the inline breakpoint.
pub ty: InlineBreakpointType,
}

/// Inline breakpoint size for (x86-64, singlepass).
pub const INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS: usize = 7;

/// Inline breakpoint size for (aarch64, singlepass).
pub const INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS: usize = 12;

/// Returns the inline breakpoint size corresponding to an (Architecture, Backend) pair.
pub fn get_inline_breakpoint_size(arch: Architecture, backend: Backend) -> Option<usize> {
match (arch, backend) {
(Architecture::X64, Backend::Singlepass) => Some(7),
(Architecture::Aarch64, Backend::Singlepass) => Some(12),
(Architecture::X64, Backend::Singlepass) => Some(INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS),
(Architecture::Aarch64, Backend::Singlepass) => {
Some(INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS)
}
_ => None,
}
}

/// Attempts to read an inline breakpoint from the code.
///
/// Inline breakpoints are detected by special instruction sequences that never
/// appear in valid code.
pub fn read_inline_breakpoint(
arch: Architecture,
backend: Backend,
Expand All @@ -112,16 +133,20 @@ pub fn read_inline_breakpoint(
match arch {
Architecture::X64 => match backend {
Backend::Singlepass => {
if code.len() < 7 {
if code.len() < INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS {
None
} else if &code[..6] == &[0x0f, 0x0b, 0x0f, 0xb9, 0xcd, 0xff] {
// ud2 ud (int 0xff) code
} else if &code[..INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS - 1]
== &[
0x0f, 0x0b, // ud2
0x0f, 0xb9, // ud
0xcd, 0xff, // int 0xff
]
{
Some(InlineBreakpoint {
size: 7,
ty: match code[6] {
0 => InlineBreakpointType::Trace,
1 => InlineBreakpointType::Middleware,
_ => InlineBreakpointType::Unknown,
size: INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS,
ty: match code[INLINE_BREAKPOINT_SIZE_X86_SINGLEPASS - 1] {
0 => InlineBreakpointType::Middleware,
_ => return None,
},
})
} else {
Expand All @@ -132,15 +157,19 @@ pub fn read_inline_breakpoint(
},
Architecture::Aarch64 => match backend {
Backend::Singlepass => {
if code.len() < 12 {
if code.len() < INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS {
None
} else if &code[..8] == &[0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff] {
} else if &code[..INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS - 4]
== &[
0, 0, 0, 0, // udf #0
0xff, 0xff, 0x00, 0x00, // udf #65535
]
{
Some(InlineBreakpoint {
size: 12,
ty: match code[8] {
0 => InlineBreakpointType::Trace,
1 => InlineBreakpointType::Middleware,
_ => InlineBreakpointType::Unknown,
size: INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS,
ty: match code[INLINE_BREAKPOINT_SIZE_AARCH64_SINGLEPASS - 4] {
0 => InlineBreakpointType::Middleware,
_ => return None,
},
})
} else {
Expand Down
7 changes: 1 addition & 6 deletions lib/runtime-core/src/fault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ extern "C" fn signal_trap_handler(
std::slice::from_raw_parts(ip as *const u8, magic_size),
) {
match ib.ty {
InlineBreakpointType::Trace => {}
InlineBreakpointType::Middleware => {
let out: Option<Result<(), Box<dyn Any + Send>>> =
with_breakpoint_map(|bkpt_map| {
Expand All @@ -321,7 +320,6 @@ extern "C" fn signal_trap_handler(
unwind_result = e;
}
}
_ => println!("Unknown breakpoint type: {:?}", ib.ty),
}

fault.ip.set(ip + magic_size);
Expand Down Expand Up @@ -464,10 +462,7 @@ pub struct FaultInfo {
impl FaultInfo {
/// Parses the stack and builds an execution state image.
pub unsafe fn read_stack(&self, max_depth: Option<usize>) -> Option<ExecutionStateImage> {
let rsp = match self.known_registers[X64Register::GPR(GPR::RSP).to_index().0] {
Some(x) => x,
None => return None,
};
let rsp = self.known_registers[X64Register::GPR(GPR::RSP).to_index().0]?;

Some(CURRENT_CODE_VERSIONS.with(|versions| {
let versions = versions.borrow();
Expand Down
2 changes: 0 additions & 2 deletions lib/runtime-core/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,6 @@ pub mod x64 {
let mut is_baseline: Option<bool> = None;

for version in versions() {
//println!("Lookup IP: {:x}", ret_addr);
match version
.msm
.lookup_call_ip(ret_addr as usize, version.base)
Expand Down Expand Up @@ -1251,7 +1250,6 @@ pub mod x64 {
stack: wasm_stack,
locals: wasm_locals,
};
//println!("WFS = {:?}", wfs);
results.push(wfs);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/singlepass-backend/src/translator_aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1673,8 +1673,8 @@ impl Emitter for Assembler {

fn emit_inline_breakpoint(&mut self, ty: InlineBreakpointType) {
dynasm!(self
; .dword 0
; .dword -1
; .dword 0x00000000
; .dword 0x0000ffff
; .dword (ty as u8 as i32)
);
}
Expand Down