Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
1120: Port to FreeBSD r=MarkMcCaskey a=syrusakbary

<!-- 
Prior to submitting a PR, review the CONTRIBUTING.md document for recommendations on how to test:
https://github.com/wasmerio/wasmer/blob/master/CONTRIBUTING.md#pull-requests

-->

# Description

I disovered this great patch today: https://github.com/MikaelUrankar/webasm/blob/master/www/wasmer/files/patch-freebsd

And then realized that @MikaelUrankar forked wasmer to add support for FreeBSD.

I'm creating this PR to follow up on that fork and merge the changes upstream.

@MikaelUrankar let us know if everything is good to go with this PR!

<!-- 
Provide details regarding the change including motivation,
links to related issues, and the context of the PR.
-->

# Review

- [ ] Add a short description of the the change to the CHANGELOG.md file


Co-authored-by: MikaelUrankar <[email protected]>
  • Loading branch information
bors[bot] and MikaelUrankar authored Jan 28, 2020
2 parents 589a994 + fcbdada commit c5d033e
Show file tree
Hide file tree
Showing 12 changed files with 509 additions and 12 deletions.
5 changes: 4 additions & 1 deletion lib/clif-backend/src/libcalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
80 changes: 80 additions & 0 deletions lib/clif-backend/src/signal/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"),
Expand Down
37 changes: 31 additions & 6 deletions lib/emscripten/src/syscalls/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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) };
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
Expand Down
5 changes: 5 additions & 0 deletions lib/emscripten/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
1 change: 1 addition & 0 deletions lib/llvm-backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
]
};

Expand Down
5 changes: 4 additions & 1 deletion lib/llvm-backend/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion lib/llvm-backend/src/stackmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions lib/runtime-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
127 changes: 127 additions & 0 deletions lib/runtime-core/image-loading-freebsd-x86-64.s
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit c5d033e

Please sign in to comment.