Port to FreeBSD

This commit is contained in:
MikaelUrankar
2019-11-24 20:08:54 +01:00
parent 589a99452c
commit fcbdada259
12 changed files with 509 additions and 12 deletions

View File

@ -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() {}

View File

@ -141,6 +141,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 +317,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"),

View File

@ -130,7 +130,19 @@ extern "C" {
pub fn lstat64(path: *const libc::c_char, buf: *mut c_void) -> c_int;
}
#[cfg(not(target_os = "macos"))]
// Linking to functions that are not provided by rust libc
#[cfg(target_os = "freebsd")]
#[link(name = "c")]
extern "C" {
pub fn wait4(pid: pid_t, status: *mut c_int, options: c_int, rusage: *mut rusage) -> pid_t;
pub fn fdatasync(fd: c_int) -> c_int;
pub fn ftruncate(fd: c_int, length: i64) -> c_int;
pub fn lstat(path: *const libc::c_char, buf: *mut stat) -> c_int;
}
#[cfg(target_os = "freebsd")]
use libc::madvise;
#[cfg(not(any(target_os = "freebsd", target_os = "macos")))]
use libc::{fallocate, fdatasync, ftruncate64, lstat, madvise, wait4};
// Another conditional constant for name resolution: Macos et iOS use
@ -255,10 +267,14 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
debug!("emscripten::___syscall194 (ftruncate64) {}", _which);
let _fd: c_int = varargs.get(ctx);
let _length: i64 = varargs.get(ctx);
#[cfg(not(target_os = "macos"))]
#[cfg(not(any(target_os = "freebsd", target_os = "macos")))]
unsafe {
ftruncate64(_fd, _length)
}
#[cfg(target_os = "freebsd")]
unsafe {
ftruncate(_fd, _length)
}
#[cfg(target_os = "macos")]
unimplemented!("emscripten::___syscall194 (ftruncate64) {}", _which)
}
@ -621,7 +637,7 @@ pub fn ___syscall102(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let mut host_address: sockaddr = sockaddr {
sa_family: Default::default(),
sa_data: Default::default(),
#[cfg(target_os = "macos")]
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
sa_len: Default::default(),
};
let fd = unsafe { accept(socket, &mut host_address, address_len_addr) };
@ -655,7 +671,7 @@ pub fn ___syscall102(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let mut sock_addr_host: sockaddr = sockaddr {
sa_family: Default::default(),
sa_data: Default::default(),
#[cfg(target_os = "macos")]
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
sa_len: Default::default(),
};
let ret = unsafe {
@ -1056,8 +1072,17 @@ pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
break;
}
#[allow(clippy::cast_ptr_alignment)]
#[cfg(not(target_os = "freebsd"))]
unsafe {
*(dirp.add(pos) as *mut u32) = (*dirent).d_ino as u32;
}
#[allow(clippy::cast_ptr_alignment)]
#[cfg(target_os = "freebsd")]
unsafe {
*(dirp.add(pos) as *mut u32) = (*dirent).d_fileno as u32;
}
#[allow(clippy::cast_ptr_alignment)]
unsafe {
*(dirp.add(pos + 4) as *mut u32) = pos as u32;
*(dirp.add(pos + 8) as *mut u16) = offset as u16;
*(dirp.add(pos + 10) as *mut u8) = (*dirent).d_type;
@ -1106,11 +1131,11 @@ pub fn ___syscall324(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let _mode: c_int = varargs.get(ctx);
let _offset: off_t = varargs.get(ctx);
let _len: off_t = varargs.get(ctx);
#[cfg(not(target_os = "macos"))]
#[cfg(not(any(target_os = "freebsd", target_os = "macos")))]
unsafe {
fallocate(_fd, _mode, _offset, _len)
}
#[cfg(target_os = "macos")]
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
{
unimplemented!("emscripten::___syscall324 (fallocate) {}", _which)
}

View File

@ -31,6 +31,11 @@ use wasmer_runtime_core::vm::Ctx;
#[cfg(target_os = "linux")]
use libc::{CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_REALTIME};
#[cfg(target_os = "freebsd")]
use libc::{CLOCK_MONOTONIC, CLOCK_REALTIME};
#[cfg(target_os = "freebsd")]
const CLOCK_MONOTONIC_COARSE: clockid_t = 6;
#[cfg(target_os = "macos")]
use libc::CLOCK_REALTIME;
#[cfg(target_os = "macos")]

View File

@ -58,6 +58,7 @@ lazy_static! {
"llvm-config".into(),
format!("llvm-config-{}", CRATE_VERSION.major),
format!("llvm-config-{}.{}", CRATE_VERSION.major, CRATE_VERSION.minor),
format!("llvm-config{}{}", CRATE_VERSION.major, CRATE_VERSION.minor),
]
};

View File

@ -206,7 +206,10 @@ impl LLVMBackend {
let buffer = Arc::new(Buffer::LlvmMemory(memory_buffer));
#[cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))]
#[cfg(all(
any(target_os = "freebsd", target_os = "linux", target_os = "macos"),
target_arch = "x86_64"
))]
{
use super::stackmap::{self, StkMapRecord, StkSizeRecord};
use std::collections::BTreeMap;

View File

@ -53,7 +53,10 @@ pub enum StackmapEntryKind {
}
impl StackmapEntry {
#[cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))]
#[cfg(all(
any(target_os = "freebsd", target_os = "linux", target_os = "macos"),
target_arch = "x86_64"
))]
pub fn populate_msm(
&self,
module_info: &ModuleInfo,

View File

@ -32,6 +32,11 @@ fn main() {
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
match (target_os.as_str(), target_arch.as_str()) {
("freebsd", "x86_64") => {
cc::Build::new()
.file("image-loading-freebsd-x86-64.s")
.compile("image-loading");
}
("linux", "x86_64") => {
cc::Build::new()
.file("image-loading-linux-x86-64.s")

View File

@ -0,0 +1,127 @@
# NOTE: Keep this consistent with `fault.rs`.
.globl run_on_alternative_stack
run_on_alternative_stack:
# (stack_end, stack_begin)
# We need to ensure 16-byte alignment here.
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rbp
movq %rsp, -16(%rdi)
leaq run_on_alternative_stack.returning(%rip), %rax
movq %rax, -24(%rdi)
movq %rsi, %rsp
movq (%rsp), %xmm0
add $8, %rsp
movq (%rsp), %xmm1
add $8, %rsp
movq (%rsp), %xmm2
add $8, %rsp
movq (%rsp), %xmm3
add $8, %rsp
movq (%rsp), %xmm4
add $8, %rsp
movq (%rsp), %xmm5
add $8, %rsp
movq (%rsp), %xmm6
add $8, %rsp
movq (%rsp), %xmm7
add $8, %rsp
movq (%rsp), %xmm8
add $8, %rsp
movq (%rsp), %xmm9
add $8, %rsp
movq (%rsp), %xmm10
add $8, %rsp
movq (%rsp), %xmm11
add $8, %rsp
movq (%rsp), %xmm12
add $8, %rsp
movq (%rsp), %xmm13
add $8, %rsp
movq (%rsp), %xmm14
add $8, %rsp
movq (%rsp), %xmm15
add $8, %rsp
popq %rbp
popq %rax
popq %rbx
popq %rcx
popq %rdx
popq %rdi
popq %rsi
popq %r8
popq %r9
popq %r10
popq %r11
popq %r12
popq %r13
popq %r14
popq %r15
retq
run_on_alternative_stack.returning:
movq (%rsp), %rsp
popq %rbp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
# For switching into a backend without information about where registers are preserved.
.globl register_preservation_trampoline
register_preservation_trampoline:
subq $8, %rsp
pushq %rax
pushq %rcx
pushq %rdx
pushq %rdi
pushq %rsi
pushq %r8
pushq %r9
pushq %r10
callq get_boundary_register_preservation@PLT
# Keep this consistent with BoundaryRegisterPreservation
movq %r15, 0(%rax)
movq %r14, 8(%rax)
movq %r13, 16(%rax)
movq %r12, 24(%rax)
movq %rbx, 32(%rax)
popq %r10
popq %r9
popq %r8
popq %rsi
popq %rdi
popq %rdx
popq %rcx
popq %rax
addq $8, %rsp
jmpq *%rax

View File

@ -500,6 +500,249 @@ impl FaultInfo {
}
}
#[cfg(all(target_os = "freebsd", target_arch = "aarch64"))]
/// Get fault info from siginfo and ucontext.
pub unsafe fn get_fault_info(siginfo: *const c_void, ucontext: *mut c_void) -> FaultInfo {
#[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 gpregs {
gp_x: [u64; 30],
gp_lr: u64,
gp_sp: u64,
gp_elr: u64,
gp_spsr: u64,
gp_pad: i32,
};
#[repr(C)]
pub struct fpregs {
fp_q: [u128; 32],
fp_sr: u32,
fp_cr: u32,
fp_flags: i32,
fp_pad: i32,
};
#[repr(C)]
pub struct mcontext_t {
mc_gpregs: gpregs,
mc_fpregs: fpregs,
mc_flags: i32,
mc_pad: i32,
mc_spare: [u64; 8],
}
let siginfo = siginfo as *const siginfo_t;
let si_addr = (*siginfo).si_addr;
let ucontext = ucontext as *mut ucontext_t;
let gregs = &(*ucontext).uc_mcontext.mc_gpregs;
let mut known_registers: [Option<u64>; 32] = [None; 32];
known_registers[X64Register::GPR(GPR::R15).to_index().0] = Some(gregs.gp_x[15] as _);
known_registers[X64Register::GPR(GPR::R14).to_index().0] = Some(gregs.gp_x[14] as _);
known_registers[X64Register::GPR(GPR::R13).to_index().0] = Some(gregs.gp_x[13] as _);
known_registers[X64Register::GPR(GPR::R12).to_index().0] = Some(gregs.gp_x[12] as _);
known_registers[X64Register::GPR(GPR::R11).to_index().0] = Some(gregs.gp_x[11] as _);
known_registers[X64Register::GPR(GPR::R10).to_index().0] = Some(gregs.gp_x[10] as _);
known_registers[X64Register::GPR(GPR::R9).to_index().0] = Some(gregs.gp_x[9] as _);
known_registers[X64Register::GPR(GPR::R8).to_index().0] = Some(gregs.gp_x[8] as _);
known_registers[X64Register::GPR(GPR::RSI).to_index().0] = Some(gregs.gp_x[6] as _);
known_registers[X64Register::GPR(GPR::RDI).to_index().0] = Some(gregs.gp_x[7] as _);
known_registers[X64Register::GPR(GPR::RDX).to_index().0] = Some(gregs.gp_x[2] as _);
known_registers[X64Register::GPR(GPR::RCX).to_index().0] = Some(gregs.gp_x[1] as _);
known_registers[X64Register::GPR(GPR::RBX).to_index().0] = Some(gregs.gp_x[3] as _);
known_registers[X64Register::GPR(GPR::RAX).to_index().0] = Some(gregs.gp_x[0] as _);
known_registers[X64Register::GPR(GPR::RBP).to_index().0] = Some(gregs.gp_x[5] as _);
known_registers[X64Register::GPR(GPR::RSP).to_index().0] = Some(gregs.gp_x[28] as _);
FaultInfo {
faulting_addr: si_addr as usize as _,
ip: std::mem::transmute::<&mut u64, &'static Cell<usize>>(
&mut (*ucontext).uc_mcontext.mc_gpregs.gp_elr,
),
known_registers,
}
}
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
/// Get fault info from siginfo and ucontext.
pub unsafe fn get_fault_info(siginfo: *const c_void, ucontext: *mut c_void) -> FaultInfo {
use crate::state::x64::XMM;
#[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_savefpu: *const savefpu,
mc_fpstate: [i64; 63], // 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],
}
#[repr(C)]
pub struct xmmacc {
element: [u32; 4],
}
#[repr(C)]
pub struct __envxmm64 {
en_cw: u16,
en_sw: u16,
en_tw: u8,
en_zero: u8,
en_opcode: u16,
en_rip: u64,
en_rdp: u64,
en_mxcsr: u32,
en_mxcsr_mask: u32,
}
#[repr(C)]
pub struct fpacc87 {
fp_bytes: [u8; 10],
}
#[repr(C)]
pub struct sv_fp {
fp_acc: fpacc87,
fp_pad: [u8; 6],
}
#[repr(C, align(16))]
pub struct savefpu {
sv_env: __envxmm64,
sv_fp_t: [sv_fp; 8],
sv_xmm: [xmmacc; 16],
sv_pad: [u8; 96],
}
let siginfo = siginfo as *const siginfo_t;
let si_addr = (*siginfo).si_addr;
let ucontext = ucontext as *mut ucontext_t;
let gregs = &mut (*ucontext).uc_mcontext;
fn read_xmm(reg: &xmmacc) -> u64 {
(reg.element[0] as u64) | ((reg.element[1] as u64) << 32)
}
let mut known_registers: [Option<u64>; 32] = [None; 32];
known_registers[X64Register::GPR(GPR::R15).to_index().0] = Some(gregs.mc_r15);
known_registers[X64Register::GPR(GPR::R14).to_index().0] = Some(gregs.mc_r14);
known_registers[X64Register::GPR(GPR::R13).to_index().0] = Some(gregs.mc_r13);
known_registers[X64Register::GPR(GPR::R12).to_index().0] = Some(gregs.mc_r12);
known_registers[X64Register::GPR(GPR::R11).to_index().0] = Some(gregs.mc_r11);
known_registers[X64Register::GPR(GPR::R10).to_index().0] = Some(gregs.mc_r10);
known_registers[X64Register::GPR(GPR::R9).to_index().0] = Some(gregs.mc_r9);
known_registers[X64Register::GPR(GPR::R8).to_index().0] = Some(gregs.mc_r8);
known_registers[X64Register::GPR(GPR::RSI).to_index().0] = Some(gregs.mc_rsi);
known_registers[X64Register::GPR(GPR::RDI).to_index().0] = Some(gregs.mc_rdi);
known_registers[X64Register::GPR(GPR::RDX).to_index().0] = Some(gregs.mc_rdx);
known_registers[X64Register::GPR(GPR::RCX).to_index().0] = Some(gregs.mc_rcx);
known_registers[X64Register::GPR(GPR::RBX).to_index().0] = Some(gregs.mc_rbx);
known_registers[X64Register::GPR(GPR::RAX).to_index().0] = Some(gregs.mc_rax);
known_registers[X64Register::GPR(GPR::RBP).to_index().0] = Some(gregs.mc_rbp);
known_registers[X64Register::GPR(GPR::RSP).to_index().0] = Some(gregs.mc_rsp);
// https://lists.freebsd.org/pipermail/freebsd-arch/2011-December/012077.html
// https://people.freebsd.org/~kib/misc/defer_sig.c
const _MC_HASFPXSTATE: u32 = 0x4;
if (gregs.mc_flags & _MC_HASFPXSTATE) == 0 {
// XXX mc_fpstate[0] is actually a pointer to a struct savefpu
let fpregs = &*(*ucontext).uc_mcontext.mc_savefpu;
known_registers[X64Register::XMM(XMM::XMM0).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[0]));
known_registers[X64Register::XMM(XMM::XMM1).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[1]));
known_registers[X64Register::XMM(XMM::XMM2).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[2]));
known_registers[X64Register::XMM(XMM::XMM3).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[3]));
known_registers[X64Register::XMM(XMM::XMM4).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[4]));
known_registers[X64Register::XMM(XMM::XMM5).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[5]));
known_registers[X64Register::XMM(XMM::XMM6).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[6]));
known_registers[X64Register::XMM(XMM::XMM7).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[7]));
known_registers[X64Register::XMM(XMM::XMM8).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[8]));
known_registers[X64Register::XMM(XMM::XMM9).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[9]));
known_registers[X64Register::XMM(XMM::XMM10).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[10]));
known_registers[X64Register::XMM(XMM::XMM11).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[11]));
known_registers[X64Register::XMM(XMM::XMM12).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[12]));
known_registers[X64Register::XMM(XMM::XMM13).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[13]));
known_registers[X64Register::XMM(XMM::XMM14).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[14]));
known_registers[X64Register::XMM(XMM::XMM15).to_index().0] =
Some(read_xmm(&fpregs.sv_xmm[15]));
}
FaultInfo {
faulting_addr: si_addr,
ip: std::mem::transmute::<&mut u64, &'static Cell<usize>>(
&mut (*ucontext).uc_mcontext.mc_rip,
),
known_registers,
}
}
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
/// Get fault info from siginfo and ucontext.
pub unsafe fn get_fault_info(siginfo: *const c_void, ucontext: *mut c_void) -> FaultInfo {

View File

@ -12,11 +12,13 @@
#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
#[cfg(not(any(
all(target_os = "freebsd", target_arch = "x86_64"),
all(target_os = "freebsd", target_arch = "aarch64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "aarch64"),
)))]
compile_error!("This crate doesn't yet support compiling on operating systems other than linux and macos and architectures other than x86_64");
compile_error!("This crate doesn't yet support compiling on operating systems other than FreeBSD, linux and macos and architectures other than x86_64");
extern crate dynasmrt;

View File

@ -1,6 +1,6 @@
#![allow(unused, clippy::too_many_arguments)]
pub mod types;
#[cfg(any(target_os = "linux", target_os = "macos"))]
#[cfg(any(target_os = "freebsd", target_os = "linux", target_os = "macos"))]
pub mod unix;
#[cfg(any(target_os = "windows"))]
pub mod windows;
@ -23,7 +23,7 @@ use std::convert::{Infallible, TryInto};
use std::io::{self, Read, Seek, Write};
use wasmer_runtime_core::{memory::Memory, vm::Ctx};
#[cfg(any(target_os = "linux", target_os = "macos"))]
#[cfg(any(target_os = "freebsd", target_os = "linux", target_os = "macos"))]
pub use unix::*;
#[cfg(any(target_os = "windows"))]