mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-26 23:21:35 +00:00
Merge branch 'master' into feature/debug-prototype2
This commit is contained in:
@ -42,7 +42,9 @@ fn get_isa() -> Box<dyn isa::TargetIsa> {
|
||||
builder.set("opt_level", "speed_and_size").unwrap();
|
||||
builder.set("jump_tables_enabled", "false").unwrap();
|
||||
|
||||
if cfg!(not(test)) && cfg!(not(debug)) {
|
||||
if cfg!(test) || cfg!(debug_assertions) {
|
||||
builder.set("enable_verifier", "true").unwrap();
|
||||
} else {
|
||||
builder.set("enable_verifier", "false").unwrap();
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,9 @@ pub extern "C" fn nearbyintf64(x: f64) -> f64 {
|
||||
}
|
||||
|
||||
// FIXME: Is there a replacement on AArch64?
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
||||
#[cfg(all(
|
||||
any(target_os = "freebsd", target_os = "linux"),
|
||||
target_arch = "aarch64"
|
||||
))]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rust_probestack() {}
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use cranelift_codegen::{
|
||||
binemit::{Stackmap, StackmapSink},
|
||||
ir, isa, Context, ValueLabelsRanges,
|
||||
ir, isa,CodegenError, Context, ValueLabelsRanges,
|
||||
};
|
||||
use rayon::prelude::*;
|
||||
use std::{
|
||||
@ -141,7 +141,12 @@ impl FuncResolverBuilder {
|
||||
&mut local_trap_sink,
|
||||
&mut stackmap_sink,
|
||||
)
|
||||
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
|
||||
.map_err(|e| match e {
|
||||
CodegenError::Verifier(v) => CompileError::InternalError {
|
||||
msg: format!("Verifier error: {}", v),
|
||||
},
|
||||
_ => CompileError::InternalError { msg: e.to_string() },
|
||||
})?;
|
||||
|
||||
let debug_entry = if generate_debug_info {
|
||||
let func = &ctx.func;
|
||||
|
@ -8,7 +8,7 @@ use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
|
||||
use wasmer_runtime_core::{
|
||||
backend::RunnableModule,
|
||||
module::ModuleInfo,
|
||||
typed_func::{Trampoline, Wasm, WasmTrapInfo},
|
||||
typed_func::{Trampoline, Wasm},
|
||||
types::{LocalFuncIndex, SigIndex},
|
||||
vm,
|
||||
};
|
||||
@ -29,10 +29,7 @@ thread_local! {
|
||||
pub static TRAP_EARLY_DATA: Cell<Option<Box<dyn Any + Send>>> = Cell::new(None);
|
||||
}
|
||||
|
||||
pub enum CallProtError {
|
||||
Trap(WasmTrapInfo),
|
||||
Error(Box<dyn Any + Send>),
|
||||
}
|
||||
pub struct CallProtError(pub Box<dyn Any + Send>);
|
||||
|
||||
pub struct Caller {
|
||||
handler_data: HandlerData,
|
||||
@ -66,8 +63,7 @@ impl RunnableModule for Caller {
|
||||
func: NonNull<vm::Func>,
|
||||
args: *const u64,
|
||||
rets: *mut u64,
|
||||
trap_info: *mut WasmTrapInfo,
|
||||
user_error: *mut Option<Box<dyn Any + Send>>,
|
||||
error_out: *mut Option<Box<dyn Any + Send>>,
|
||||
invoke_env: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
||||
@ -84,10 +80,7 @@ impl RunnableModule for Caller {
|
||||
|
||||
match res {
|
||||
Err(err) => {
|
||||
match err {
|
||||
CallProtError::Trap(info) => *trap_info = info,
|
||||
CallProtError::Error(data) => *user_error = Some(data),
|
||||
}
|
||||
*error_out = Some(err.0);
|
||||
false
|
||||
}
|
||||
Ok(()) => true,
|
||||
|
@ -18,7 +18,7 @@ use nix::sys::signal::{
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::ptr;
|
||||
use std::sync::Once;
|
||||
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||
use wasmer_runtime_core::backend::ExceptionCode;
|
||||
|
||||
extern "C" fn signal_trap_handler(
|
||||
signum: ::nix::libc::c_int,
|
||||
@ -79,7 +79,7 @@ pub fn call_protected<T>(
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
|
||||
if let Some(data) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
||||
Err(CallProtError::Error(data))
|
||||
Err(CallProtError(data))
|
||||
} else {
|
||||
let (faulting_addr, inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
||||
|
||||
@ -88,21 +88,31 @@ pub fn call_protected<T>(
|
||||
srcloc: _,
|
||||
}) = handler_data.lookup(inst_ptr)
|
||||
{
|
||||
Err(CallProtError::Trap(match Signal::from_c_int(signum) {
|
||||
Err(CallProtError(Box::new(match Signal::from_c_int(signum) {
|
||||
Ok(SIGILL) => match trapcode {
|
||||
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
|
||||
TrapCode::IndirectCallToNull => WasmTrapInfo::CallIndirectOOB,
|
||||
TrapCode::HeapOutOfBounds => WasmTrapInfo::MemoryOutOfBounds,
|
||||
TrapCode::TableOutOfBounds => WasmTrapInfo::CallIndirectOOB,
|
||||
_ => WasmTrapInfo::Unknown,
|
||||
TrapCode::StackOverflow => ExceptionCode::MemoryOutOfBounds,
|
||||
TrapCode::HeapOutOfBounds => ExceptionCode::MemoryOutOfBounds,
|
||||
TrapCode::TableOutOfBounds => ExceptionCode::CallIndirectOOB,
|
||||
TrapCode::OutOfBounds => ExceptionCode::MemoryOutOfBounds,
|
||||
TrapCode::IndirectCallToNull => ExceptionCode::CallIndirectOOB,
|
||||
TrapCode::BadSignature => ExceptionCode::IncorrectCallIndirectSignature,
|
||||
TrapCode::IntegerOverflow => ExceptionCode::IllegalArithmetic,
|
||||
TrapCode::IntegerDivisionByZero => ExceptionCode::IllegalArithmetic,
|
||||
TrapCode::BadConversionToInteger => ExceptionCode::IllegalArithmetic,
|
||||
TrapCode::UnreachableCodeReached => ExceptionCode::Unreachable,
|
||||
_ => {
|
||||
return Err(CallProtError(Box::new(
|
||||
"unknown clif trap code".to_string(),
|
||||
)))
|
||||
}
|
||||
},
|
||||
Ok(SIGSEGV) | Ok(SIGBUS) => WasmTrapInfo::MemoryOutOfBounds,
|
||||
Ok(SIGFPE) => WasmTrapInfo::IllegalArithmetic,
|
||||
Ok(SIGSEGV) | Ok(SIGBUS) => ExceptionCode::MemoryOutOfBounds,
|
||||
Ok(SIGFPE) => ExceptionCode::IllegalArithmetic,
|
||||
_ => unimplemented!(
|
||||
"WasmTrapInfo::Unknown signal:{:?}",
|
||||
"ExceptionCode::Unknown signal:{:?}",
|
||||
Signal::from_c_int(signum)
|
||||
),
|
||||
}))
|
||||
})))
|
||||
} else {
|
||||
let signal = match Signal::from_c_int(signum) {
|
||||
Ok(SIGFPE) => "floating-point exception",
|
||||
@ -114,7 +124,7 @@ pub fn call_protected<T>(
|
||||
};
|
||||
// When the trap-handler is fully implemented, this will return more information.
|
||||
let s = format!("unknown trap at {:p} - {}", faulting_addr, signal);
|
||||
Err(CallProtError::Error(Box::new(s)))
|
||||
Err(CallProtError(Box::new(s)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -141,6 +151,84 @@ pub unsafe fn do_unwind(signum: i32, siginfo: *const c_void, ucontext: *const c_
|
||||
longjmp(jmp_buf as *mut ::nix::libc::c_void, signum)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "freebsd", target_arch = "aarch64"))]
|
||||
unsafe fn get_faulting_addr_and_ip(
|
||||
_siginfo: *const c_void,
|
||||
_ucontext: *const c_void,
|
||||
) -> (*const c_void, *const c_void) {
|
||||
(::std::ptr::null(), ::std::ptr::null())
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
||||
unsafe fn get_faulting_addr_and_ip(
|
||||
siginfo: *const c_void,
|
||||
ucontext: *const c_void,
|
||||
) -> (*const c_void, *const c_void) {
|
||||
#[repr(C)]
|
||||
pub struct ucontext_t {
|
||||
uc_sigmask: libc::sigset_t,
|
||||
uc_mcontext: mcontext_t,
|
||||
uc_link: *mut ucontext_t,
|
||||
uc_stack: libc::stack_t,
|
||||
uc_flags: i32,
|
||||
__spare__: [i32; 4],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct mcontext_t {
|
||||
mc_onstack: u64,
|
||||
mc_rdi: u64,
|
||||
mc_rsi: u64,
|
||||
mc_rdx: u64,
|
||||
mc_rcx: u64,
|
||||
mc_r8: u64,
|
||||
mc_r9: u64,
|
||||
mc_rax: u64,
|
||||
mc_rbx: u64,
|
||||
mc_rbp: u64,
|
||||
mc_r10: u64,
|
||||
mc_r11: u64,
|
||||
mc_r12: u64,
|
||||
mc_r13: u64,
|
||||
mc_r14: u64,
|
||||
mc_r15: u64,
|
||||
mc_trapno: u32,
|
||||
mc_fs: u16,
|
||||
mc_gs: u16,
|
||||
mc_addr: u64,
|
||||
mc_flags: u32,
|
||||
mc_es: u16,
|
||||
mc_ds: u16,
|
||||
mc_err: u64,
|
||||
mc_rip: u64,
|
||||
mc_cs: u64,
|
||||
mc_rflags: u64,
|
||||
mc_rsp: u64,
|
||||
mc_ss: u64,
|
||||
mc_len: i64,
|
||||
|
||||
mc_fpformat: i64,
|
||||
mc_ownedfp: i64,
|
||||
mc_fpstate: [i64; 64], // mc_fpstate[0] is a pointer to savefpu
|
||||
|
||||
mc_fsbase: u64,
|
||||
mc_gsbase: u64,
|
||||
|
||||
mc_xfpustate: u64,
|
||||
mc_xfpustate_len: u64,
|
||||
|
||||
mc_spare: [i64; 4],
|
||||
}
|
||||
|
||||
let siginfo = siginfo as *const siginfo_t;
|
||||
let si_addr = (*siginfo).si_addr;
|
||||
|
||||
let ucontext = ucontext as *const ucontext_t;
|
||||
let rip = (*ucontext).uc_mcontext.mc_rip;
|
||||
|
||||
(si_addr, rip as _)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
||||
unsafe fn get_faulting_addr_and_ip(
|
||||
_siginfo: *const c_void,
|
||||
@ -239,6 +327,8 @@ unsafe fn get_faulting_addr_and_ip(
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
all(target_os = "freebsd", target_arch = "aarch64"),
|
||||
all(target_os = "freebsd", target_arch = "x86_64"),
|
||||
all(target_os = "macos", target_arch = "x86_64"),
|
||||
all(target_os = "linux", target_arch = "x86_64"),
|
||||
all(target_os = "linux", target_arch = "aarch64"),
|
||||
|
@ -8,7 +8,8 @@ use std::{
|
||||
ptr::{self, NonNull},
|
||||
};
|
||||
use wasmer_runtime_core::{
|
||||
typed_func::{Trampoline, WasmTrapInfo},
|
||||
backend::ExceptionCode,
|
||||
typed_func::Trampoline,
|
||||
vm::{Ctx, Func},
|
||||
};
|
||||
use wasmer_win_exception_handler::CallProtectedData;
|
||||
@ -62,22 +63,26 @@ pub fn call_protected(
|
||||
srcloc: _,
|
||||
}) = handler_data.lookup(instruction_pointer as _)
|
||||
{
|
||||
Err(CallProtError::Trap(match code as DWORD {
|
||||
EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds,
|
||||
Err(CallProtError(Box::new(match code as DWORD {
|
||||
EXCEPTION_ACCESS_VIOLATION => ExceptionCode::MemoryOutOfBounds,
|
||||
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
|
||||
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
|
||||
TrapCode::IndirectCallToNull => WasmTrapInfo::CallIndirectOOB,
|
||||
TrapCode::HeapOutOfBounds => WasmTrapInfo::MemoryOutOfBounds,
|
||||
TrapCode::TableOutOfBounds => WasmTrapInfo::CallIndirectOOB,
|
||||
TrapCode::UnreachableCodeReached => WasmTrapInfo::Unreachable,
|
||||
_ => WasmTrapInfo::Unknown,
|
||||
TrapCode::BadSignature => ExceptionCode::IncorrectCallIndirectSignature,
|
||||
TrapCode::IndirectCallToNull => ExceptionCode::CallIndirectOOB,
|
||||
TrapCode::HeapOutOfBounds => ExceptionCode::MemoryOutOfBounds,
|
||||
TrapCode::TableOutOfBounds => ExceptionCode::CallIndirectOOB,
|
||||
TrapCode::UnreachableCodeReached => ExceptionCode::Unreachable,
|
||||
_ => return Err(CallProtError(Box::new("unknown trap code".to_string()))),
|
||||
},
|
||||
EXCEPTION_STACK_OVERFLOW => WasmTrapInfo::Unknown,
|
||||
EXCEPTION_STACK_OVERFLOW => ExceptionCode::MemoryOutOfBounds,
|
||||
EXCEPTION_INT_DIVIDE_BY_ZERO | EXCEPTION_INT_OVERFLOW => {
|
||||
WasmTrapInfo::IllegalArithmetic
|
||||
ExceptionCode::IllegalArithmetic
|
||||
}
|
||||
_ => WasmTrapInfo::Unknown,
|
||||
}))
|
||||
_ => {
|
||||
return Err(CallProtError(Box::new(
|
||||
"unknown exception code".to_string(),
|
||||
)))
|
||||
}
|
||||
})))
|
||||
} else {
|
||||
let signal = match code as DWORD {
|
||||
EXCEPTION_FLT_DENORMAL_OPERAND
|
||||
@ -110,7 +115,7 @@ pub fn call_protected(
|
||||
exception_address, code, signal,
|
||||
);
|
||||
|
||||
Err(CallProtError::Error(Box::new(s)))
|
||||
Err(CallProtError(Box::new(s)))
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user