mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
create platform mods for syscalls and stub for windows (#161)
* create platform mods for syscalls and stub for windows * missing constants and duplicate use statements
This commit is contained in:
parent
f8e2b25137
commit
9719781eee
466
lib/emscripten/src/syscalls/mod.rs
Normal file
466
lib/emscripten/src/syscalls/mod.rs
Normal file
@ -0,0 +1,466 @@
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use self::unix::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use self::windows::*;
|
||||
|
||||
use super::utils::copy_stat_into_wasm;
|
||||
use super::varargs::VarArgs;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
||||
use libc::{
|
||||
accept,
|
||||
bind,
|
||||
// ENOTTY,
|
||||
c_char,
|
||||
c_int,
|
||||
c_void,
|
||||
chdir,
|
||||
// fcntl, setsockopt, getppid
|
||||
close,
|
||||
connect,
|
||||
dup2,
|
||||
exit,
|
||||
fstat,
|
||||
getpeername,
|
||||
getpid,
|
||||
getsockname,
|
||||
getsockopt,
|
||||
// iovec,
|
||||
listen,
|
||||
lseek,
|
||||
mkdir,
|
||||
off_t,
|
||||
open,
|
||||
read,
|
||||
// readv,
|
||||
recvfrom,
|
||||
rmdir,
|
||||
// writev,
|
||||
sendto,
|
||||
setsockopt,
|
||||
sockaddr,
|
||||
socket,
|
||||
ssize_t,
|
||||
stat,
|
||||
write,
|
||||
EINVAL,
|
||||
// sockaddr_in,
|
||||
};
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
use super::env;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
// use std::sys::fd::FileDesc;
|
||||
|
||||
// Another conditional constant for name resolution: Macos et iOS use
|
||||
// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
|
||||
// Other platforms do otherwise.
|
||||
#[cfg(target_os = "darwin")]
|
||||
use libc::SO_NOSIGPIPE;
|
||||
#[cfg(not(target_os = "darwin"))]
|
||||
const SO_NOSIGPIPE: c_int = 0;
|
||||
|
||||
/// exit
|
||||
pub fn ___syscall1(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) {
|
||||
debug!("emscripten::___syscall1 (exit) {}", which);
|
||||
let status: i32 = varargs.get(ctx);
|
||||
unsafe {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
/// read
|
||||
pub fn ___syscall3(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall3 (read) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
let count = varargs.get(ctx);
|
||||
debug!("=> fd: {}, buf_offset: {}, count: {}", fd, buf, count);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_void;
|
||||
let ret = unsafe { read(fd, buf_addr, count) };
|
||||
debug!("=> ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
|
||||
/// write
|
||||
pub fn ___syscall4(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall4 (write) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
let count = varargs.get(ctx);
|
||||
debug!("=> fd: {}, buf: {}, count: {}", fd, buf, count);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *const c_void;
|
||||
unsafe { write(fd, buf_addr, count) as i32 }
|
||||
}
|
||||
|
||||
/// open
|
||||
pub fn ___syscall5(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall5 (open) {}", which);
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let flags: i32 = varargs.get(ctx);
|
||||
let mode: u32 = varargs.get(ctx);
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
|
||||
let fd = unsafe { open(pathname_addr, flags, mode) };
|
||||
debug!(
|
||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
||||
pathname, flags, mode, fd, path_str
|
||||
);
|
||||
fd
|
||||
}
|
||||
|
||||
/// close
|
||||
pub fn ___syscall6(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall6 (close) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
debug!("fd: {}", fd);
|
||||
unsafe { close(fd) }
|
||||
}
|
||||
|
||||
// chdir
|
||||
pub fn ___syscall12(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall12 (chdir) {}", which);
|
||||
let path_addr: i32 = varargs.get(ctx);
|
||||
unsafe {
|
||||
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const i8;
|
||||
let path = std::ffi::CStr::from_ptr(path_ptr);
|
||||
let ret = chdir(path_ptr);
|
||||
debug!("=> path: {:?}, ret: {}", path, ret);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall10(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall10");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall15(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall15");
|
||||
-1
|
||||
}
|
||||
|
||||
// getpid
|
||||
pub fn ___syscall20(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall20 (getpid)");
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
pub fn ___syscall38(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall38");
|
||||
-1
|
||||
}
|
||||
|
||||
// rmdir
|
||||
pub fn ___syscall40(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall40 (rmdir)");
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
unsafe { rmdir(pathname_addr) }
|
||||
}
|
||||
|
||||
pub fn ___syscall60(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall60");
|
||||
-1
|
||||
}
|
||||
|
||||
// dup2
|
||||
pub fn ___syscall63(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall63 (dup2) {}", which);
|
||||
|
||||
let src: i32 = varargs.get(ctx);
|
||||
let dst: i32 = varargs.get(ctx);
|
||||
|
||||
unsafe { dup2(src, dst) }
|
||||
}
|
||||
|
||||
// getppid
|
||||
pub fn ___syscall64(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall64 (getppid)");
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
pub fn ___syscall66(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall66");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall75(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall75");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall85(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall85");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall91(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall91");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall97(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall97");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall110(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall110");
|
||||
-1
|
||||
}
|
||||
|
||||
// mmap2
|
||||
pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall192 (mmap2) {}", which);
|
||||
let addr: i32 = varargs.get(ctx);
|
||||
let len: u32 = varargs.get(ctx);
|
||||
let prot: i32 = varargs.get(ctx);
|
||||
let flags: i32 = varargs.get(ctx);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let off: i32 = varargs.get(ctx);
|
||||
debug!(
|
||||
"=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}",
|
||||
addr, len, prot, flags, fd, off
|
||||
);
|
||||
|
||||
if fd == -1 {
|
||||
let ptr = env::call_memalign(16384, len, ctx);
|
||||
if ptr == 0 {
|
||||
return -1;
|
||||
}
|
||||
env::call_memset(ptr, 0, len, ctx);
|
||||
ptr as _
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/// lseek
|
||||
pub fn ___syscall140(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> c_int
|
||||
debug!("emscripten::___syscall140 (lseek) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let offset = varargs.get(ctx);
|
||||
let whence: i32 = varargs.get(ctx);
|
||||
debug!("=> fd: {}, offset: {}, whence = {}", fd, offset, whence);
|
||||
unsafe { lseek(fd, offset, whence) as _ }
|
||||
}
|
||||
|
||||
/// readv
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall145(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall145 (readv) {}", which);
|
||||
// let fd: i32 = varargs.get(ctx);
|
||||
// let iov: u32 = varargs.get(ctx);
|
||||
// let iovcnt: i32 = varargs.get(ctx);
|
||||
// debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
// let iov_addr = emscripten_memory_pointer!(ctx.memory(0), iov) as *mut iovec;
|
||||
// unsafe { readv(fd, iov_addr, iovcnt) }
|
||||
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let iov: i32 = varargs.get(ctx);
|
||||
let iovcnt: i32 = varargs.get(ctx);
|
||||
|
||||
#[repr(C)]
|
||||
struct GuestIovec {
|
||||
iov_base: i32,
|
||||
iov_len: i32,
|
||||
}
|
||||
|
||||
debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
let mut ret = 0;
|
||||
unsafe {
|
||||
for i in 0..iovcnt {
|
||||
let guest_iov_addr =
|
||||
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
|
||||
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
|
||||
as *mut c_void;
|
||||
let iov_len = (*guest_iov_addr).iov_len as _;
|
||||
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
|
||||
let curr = read(fd, iov_base, iov_len);
|
||||
if curr < 0 {
|
||||
return -1;
|
||||
}
|
||||
ret += curr;
|
||||
}
|
||||
// debug!(" => ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
}
|
||||
|
||||
// writev
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall146(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall146 (writev) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let iov: i32 = varargs.get(ctx);
|
||||
let iovcnt: i32 = varargs.get(ctx);
|
||||
|
||||
#[repr(C)]
|
||||
struct GuestIovec {
|
||||
iov_base: i32,
|
||||
iov_len: i32,
|
||||
}
|
||||
|
||||
debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
let mut ret = 0;
|
||||
unsafe {
|
||||
for i in 0..iovcnt {
|
||||
let guest_iov_addr =
|
||||
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
|
||||
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
|
||||
as *const c_void;
|
||||
let iov_len = (*guest_iov_addr).iov_len as _;
|
||||
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
|
||||
let curr = write(fd, iov_base, iov_len);
|
||||
if curr < 0 {
|
||||
return -1;
|
||||
}
|
||||
ret += curr;
|
||||
}
|
||||
// debug!(" => ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall168(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall168");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall191(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall191 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall194(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall194 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall196(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall194 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall199(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall199 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
// stat64
|
||||
pub fn ___syscall195(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall195 (stat64) {}", which);
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
|
||||
unsafe {
|
||||
let mut _stat: stat = std::mem::zeroed();
|
||||
let ret = stat(pathname_addr, &mut _stat);
|
||||
debug!("ret: {}", ret);
|
||||
if ret != 0 {
|
||||
return ret;
|
||||
}
|
||||
copy_stat_into_wasm(ctx, buf, &_stat);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
// fstat64
|
||||
pub fn ___syscall197(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall197 (fstat64) {}", which);
|
||||
let fd: c_int = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
|
||||
unsafe {
|
||||
let mut stat = std::mem::zeroed();
|
||||
let ret = fstat(fd, &mut stat);
|
||||
debug!("ret: {}", ret);
|
||||
if ret != 0 {
|
||||
return ret;
|
||||
}
|
||||
copy_stat_into_wasm(ctx, buf, &stat);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn ___syscall220(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall220");
|
||||
-1
|
||||
}
|
||||
|
||||
// fcntl64
|
||||
pub fn ___syscall221(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall221 (fcntl64) {}", which);
|
||||
// fcntl64
|
||||
let _fd: i32 = varargs.get(ctx);
|
||||
let cmd: u32 = varargs.get(ctx);
|
||||
match cmd {
|
||||
2 => 0,
|
||||
_ => -1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall268(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall268");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall272(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall272");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall295(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall295");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall300(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall300");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall334(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall334");
|
||||
-1
|
||||
}
|
||||
|
||||
// prlimit64
|
||||
pub fn ___syscall340(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall340 (prlimit64), {}", which);
|
||||
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
|
||||
let _pid: i32 = varargs.get(ctx);
|
||||
let _resource: i32 = varargs.get(ctx);
|
||||
let _new_limit: u32 = varargs.get(ctx);
|
||||
let old_limit: u32 = varargs.get(ctx);
|
||||
|
||||
if old_limit != 0 {
|
||||
// just report no limits
|
||||
let buf_ptr = emscripten_memory_pointer!(ctx.memory(0), old_limit) as *mut u8;
|
||||
let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) };
|
||||
|
||||
LittleEndian::write_i32(&mut buf[..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[4..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[8..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[12..], -1); // RLIM_INFINITY
|
||||
}
|
||||
|
||||
0
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
use super::utils::copy_stat_into_wasm;
|
||||
use super::varargs::VarArgs;
|
||||
use crate::varargs::VarArgs;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
||||
@ -75,7 +74,6 @@ use wasmer_runtime_core::vm::Ctx;
|
||||
use super::env;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
// use std::sys::fd::FileDesc;
|
||||
|
||||
// Linking to functions that are not provided by rust libc
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -95,96 +93,17 @@ use libc::SO_NOSIGPIPE;
|
||||
#[cfg(not(target_os = "darwin"))]
|
||||
const SO_NOSIGPIPE: c_int = 0;
|
||||
|
||||
/// exit
|
||||
pub fn ___syscall1(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) {
|
||||
debug!("emscripten::___syscall1 (exit) {}", which);
|
||||
let status: i32 = varargs.get(ctx);
|
||||
unsafe {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
// chown
|
||||
pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall212 (chown) {}", which);
|
||||
|
||||
/// read
|
||||
pub fn ___syscall3(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall3 (read) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
let count = varargs.get(ctx);
|
||||
debug!("=> fd: {}, buf_offset: {}, count: {}", fd, buf, count);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_void;
|
||||
let ret = unsafe { read(fd, buf_addr, count) };
|
||||
debug!("=> ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
|
||||
/// write
|
||||
pub fn ___syscall4(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall4 (write) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
let count = varargs.get(ctx);
|
||||
debug!("=> fd: {}, buf: {}, count: {}", fd, buf, count);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *const c_void;
|
||||
unsafe { write(fd, buf_addr, count) as i32 }
|
||||
}
|
||||
|
||||
/// open
|
||||
pub fn ___syscall5(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall5 (open) {}", which);
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let flags: i32 = varargs.get(ctx);
|
||||
let mode: u32 = varargs.get(ctx);
|
||||
let owner: u32 = varargs.get(ctx);
|
||||
let group: u32 = varargs.get(ctx);
|
||||
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
|
||||
let fd = unsafe { open(pathname_addr, flags, mode) };
|
||||
debug!(
|
||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
||||
pathname, flags, mode, fd, path_str
|
||||
);
|
||||
fd
|
||||
}
|
||||
|
||||
/// close
|
||||
pub fn ___syscall6(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall6 (close) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
debug!("fd: {}", fd);
|
||||
unsafe { close(fd) }
|
||||
}
|
||||
|
||||
// chdir
|
||||
pub fn ___syscall12(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall12 (chdir) {}", which);
|
||||
let path_addr: i32 = varargs.get(ctx);
|
||||
unsafe {
|
||||
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const i8;
|
||||
let path = std::ffi::CStr::from_ptr(path_ptr);
|
||||
let ret = chdir(path_ptr);
|
||||
debug!("=> path: {:?}, ret: {}", path, ret);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall10(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall10");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall15(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall15");
|
||||
-1
|
||||
}
|
||||
|
||||
// getpid
|
||||
pub fn ___syscall20(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall20 (getpid)");
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
pub fn ___syscall38(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall38");
|
||||
-1
|
||||
unsafe { chown(pathname_addr, owner, group) }
|
||||
}
|
||||
|
||||
// mkdir
|
||||
@ -196,12 +115,57 @@ pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
unsafe { mkdir(pathname_addr, mode as _) }
|
||||
}
|
||||
|
||||
// rmdir
|
||||
pub fn ___syscall40(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall40 (rmdir)");
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
unsafe { rmdir(pathname_addr) }
|
||||
// getgid
|
||||
pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall201 (getgid)");
|
||||
unsafe {
|
||||
// Maybe fix: Emscripten returns 0 always
|
||||
getgid() as i32
|
||||
}
|
||||
}
|
||||
|
||||
// getgid32
|
||||
pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
// gid_t
|
||||
debug!("emscripten::___syscall202 (getgid32)");
|
||||
unsafe {
|
||||
// Maybe fix: Emscripten returns 0 always
|
||||
getgid() as _
|
||||
}
|
||||
}
|
||||
|
||||
/// dup3
|
||||
pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
// Implementation based on description at https://linux.die.net/man/2/dup3
|
||||
debug!("emscripten::___syscall330 (dup3)");
|
||||
let oldfd: c_int = varargs.get(ctx);
|
||||
let newfd: c_int = varargs.get(ctx);
|
||||
let flags: c_int = varargs.get(ctx);
|
||||
|
||||
if oldfd == newfd {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
let res = unsafe { dup2(oldfd, newfd) };
|
||||
|
||||
// Set flags on newfd (https://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html)
|
||||
let mut old_flags = unsafe { fcntl(newfd, F_GETFD, 0) };
|
||||
|
||||
if old_flags > 0 {
|
||||
old_flags |= flags;
|
||||
} else if old_flags == 0 {
|
||||
old_flags &= !flags;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
fcntl(newfd, F_SETFD, old_flags);
|
||||
}
|
||||
|
||||
debug!(
|
||||
"=> oldfd: {}, newfd: {}, flags: {} = pid: {}",
|
||||
oldfd, newfd, flags, res
|
||||
);
|
||||
res
|
||||
}
|
||||
|
||||
/// ioctl
|
||||
@ -246,60 +210,6 @@ pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
}
|
||||
}
|
||||
|
||||
// setpgid
|
||||
pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall57 (setpgid) {}", which);
|
||||
let pid: i32 = varargs.get(ctx);
|
||||
let pgid: i32 = varargs.get(ctx);
|
||||
unsafe { setpgid(pid, pgid) }
|
||||
}
|
||||
|
||||
pub fn ___syscall60(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall60");
|
||||
-1
|
||||
}
|
||||
|
||||
// dup2
|
||||
pub fn ___syscall63(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall63 (dup2) {}", which);
|
||||
|
||||
let src: i32 = varargs.get(ctx);
|
||||
let dst: i32 = varargs.get(ctx);
|
||||
|
||||
unsafe { dup2(src, dst) }
|
||||
}
|
||||
|
||||
// getppid
|
||||
pub fn ___syscall64(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall64 (getppid)");
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
pub fn ___syscall66(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall66");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall75(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall75");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall85(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall85");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall91(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall91");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall97(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall97");
|
||||
-1
|
||||
}
|
||||
|
||||
// socketcall
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
@ -357,7 +267,7 @@ pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
"=> domain: {} (AF_INET/2), type: {} (SOCK_STREAM/1), protocol: {} = fd: {}",
|
||||
domain, ty, protocol, fd
|
||||
);
|
||||
fd
|
||||
fd as _
|
||||
}
|
||||
2 => {
|
||||
debug!("socket: bind");
|
||||
@ -440,7 +350,7 @@ pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
|
||||
debug!("fd: {}", fd);
|
||||
|
||||
fd
|
||||
fd as _
|
||||
}
|
||||
6 => {
|
||||
debug!("socket: getsockname");
|
||||
@ -553,180 +463,6 @@ pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall110(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall110");
|
||||
-1
|
||||
}
|
||||
|
||||
/// wait4
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
debug!("emscripten::___syscall114 (wait4)");
|
||||
let pid: pid_t = varargs.get(ctx);
|
||||
let status: u32 = varargs.get(ctx);
|
||||
let options: c_int = varargs.get(ctx);
|
||||
let rusage: u32 = varargs.get(ctx);
|
||||
let status_addr = emscripten_memory_pointer!(ctx.memory(0), status) as *mut c_int;
|
||||
let rusage_addr = emscripten_memory_pointer!(ctx.memory(0), rusage) as *mut rusage;
|
||||
let res = unsafe { wait4(pid, status_addr, options, rusage_addr) };
|
||||
debug!(
|
||||
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
|
||||
pid, status_addr, options, rusage_addr, res
|
||||
);
|
||||
res
|
||||
}
|
||||
|
||||
/// uname
|
||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||
pub fn ___syscall122(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall122 (uname) {}", which);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
debug!("=> buf: {}", buf);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut utsname;
|
||||
unsafe { uname(buf_addr) }
|
||||
}
|
||||
|
||||
// select
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall142 (newselect) {}", which);
|
||||
|
||||
let nfds: i32 = varargs.get(ctx);
|
||||
let readfds: u32 = varargs.get(ctx);
|
||||
let writefds: u32 = varargs.get(ctx);
|
||||
let exceptfds: u32 = varargs.get(ctx);
|
||||
let _timeout: i32 = varargs.get(ctx);
|
||||
|
||||
assert!(nfds <= 64, "`nfds` must be less than or equal to 64");
|
||||
assert!(exceptfds == 0, "`exceptfds` is not supporrted");
|
||||
|
||||
let readfds_ptr = emscripten_memory_pointer!(ctx.memory(0), readfds) as _;
|
||||
let writefds_ptr = emscripten_memory_pointer!(ctx.memory(0), writefds) as _;
|
||||
|
||||
unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) }
|
||||
}
|
||||
|
||||
// mmap2
|
||||
pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall192 (mmap2) {}", which);
|
||||
let addr: i32 = varargs.get(ctx);
|
||||
let len: u32 = varargs.get(ctx);
|
||||
let prot: i32 = varargs.get(ctx);
|
||||
let flags: i32 = varargs.get(ctx);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let off: i32 = varargs.get(ctx);
|
||||
debug!(
|
||||
"=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}",
|
||||
addr, len, prot, flags, fd, off
|
||||
);
|
||||
|
||||
if fd == -1 {
|
||||
let ptr = env::call_memalign(16384, len, ctx);
|
||||
if ptr == 0 {
|
||||
return -1;
|
||||
}
|
||||
env::call_memset(ptr, 0, len, ctx);
|
||||
ptr as _
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/// lseek
|
||||
pub fn ___syscall140(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> c_int
|
||||
debug!("emscripten::___syscall140 (lseek) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let offset = varargs.get(ctx);
|
||||
let whence: i32 = varargs.get(ctx);
|
||||
debug!("=> fd: {}, offset: {}, whence = {}", fd, offset, whence);
|
||||
unsafe { lseek(fd, offset, whence) as _ }
|
||||
}
|
||||
|
||||
/// readv
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall145(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall145 (readv) {}", which);
|
||||
// let fd: i32 = varargs.get(ctx);
|
||||
// let iov: u32 = varargs.get(ctx);
|
||||
// let iovcnt: i32 = varargs.get(ctx);
|
||||
// debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
// let iov_addr = emscripten_memory_pointer!(ctx.memory(0), iov) as *mut iovec;
|
||||
// unsafe { readv(fd, iov_addr, iovcnt) }
|
||||
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let iov: i32 = varargs.get(ctx);
|
||||
let iovcnt: i32 = varargs.get(ctx);
|
||||
|
||||
#[repr(C)]
|
||||
struct GuestIovec {
|
||||
iov_base: i32,
|
||||
iov_len: i32,
|
||||
}
|
||||
|
||||
debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
let mut ret = 0;
|
||||
unsafe {
|
||||
for i in 0..iovcnt {
|
||||
let guest_iov_addr =
|
||||
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
|
||||
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
|
||||
as *mut c_void;
|
||||
let iov_len = (*guest_iov_addr).iov_len as _;
|
||||
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
|
||||
let curr = read(fd, iov_base, iov_len);
|
||||
if curr < 0 {
|
||||
return -1;
|
||||
}
|
||||
ret += curr;
|
||||
}
|
||||
// debug!(" => ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
}
|
||||
|
||||
// writev
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall146(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
|
||||
// -> ssize_t
|
||||
debug!("emscripten::___syscall146 (writev) {}", which);
|
||||
let fd: i32 = varargs.get(ctx);
|
||||
let iov: i32 = varargs.get(ctx);
|
||||
let iovcnt: i32 = varargs.get(ctx);
|
||||
|
||||
#[repr(C)]
|
||||
struct GuestIovec {
|
||||
iov_base: i32,
|
||||
iov_len: i32,
|
||||
}
|
||||
|
||||
debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt);
|
||||
let mut ret = 0;
|
||||
unsafe {
|
||||
for i in 0..iovcnt {
|
||||
let guest_iov_addr =
|
||||
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
|
||||
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
|
||||
as *const c_void;
|
||||
let iov_len = (*guest_iov_addr).iov_len as _;
|
||||
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
|
||||
let curr = write(fd, iov_base, iov_len);
|
||||
if curr < 0 {
|
||||
return -1;
|
||||
}
|
||||
ret += curr;
|
||||
}
|
||||
// debug!(" => ret: {}", ret);
|
||||
ret as _
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall168(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall168");
|
||||
-1
|
||||
}
|
||||
|
||||
// pread
|
||||
pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall180 (pread) {}", which);
|
||||
@ -765,192 +501,58 @@ pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
|
||||
status
|
||||
}
|
||||
|
||||
pub fn ___syscall191(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall191 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall194(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall194 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall196(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall194 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall199(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall199 - stub");
|
||||
-1
|
||||
}
|
||||
|
||||
// stat64
|
||||
pub fn ___syscall195(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall195 (stat64) {}", which);
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
|
||||
unsafe {
|
||||
let mut _stat: stat = std::mem::zeroed();
|
||||
let ret = stat(pathname_addr, &mut _stat);
|
||||
debug!("ret: {}", ret);
|
||||
if ret != 0 {
|
||||
return ret;
|
||||
}
|
||||
copy_stat_into_wasm(ctx, buf, &_stat);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
// fstat64
|
||||
pub fn ___syscall197(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall197 (fstat64) {}", which);
|
||||
let fd: c_int = varargs.get(ctx);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
|
||||
unsafe {
|
||||
let mut stat = std::mem::zeroed();
|
||||
let ret = fstat(fd, &mut stat);
|
||||
debug!("ret: {}", ret);
|
||||
if ret != 0 {
|
||||
return ret;
|
||||
}
|
||||
copy_stat_into_wasm(ctx, buf, &stat);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
// getgid
|
||||
pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall201 (getgid)");
|
||||
unsafe {
|
||||
// Maybe fix: Emscripten returns 0 always
|
||||
getgid() as i32
|
||||
}
|
||||
}
|
||||
|
||||
// getgid32
|
||||
pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
// gid_t
|
||||
debug!("emscripten::___syscall202 (getgid32)");
|
||||
unsafe {
|
||||
// Maybe fix: Emscripten returns 0 always
|
||||
getgid() as _
|
||||
}
|
||||
}
|
||||
|
||||
// chown
|
||||
pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall212 (chown) {}", which);
|
||||
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let owner: u32 = varargs.get(ctx);
|
||||
let group: u32 = varargs.get(ctx);
|
||||
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
|
||||
unsafe { chown(pathname_addr, owner, group) }
|
||||
}
|
||||
|
||||
pub fn ___syscall220(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall220");
|
||||
-1
|
||||
}
|
||||
|
||||
// fcntl64
|
||||
pub fn ___syscall221(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall221 (fcntl64) {}", which);
|
||||
// fcntl64
|
||||
let _fd: i32 = varargs.get(ctx);
|
||||
let cmd: u32 = varargs.get(ctx);
|
||||
match cmd {
|
||||
2 => 0,
|
||||
_ => -1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ___syscall268(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall268");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall272(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall272");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall295(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall295");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall300(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall300");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn ___syscall334(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall334");
|
||||
-1
|
||||
}
|
||||
|
||||
/// dup3
|
||||
pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
// Implementation based on description at https://linux.die.net/man/2/dup3
|
||||
debug!("emscripten::___syscall330 (dup3)");
|
||||
let oldfd: c_int = varargs.get(ctx);
|
||||
let newfd: c_int = varargs.get(ctx);
|
||||
let flags: c_int = varargs.get(ctx);
|
||||
|
||||
if oldfd == newfd {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
let res = unsafe { dup2(oldfd, newfd) };
|
||||
|
||||
// Set flags on newfd (https://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html)
|
||||
let mut old_flags = unsafe { fcntl(newfd, F_GETFD, 0) };
|
||||
|
||||
if old_flags > 0 {
|
||||
old_flags |= flags;
|
||||
} else if old_flags == 0 {
|
||||
old_flags &= !flags;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
fcntl(newfd, F_SETFD, old_flags);
|
||||
}
|
||||
|
||||
/// wait4
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
debug!("emscripten::___syscall114 (wait4)");
|
||||
let pid: pid_t = varargs.get(ctx);
|
||||
let status: u32 = varargs.get(ctx);
|
||||
let options: c_int = varargs.get(ctx);
|
||||
let rusage: u32 = varargs.get(ctx);
|
||||
let status_addr = emscripten_memory_pointer!(ctx.memory(0), status) as *mut c_int;
|
||||
let rusage_addr = emscripten_memory_pointer!(ctx.memory(0), rusage) as *mut rusage;
|
||||
let res = unsafe { wait4(pid, status_addr, options, rusage_addr) };
|
||||
debug!(
|
||||
"=> oldfd: {}, newfd: {}, flags: {} = pid: {}",
|
||||
oldfd, newfd, flags, res
|
||||
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
|
||||
pid, status_addr, options, rusage_addr, res
|
||||
);
|
||||
res
|
||||
}
|
||||
|
||||
// prlimit64
|
||||
pub fn ___syscall340(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall340 (prlimit64), {}", which);
|
||||
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
|
||||
let _pid: i32 = varargs.get(ctx);
|
||||
let _resource: i32 = varargs.get(ctx);
|
||||
let _new_limit: u32 = varargs.get(ctx);
|
||||
let old_limit: u32 = varargs.get(ctx);
|
||||
// select
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall142 (newselect) {}", which);
|
||||
|
||||
if old_limit != 0 {
|
||||
// just report no limits
|
||||
let buf_ptr = emscripten_memory_pointer!(ctx.memory(0), old_limit) as *mut u8;
|
||||
let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) };
|
||||
let nfds: i32 = varargs.get(ctx);
|
||||
let readfds: u32 = varargs.get(ctx);
|
||||
let writefds: u32 = varargs.get(ctx);
|
||||
let exceptfds: u32 = varargs.get(ctx);
|
||||
let _timeout: i32 = varargs.get(ctx);
|
||||
|
||||
LittleEndian::write_i32(&mut buf[..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[4..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[8..], -1); // RLIM_INFINITY
|
||||
LittleEndian::write_i32(&mut buf[12..], -1); // RLIM_INFINITY
|
||||
}
|
||||
assert!(nfds <= 64, "`nfds` must be less than or equal to 64");
|
||||
assert!(exceptfds == 0, "`exceptfds` is not supporrted");
|
||||
|
||||
0
|
||||
let readfds_ptr = emscripten_memory_pointer!(ctx.memory(0), readfds) as _;
|
||||
let writefds_ptr = emscripten_memory_pointer!(ctx.memory(0), writefds) as _;
|
||||
|
||||
unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) }
|
||||
}
|
||||
|
||||
// setpgid
|
||||
pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall57 (setpgid) {}", which);
|
||||
let pid: i32 = varargs.get(ctx);
|
||||
let pgid: i32 = varargs.get(ctx);
|
||||
unsafe { setpgid(pid, pgid) }
|
||||
}
|
||||
|
||||
/// uname
|
||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||
pub fn ___syscall122(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall122 (uname) {}", which);
|
||||
let buf: u32 = varargs.get(ctx);
|
||||
debug!("=> buf: {}", buf);
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut utsname;
|
||||
unsafe { uname(buf_addr) }
|
||||
}
|
92
lib/emscripten/src/syscalls/windows.rs
Normal file
92
lib/emscripten/src/syscalls/windows.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use crate::varargs::VarArgs;
|
||||
use libc::mkdir;
|
||||
use std::os::raw::c_int;
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
type pid_t = c_int;
|
||||
|
||||
// chown
|
||||
pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall212 (chown) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
// mkdir
|
||||
pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall39 (mkdir) {}", which);
|
||||
let pathname: u32 = varargs.get(ctx);
|
||||
let mode: u32 = varargs.get(ctx);
|
||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
||||
unsafe { mkdir(pathname_addr) }
|
||||
}
|
||||
|
||||
// getgid
|
||||
pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
debug!("emscripten::___syscall201 (getgid)");
|
||||
-1
|
||||
}
|
||||
|
||||
// getgid32
|
||||
pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
|
||||
// gid_t
|
||||
debug!("emscripten::___syscall202 (getgid32)");
|
||||
-1
|
||||
}
|
||||
|
||||
/// dup3
|
||||
pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
debug!("emscripten::___syscall330 (dup3)");
|
||||
-1
|
||||
}
|
||||
|
||||
/// ioctl
|
||||
pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall54 (ioctl) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
// socketcall
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall102 (socketcall) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
// pread
|
||||
pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall180 (pread) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
// pwrite
|
||||
pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall181 (pwrite) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
/// wait4
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t {
|
||||
debug!("emscripten::___syscall114 (wait4)");
|
||||
-1
|
||||
}
|
||||
|
||||
// select
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall142 (newselect) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
// setpgid
|
||||
pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall57 (setpgid) {}", which);
|
||||
-1
|
||||
}
|
||||
|
||||
/// uname
|
||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||
pub fn ___syscall122(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
|
||||
debug!("emscripten::___syscall122 (uname) {}", which);
|
||||
-1
|
||||
}
|
Loading…
Reference in New Issue
Block a user