mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 08:10:49 +00:00
reorganize signal module and leave stubs in windows (#162)
This commit is contained in:
parent
9719781eee
commit
46ac4e9e1a
@ -1,31 +0,0 @@
|
||||
//! Installing signal handlers allows us to handle traps and out-of-bounds memory
|
||||
//! accesses that occur when runniing webassembly.
|
||||
//!
|
||||
//! This code is inspired by: https://github.com/pepyakin/wasmtime/commit/625a2b6c0815b21996e111da51b9664feb174622
|
||||
use crate::call::recovery;
|
||||
use nix::libc::{c_void, siginfo_t};
|
||||
use nix::sys::signal::{
|
||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||
};
|
||||
|
||||
pub unsafe fn install_sighandler() {
|
||||
let sa = SigAction::new(
|
||||
SigHandler::SigAction(signal_trap_handler),
|
||||
SaFlags::SA_ONSTACK,
|
||||
SigSet::empty(),
|
||||
);
|
||||
sigaction(SIGFPE, &sa).unwrap();
|
||||
sigaction(SIGILL, &sa).unwrap();
|
||||
sigaction(SIGSEGV, &sa).unwrap();
|
||||
sigaction(SIGBUS, &sa).unwrap();
|
||||
}
|
||||
|
||||
extern "C" fn signal_trap_handler(
|
||||
signum: ::nix::libc::c_int,
|
||||
siginfo: *mut siginfo_t,
|
||||
ucontext: *mut c_void,
|
||||
) {
|
||||
unsafe {
|
||||
recovery::do_unwind(signum, siginfo as _, ucontext);
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
#[cfg(feature = "cache")]
|
||||
mod cache;
|
||||
mod call;
|
||||
mod func_env;
|
||||
mod libcalls;
|
||||
mod module;
|
||||
mod module_env;
|
||||
mod relocation;
|
||||
mod resolver;
|
||||
mod signal;
|
||||
mod trampoline;
|
||||
|
||||
use cranelift_codegen::{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#[cfg(feature = "cache")]
|
||||
use crate::cache::BackendCache;
|
||||
use crate::{call::Caller, resolver::FuncResolverBuilder, trampoline::Trampolines};
|
||||
use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines};
|
||||
|
||||
use cranelift_codegen::{ir, isa};
|
||||
use cranelift_entity::EntityRef;
|
||||
|
@ -4,12 +4,12 @@ use crate::{
|
||||
trampoline::Trampolines,
|
||||
};
|
||||
use crate::{
|
||||
call::HandlerData,
|
||||
libcalls,
|
||||
relocation::{
|
||||
ExternalRelocation, LibCall, LocalRelocation, LocalTrapSink, Reloc, RelocSink,
|
||||
RelocationType, TrapSink, VmCall, VmCallKind,
|
||||
},
|
||||
signal::HandlerData,
|
||||
};
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
@ -1,11 +1,7 @@
|
||||
mod recovery;
|
||||
mod sighandler;
|
||||
|
||||
pub use self::recovery::{call_protected, HandlerData};
|
||||
|
||||
use crate::relocation::{TrapData, TrapSink};
|
||||
use crate::trampoline::Trampolines;
|
||||
|
||||
use hashbrown::HashSet;
|
||||
use libc::c_void;
|
||||
use std::sync::Arc;
|
||||
use wasmer_runtime_core::{
|
||||
backend::{ProtectedCaller, Token},
|
||||
@ -16,6 +12,18 @@ use wasmer_runtime_core::{
|
||||
vm::{self, ImportBacking},
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use self::unix::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use self::windows::*;
|
||||
|
||||
pub struct Caller {
|
||||
func_export_set: HashSet<FuncIndex>,
|
||||
handler_data: HandlerData,
|
||||
@ -146,3 +154,38 @@ fn get_func_from_index(
|
||||
|
||||
(func_ptr, ctx, signature, sig_index)
|
||||
}
|
||||
|
||||
unsafe impl Send for HandlerData {}
|
||||
unsafe impl Sync for HandlerData {}
|
||||
|
||||
pub struct HandlerData {
|
||||
pub trap_data: TrapSink,
|
||||
exec_buffer_ptr: *const c_void,
|
||||
exec_buffer_size: usize,
|
||||
}
|
||||
|
||||
impl HandlerData {
|
||||
pub fn new(
|
||||
trap_data: TrapSink,
|
||||
exec_buffer_ptr: *const c_void,
|
||||
exec_buffer_size: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
trap_data,
|
||||
exec_buffer_ptr,
|
||||
exec_buffer_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(&self, ip: *const c_void) -> Option<TrapData> {
|
||||
let ip = ip as usize;
|
||||
let buffer_ptr = self.exec_buffer_ptr as usize;
|
||||
|
||||
if buffer_ptr <= ip && ip < buffer_ptr + self.exec_buffer_size {
|
||||
let offset = ip - buffer_ptr;
|
||||
self.trap_data.lookup(offset)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
//! Installing signal handlers allows us to handle traps and out-of-bounds memory
|
||||
//! accesses that occur when runniing webassembly.
|
||||
//!
|
||||
//! This code is inspired by: https://github.com/pepyakin/wasmtime/commit/625a2b6c0815b21996e111da51b9664feb174622
|
||||
//!
|
||||
//! When a WebAssembly module triggers any traps, we perform recovery here.
|
||||
//!
|
||||
//! This module uses TLS (thread-local storage) to track recovery information. Since the four signals we're handling
|
||||
//! are very special, the async signal unsafety of Rust's TLS implementation generally does not affect the correctness here
|
||||
//! unless you have memory unsafety elsewhere in your code.
|
||||
|
||||
use crate::call::sighandler::install_sighandler;
|
||||
//!
|
||||
use crate::relocation::{TrapCode, TrapData, TrapSink};
|
||||
use crate::signal::HandlerData;
|
||||
use libc::{c_int, c_void, siginfo_t};
|
||||
use nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV};
|
||||
use nix::sys::signal::{
|
||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||
};
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::ptr;
|
||||
use std::sync::Once;
|
||||
@ -17,11 +24,33 @@ use wasmer_runtime_core::{
|
||||
types::{MemoryIndex, TableIndex},
|
||||
};
|
||||
|
||||
extern "C" fn signal_trap_handler(
|
||||
signum: ::nix::libc::c_int,
|
||||
siginfo: *mut siginfo_t,
|
||||
ucontext: *mut c_void,
|
||||
) {
|
||||
unsafe {
|
||||
do_unwind(signum, siginfo as _, ucontext);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn setjmp(env: *mut c_void) -> c_int;
|
||||
fn longjmp(env: *mut c_void, val: c_int) -> !;
|
||||
}
|
||||
|
||||
pub unsafe fn install_sighandler() {
|
||||
let sa = SigAction::new(
|
||||
SigHandler::SigAction(signal_trap_handler),
|
||||
SaFlags::SA_ONSTACK,
|
||||
SigSet::empty(),
|
||||
);
|
||||
sigaction(SIGFPE, &sa).unwrap();
|
||||
sigaction(SIGILL, &sa).unwrap();
|
||||
sigaction(SIGSEGV, &sa).unwrap();
|
||||
sigaction(SIGBUS, &sa).unwrap();
|
||||
}
|
||||
|
||||
const SETJMP_BUFFER_LEN: usize = 27;
|
||||
pub static SIGHANDLER_INIT: Once = Once::new();
|
||||
|
||||
@ -31,41 +60,6 @@ thread_local! {
|
||||
pub static CURRENT_EXECUTABLE_BUFFER: Cell<*const c_void> = Cell::new(ptr::null());
|
||||
}
|
||||
|
||||
unsafe impl Send for HandlerData {}
|
||||
unsafe impl Sync for HandlerData {}
|
||||
|
||||
pub struct HandlerData {
|
||||
pub trap_data: TrapSink,
|
||||
exec_buffer_ptr: *const c_void,
|
||||
exec_buffer_size: usize,
|
||||
}
|
||||
|
||||
impl HandlerData {
|
||||
pub fn new(
|
||||
trap_data: TrapSink,
|
||||
exec_buffer_ptr: *const c_void,
|
||||
exec_buffer_size: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
trap_data,
|
||||
exec_buffer_ptr,
|
||||
exec_buffer_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(&self, ip: *const c_void) -> Option<TrapData> {
|
||||
let ip = ip as usize;
|
||||
let buffer_ptr = self.exec_buffer_ptr as usize;
|
||||
|
||||
if buffer_ptr <= ip && ip < buffer_ptr + self.exec_buffer_size {
|
||||
let offset = ip - buffer_ptr;
|
||||
self.trap_data.lookup(offset)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult<T> {
|
||||
unsafe {
|
||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
6
lib/clif-backend/src/signal/windows.rs
Normal file
6
lib/clif-backend/src/signal/windows.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use crate::signal::HandlerData;
|
||||
use wasmer_runtime_core::error::RuntimeResult;
|
||||
|
||||
pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult<T> {
|
||||
unimplemented!("TODO");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user