mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Add sig* syscalls
This commit is contained in:
parent
ad426fb5e3
commit
88589a9cbc
@ -127,7 +127,7 @@
|
||||
```rust
|
||||
|
||||
```
|
||||
- **dup** (\_\_\_syscall63) [:top:](#host-apis)
|
||||
- **dup2** (\_\_\_syscall63) [:top:](#host-apis)
|
||||
```rust
|
||||
|
||||
```
|
||||
|
@ -224,6 +224,11 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"___syscall180",
|
||||
ImportValue::Func(syscalls::___syscall180 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall181",
|
||||
ImportValue::Func(syscalls::___syscall181 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall39",
|
||||
@ -264,6 +269,11 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"___syscall192",
|
||||
ImportValue::Func(syscalls::___syscall192 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall63",
|
||||
ImportValue::Func(syscalls::___syscall63 as _),
|
||||
);
|
||||
|
||||
// Process
|
||||
import_object.set(
|
||||
@ -281,6 +291,27 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"abortStackOverflow",
|
||||
ImportValue::Func(process::abort_stack_overflow as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_sigemptyset",
|
||||
ImportValue::Func(process::_sigemptyset as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_sigaddset",
|
||||
ImportValue::Func(process::_sigaddset as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_sigprocmask",
|
||||
ImportValue::Func(process::_sigprocmask as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_sigaction",
|
||||
ImportValue::Func(process::_sigaction as _),
|
||||
);
|
||||
|
||||
// Memory
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -384,10 +415,10 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
mock_external!(import_object, _sysconf);
|
||||
// mock_external!(import_object, _strftime);
|
||||
mock_external!(import_object, _sigsuspend);
|
||||
mock_external!(import_object, _sigprocmask);
|
||||
mock_external!(import_object, _sigemptyset);
|
||||
mock_external!(import_object, _sigaddset);
|
||||
mock_external!(import_object, _sigaction);
|
||||
// mock_external!(import_object, _sigprocmask);
|
||||
// mock_external!(import_object, _sigemptyset);
|
||||
// mock_external!(import_object, _sigaddset);
|
||||
// mock_external!(import_object, _sigaction);
|
||||
mock_external!(import_object, _setitimer);
|
||||
mock_external!(import_object, _setgroups);
|
||||
mock_external!(import_object, _setgrent);
|
||||
@ -418,7 +449,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
mock_external!(import_object, ___syscall75);
|
||||
mock_external!(import_object, ___syscall66);
|
||||
// mock_external!(import_object, ___syscall64);
|
||||
mock_external!(import_object, ___syscall63);
|
||||
// mock_external!(import_object, ___syscall63);
|
||||
mock_external!(import_object, ___syscall60);
|
||||
// mock_external!(import_object, ___syscall54);
|
||||
// mock_external!(import_object, ___syscall39);
|
||||
@ -439,7 +470,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
// mock_external!(import_object, ___syscall195);
|
||||
mock_external!(import_object, ___syscall194);
|
||||
mock_external!(import_object, ___syscall191);
|
||||
mock_external!(import_object, ___syscall181);
|
||||
// mock_external!(import_object, ___syscall181);
|
||||
// mock_external!(import_object, ___syscall180);
|
||||
mock_external!(import_object, ___syscall168);
|
||||
// mock_external!(import_object, ___syscall146);
|
||||
|
@ -33,3 +33,29 @@ pub extern "C" fn abort_stack_overflow() {
|
||||
// TODO: Message incomplete. Need to finish em runtime data first
|
||||
abort_with_message("Stack overflow! Attempted to allocate some bytes on the stack");
|
||||
}
|
||||
|
||||
pub extern "C" fn _sigemptyset(set: u32, instance: &mut Instance) -> i32 {
|
||||
debug!("emscripten::_sigemptyset");
|
||||
let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32;
|
||||
unsafe {
|
||||
*set_addr = 0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub extern "C" fn _sigaction(_signum: u32, act: u32, oldact: u32) -> i32 {
|
||||
debug!("emscripten::_sigaction");
|
||||
0
|
||||
}
|
||||
|
||||
pub extern "C" fn _sigaddset(set: u32, signum: u32, instance: &mut Instance) -> i32 {
|
||||
let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32;
|
||||
unsafe {
|
||||
*set_addr |= 1 << (signum - 1);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub extern "C" fn _sigprocmask() -> i32 {
|
||||
0
|
||||
}
|
@ -29,6 +29,7 @@ use libc::{
|
||||
open,
|
||||
pid_t,
|
||||
pread,
|
||||
pwrite,
|
||||
read,
|
||||
readv,
|
||||
recvfrom,
|
||||
@ -49,6 +50,7 @@ use libc::{
|
||||
in_port_t,
|
||||
in_addr_t,
|
||||
c_char,
|
||||
dup2,
|
||||
};
|
||||
|
||||
/// sys_exit
|
||||
@ -470,6 +472,27 @@ pub extern "C" fn ___syscall180(
|
||||
unsafe { pread(fd, buf_ptr, count as _, offset) as _ }
|
||||
}
|
||||
|
||||
// sys_pwrite
|
||||
pub extern "C" fn ___syscall181(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall181");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
let count: u32 = varargs.get(instance);
|
||||
{
|
||||
let zero: u32 = varargs.get(instance);
|
||||
assert_eq!(zero, 0);
|
||||
}
|
||||
let offset: i64 = varargs.get(instance);
|
||||
|
||||
let buf_ptr = instance.memory_offset_addr(0, buf as _) as _;
|
||||
|
||||
unsafe { pwrite(fd, buf_ptr, count as _, offset) as _ }
|
||||
}
|
||||
|
||||
// sys_stat64
|
||||
pub extern "C" fn ___syscall195(
|
||||
_which: c_int,
|
||||
@ -587,3 +610,18 @@ pub extern "C" fn ___syscall340(
|
||||
0
|
||||
}
|
||||
|
||||
// sys_dup2
|
||||
pub extern "C" fn ___syscall63(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall63");
|
||||
|
||||
let src: i32 = varargs.get(instance);
|
||||
let dst: i32 = varargs.get(instance);
|
||||
|
||||
unsafe {
|
||||
dup2(src, dst)
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
//! 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 std::cell::UnsafeCell;
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use nix::libc::siginfo_t;
|
||||
|
||||
extern "C" {
|
||||
pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int;
|
||||
@ -15,6 +16,7 @@ const SETJMP_BUFFER_LEN: usize = 27;
|
||||
|
||||
thread_local! {
|
||||
pub static SETJMP_BUFFER: UnsafeCell<[::nix::libc::c_int; SETJMP_BUFFER_LEN]> = UnsafeCell::new([0; SETJMP_BUFFER_LEN]);
|
||||
pub static CAUGHT_ADDRESS: Cell<usize> = Cell::new(0);
|
||||
}
|
||||
|
||||
// We need a macro since the arguments we will provide to the funciton
|
||||
@ -28,7 +30,7 @@ thread_local! {
|
||||
macro_rules! call_protected {
|
||||
($x:expr) => {
|
||||
unsafe {
|
||||
use crate::recovery::{setjmp, SETJMP_BUFFER};
|
||||
use crate::recovery::{setjmp, SETJMP_BUFFER, CAUGHT_ADDRESS};
|
||||
use crate::sighandler::install_sighandler;
|
||||
use crate::webassembly::ErrorKind;
|
||||
|
||||
@ -42,6 +44,8 @@ macro_rules! call_protected {
|
||||
let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void);
|
||||
if signum != 0 {
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
let addr = CAUGHT_ADDRESS.with(|cell| cell.get());
|
||||
|
||||
let signal = match Signal::from_c_int(signum) {
|
||||
Ok(SIGFPE) => "floating-point exception",
|
||||
Ok(SIGILL) => "illegal instruction",
|
||||
@ -50,7 +54,7 @@ macro_rules! call_protected {
|
||||
Err(_) => "error while getting the Signal",
|
||||
_ => "unkown trapped signal",
|
||||
};
|
||||
Err(ErrorKind::RuntimeError(format!("trap - {}", signal)))
|
||||
Err(ErrorKind::RuntimeError(format!("trap at {:#x} - {}", addr, signal)))
|
||||
} else {
|
||||
let ret = $x; // TODO: Switch stack?
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
@ -61,7 +65,7 @@ macro_rules! call_protected {
|
||||
}
|
||||
|
||||
/// Unwinds to last protected_call.
|
||||
pub unsafe fn do_unwind(signum: i32) -> ! {
|
||||
pub unsafe fn do_unwind(signum: i32, siginfo: *mut siginfo_t) -> ! {
|
||||
// Since do_unwind is only expected to get called from WebAssembly code which doesn't hold any host resources (locks etc.)
|
||||
// itself, accessing TLS here is safe. In case any other code calls this, it often indicates a memory safety bug and you should
|
||||
// temporarily disable the signal handlers to debug it.
|
||||
@ -70,6 +74,7 @@ pub unsafe fn do_unwind(signum: i32) -> ! {
|
||||
if *jmp_buf == [0; SETJMP_BUFFER_LEN] {
|
||||
::std::process::abort();
|
||||
}
|
||||
CAUGHT_ADDRESS.with(|cell| cell.set((*siginfo).si_addr as _));
|
||||
|
||||
longjmp(jmp_buf as *mut ::nix::libc::c_void, signum)
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ use super::recovery;
|
||||
use nix::sys::signal::{
|
||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||
};
|
||||
use nix::libc::{siginfo_t, c_void};
|
||||
|
||||
pub unsafe fn install_sighandler() {
|
||||
let sa = SigAction::new(
|
||||
SigHandler::Handler(signal_trap_handler),
|
||||
SigHandler::SigAction(signal_trap_handler),
|
||||
SaFlags::SA_ONSTACK,
|
||||
SigSet::empty(),
|
||||
);
|
||||
@ -21,8 +22,8 @@ pub unsafe fn install_sighandler() {
|
||||
sigaction(SIGBUS, &sa).unwrap();
|
||||
}
|
||||
|
||||
extern "C" fn signal_trap_handler(signum: ::nix::libc::c_int) {
|
||||
extern "C" fn signal_trap_handler(signum: ::nix::libc::c_int, siginfo: *mut siginfo_t, _ucontext: *mut c_void) {
|
||||
unsafe {
|
||||
recovery::do_unwind(signum);
|
||||
recovery::do_unwind(signum, siginfo);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user