mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 05:01:33 +00:00
Port to FreeBSD
This commit is contained in:
@ -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() {}
|
||||
|
@ -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"),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")]
|
||||
|
@ -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),
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
|
127
lib/runtime-core/image-loading-freebsd-x86-64.s
Normal file
127
lib/runtime-core/image-loading-freebsd-x86-64.s
Normal 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
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"))]
|
||||
|
Reference in New Issue
Block a user