mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-15 18:01:22 +00:00
First working version of LLVM in Windows
This commit is contained in:
@ -21,21 +21,20 @@ cache:
|
|||||||
- wapm-cli-target
|
- wapm-cli-target
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# # Install LLVM
|
# Install LLVM
|
||||||
# - mkdir C:\projects\deps
|
- mkdir C:\projects\deps
|
||||||
# - cd C:\projects\deps
|
- cd C:\projects\deps
|
||||||
# - appveyor DownloadFile https://prereleases.llvm.org/win-snapshots/LLVM-8.0.0-r351033-win64.exe -FileName llvm.exe
|
- appveyor DownloadFile https://github.com/wasmerio/windows-llvm-build/releases/download/v8.0.0/llvm-8.0.0-install.zip -FileName llvm-8.0.0-install.zip
|
||||||
# - 7z x llvm.exe -oC:\projects\deps\llvm
|
- 7z x llvm-8.0.0-install.zip
|
||||||
# # - set "PATH=%PATH%;C:\projects\deps\llvm\bin"
|
- C:\projects\deps\llvm-8.0.0-install\bin\llvm-config.exe --version
|
||||||
# - set "LLD_LINK=C:\projects\deps\llvm\bin\lld-link.exe"
|
- set "LLVM_SYS_80_PREFIX=C:\projects\deps\llvm-8.0.0-install"
|
||||||
# - set "LLVM_SYS_80_PREFIX=C:\projects\deps\llvm"
|
- cd "%APPVEYOR_BUILD_FOLDER%"
|
||||||
# - cd "%APPVEYOR_BUILD_FOLDER%"
|
|
||||||
|
|
||||||
# Install Rust
|
# Install Rust
|
||||||
# uncomment these lines if the cache is cleared, or if we must re-install rust for some reason
|
# uncomment these lines if the cache is cleared, or if we must re-install rust for some reason
|
||||||
# - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
# - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||||
# - rustup-init.exe -yv --default-host %target%
|
# - rustup-init.exe -yv --default-host %target%
|
||||||
- set PATH=%PATH%;C:\\Libraries\\llvm-5.0.0\\bin;%USERPROFILE%\.cargo\bin
|
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||||
- rustup default stable-%target%
|
- rustup default stable-%target%
|
||||||
- rustup update
|
- rustup update
|
||||||
- rustc -vV
|
- rustc -vV
|
||||||
|
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -565,19 +565,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell"
|
name = "inkwell"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#f1775622b6d88fd30006b377042726854c9e0193"
|
source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#4c5359e507b8a3439c9e2c7fff5c336224069638"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
|
"inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
|
||||||
"libc 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell_internal_macros"
|
name = "inkwell_internal_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#f1775622b6d88fd30006b377042726854c9e0193"
|
source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#4c5359e507b8a3439c9e2c7fff5c336224069638"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1522,6 +1523,7 @@ dependencies = [
|
|||||||
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.5.7",
|
"wasmer-runtime-core 0.5.7",
|
||||||
"wasmparser 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-llvm-backend"
|
name = "wasmer-llvm-backend"
|
||||||
version = "0.5.7"
|
version = "0.5.7"
|
||||||
authors = ["Lachlan Sneff <lachlan.sneff@gmail.com>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.5.7" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.5.7" }
|
||||||
inkwell = { git = "https://github.com/wasmerio/inkwell", branch = "llvm8-0", features = ["llvm8-0"] }
|
|
||||||
wasmparser = "0.34.0"
|
wasmparser = "0.34.0"
|
||||||
hashbrown = "0.1.8"
|
hashbrown = "0.1.8"
|
||||||
smallvec = "0.6.8"
|
smallvec = "0.6.8"
|
||||||
@ -16,6 +15,15 @@ libc = "0.2.49"
|
|||||||
nix = "0.14.0"
|
nix = "0.14.0"
|
||||||
capstone = { version = "0.5.0", optional = true }
|
capstone = { version = "0.5.0", optional = true }
|
||||||
|
|
||||||
|
[dependencies.inkwell]
|
||||||
|
git = "https://github.com/wasmerio/inkwell"
|
||||||
|
branch = "llvm8-0"
|
||||||
|
default-features = false
|
||||||
|
features = ["llvm8-0", "target-x86"]
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0"
|
cc = "1.0"
|
||||||
lazy_static = "1.2.0"
|
lazy_static = "1.2.0"
|
||||||
|
@ -75,16 +75,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void registerEHFrames(uint8_t* addr, uint64_t LoadAddr, size_t size) override {
|
virtual void registerEHFrames(uint8_t* addr, uint64_t LoadAddr, size_t size) override {
|
||||||
eh_frame_ptr = addr;
|
/* eh_frame_ptr = addr;
|
||||||
eh_frame_size = size;
|
eh_frame_size = size;
|
||||||
eh_frames_registered = true;
|
eh_frames_registered = true;
|
||||||
callbacks.visit_fde(addr, size, __register_frame);
|
callbacks.visit_fde(addr, size, __register_frame);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void deregisterEHFrames() override {
|
virtual void deregisterEHFrames() override {
|
||||||
if (eh_frames_registered) {
|
/* if (eh_frames_registered) {
|
||||||
callbacks.visit_fde(eh_frame_ptr, eh_frame_size, __deregister_frame);
|
callbacks.visit_fde(eh_frame_ptr, eh_frame_size, __deregister_frame);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override {
|
virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override {
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
use crate::intrinsics::Intrinsics;
|
use crate::intrinsics::Intrinsics;
|
||||||
|
use crate::structs::{Callbacks, LLVMModule, LLVMResult, MemProtect};
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
memory_buffer::MemoryBuffer,
|
memory_buffer::MemoryBuffer,
|
||||||
module::Module,
|
module::Module,
|
||||||
targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine},
|
targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine},
|
||||||
OptimizationLevel,
|
OptimizationLevel,
|
||||||
};
|
};
|
||||||
use libc::{
|
use libc::c_char;
|
||||||
c_char, mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_NONE, PROT_READ,
|
|
||||||
PROT_WRITE,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
ffi::{c_void, CString},
|
ffi::{c_void, CString},
|
||||||
@ -31,42 +29,6 @@ use wasmer_runtime_core::{
|
|||||||
vm, vmcalls,
|
vm, vmcalls,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct LLVMModule {
|
|
||||||
_private: [u8; 0],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
#[repr(C)]
|
|
||||||
enum MemProtect {
|
|
||||||
NONE,
|
|
||||||
READ,
|
|
||||||
READ_WRITE,
|
|
||||||
READ_EXECUTE,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
#[repr(C)]
|
|
||||||
enum LLVMResult {
|
|
||||||
OK,
|
|
||||||
ALLOCATE_FAILURE,
|
|
||||||
PROTECT_FAILURE,
|
|
||||||
DEALLOC_FAILURE,
|
|
||||||
OBJECT_LOAD_FAILURE,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct Callbacks {
|
|
||||||
alloc_memory: extern "C" fn(usize, MemProtect, &mut *mut u8, &mut usize) -> LLVMResult,
|
|
||||||
protect_memory: extern "C" fn(*mut u8, usize, MemProtect) -> LLVMResult,
|
|
||||||
dealloc_memory: extern "C" fn(*mut u8, usize) -> LLVMResult,
|
|
||||||
|
|
||||||
lookup_vm_symbol: extern "C" fn(*const c_char, usize) -> *const vm::Func,
|
|
||||||
visit_fde: extern "C" fn(*mut u8, usize, extern "C" fn(*mut u8)),
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn module_load(
|
fn module_load(
|
||||||
mem_ptr: *const u8,
|
mem_ptr: *const u8,
|
||||||
@ -99,69 +61,21 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_callbacks() -> Callbacks {
|
fn get_callbacks() -> Callbacks {
|
||||||
fn round_up_to_page_size(size: usize) -> usize {
|
|
||||||
(size + (4096 - 1)) & !(4096 - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn alloc_memory(
|
extern "C" fn alloc_memory(
|
||||||
size: usize,
|
size: usize,
|
||||||
protect: MemProtect,
|
protect: MemProtect,
|
||||||
ptr_out: &mut *mut u8,
|
ptr_out: &mut *mut u8,
|
||||||
size_out: &mut usize,
|
size_out: &mut usize,
|
||||||
) -> LLVMResult {
|
) -> LLVMResult {
|
||||||
let size = round_up_to_page_size(size);
|
unsafe { crate::platform::alloc_memory(size, protect, ptr_out, size_out) }
|
||||||
let ptr = unsafe {
|
|
||||||
mmap(
|
|
||||||
ptr::null_mut(),
|
|
||||||
size,
|
|
||||||
match protect {
|
|
||||||
MemProtect::NONE => PROT_NONE,
|
|
||||||
MemProtect::READ => PROT_READ,
|
|
||||||
MemProtect::READ_WRITE => PROT_READ | PROT_WRITE,
|
|
||||||
MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC,
|
|
||||||
},
|
|
||||||
MAP_PRIVATE | MAP_ANON,
|
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if ptr as isize == -1 {
|
|
||||||
return LLVMResult::ALLOCATE_FAILURE;
|
|
||||||
}
|
|
||||||
*ptr_out = ptr as _;
|
|
||||||
*size_out = size;
|
|
||||||
LLVMResult::OK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult {
|
extern "C" fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult {
|
||||||
let res = unsafe {
|
unsafe { crate::platform::protect_memory(ptr, size, protect) }
|
||||||
mprotect(
|
|
||||||
ptr as _,
|
|
||||||
round_up_to_page_size(size),
|
|
||||||
match protect {
|
|
||||||
MemProtect::NONE => PROT_NONE,
|
|
||||||
MemProtect::READ => PROT_READ,
|
|
||||||
MemProtect::READ_WRITE => PROT_READ | PROT_WRITE,
|
|
||||||
MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if res == 0 {
|
|
||||||
LLVMResult::OK
|
|
||||||
} else {
|
|
||||||
LLVMResult::PROTECT_FAILURE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult {
|
extern "C" fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult {
|
||||||
let res = unsafe { munmap(ptr as _, round_up_to_page_size(size)) };
|
unsafe { crate::platform::dealloc_memory(ptr, size) }
|
||||||
|
|
||||||
if res == 0 {
|
|
||||||
LLVMResult::OK
|
|
||||||
} else {
|
|
||||||
LLVMResult::DEALLOC_FAILURE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn lookup_vm_symbol(name_ptr: *const c_char, length: usize) -> *const vm::Func {
|
extern "C" fn lookup_vm_symbol(name_ptr: *const c_char, length: usize) -> *const vm::Func {
|
||||||
|
@ -7,6 +7,7 @@ mod intrinsics;
|
|||||||
mod platform;
|
mod platform;
|
||||||
mod read_info;
|
mod read_info;
|
||||||
mod state;
|
mod state;
|
||||||
|
mod structs;
|
||||||
mod trampolines;
|
mod trampolines;
|
||||||
|
|
||||||
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
|
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
|
||||||
|
3
lib/llvm-backend/src/platform/common.rs
Normal file
3
lib/llvm-backend/src/platform/common.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub fn round_up_to_page_size(size: usize) -> usize {
|
||||||
|
(size + (4096 - 1)) & !(4096 - 1)
|
||||||
|
}
|
@ -1,7 +1,14 @@
|
|||||||
|
mod common;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
mod unix;
|
mod unix;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub use self::unix::*;
|
pub use self::unix::*;
|
||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
compile_error!("windows not yet supported for the llvm-based compiler backend");
|
mod win;
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
pub use self::win::*;
|
||||||
|
|
||||||
|
#[cfg(not(any(unix, target_family = "windows")))]
|
||||||
|
compile_error!("Your system is not yet supported for the llvm-based compiler backend");
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
use super::common::round_up_to_page_size;
|
||||||
|
use crate::structs::{LLVMResult, MemProtect};
|
||||||
|
use libc::{
|
||||||
|
c_char, mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_NONE, PROT_READ,
|
||||||
|
PROT_WRITE,
|
||||||
|
};
|
||||||
use libc::{c_void, siginfo_t};
|
use libc::{c_void, siginfo_t};
|
||||||
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGSEGV};
|
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGSEGV};
|
||||||
|
|
||||||
@ -68,3 +74,60 @@ extern "C" fn signal_trap_handler(
|
|||||||
throw_trap(2);
|
throw_trap(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn alloc_memory(
|
||||||
|
size: usize,
|
||||||
|
protect: MemProtect,
|
||||||
|
ptr_out: &mut *mut u8,
|
||||||
|
size_out: &mut usize,
|
||||||
|
) -> LLVMResult {
|
||||||
|
let size = round_up_to_page_size(size);
|
||||||
|
let ptr = mmap(
|
||||||
|
ptr::null_mut(),
|
||||||
|
size,
|
||||||
|
match protect {
|
||||||
|
MemProtect::NONE => PROT_NONE,
|
||||||
|
MemProtect::READ => PROT_READ,
|
||||||
|
MemProtect::READ_WRITE => PROT_READ | PROT_WRITE,
|
||||||
|
MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC,
|
||||||
|
},
|
||||||
|
MAP_PRIVATE | MAP_ANON,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
if ptr as isize == -1 {
|
||||||
|
return LLVMResult::ALLOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
*ptr_out = ptr as _;
|
||||||
|
*size_out = size;
|
||||||
|
LLVMResult::OK
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult {
|
||||||
|
let res = mprotect(
|
||||||
|
ptr as _,
|
||||||
|
round_up_to_page_size(size),
|
||||||
|
match protect {
|
||||||
|
MemProtect::NONE => PROT_NONE,
|
||||||
|
MemProtect::READ => PROT_READ,
|
||||||
|
MemProtect::READ_WRITE => PROT_READ | PROT_WRITE,
|
||||||
|
MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if res == 0 {
|
||||||
|
LLVMResult::OK
|
||||||
|
} else {
|
||||||
|
LLVMResult::PROTECT_FAILURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult {
|
||||||
|
let res = munmap(ptr as _, round_up_to_page_size(size));
|
||||||
|
|
||||||
|
if res == 0 {
|
||||||
|
LLVMResult::OK
|
||||||
|
} else {
|
||||||
|
LLVMResult::DEALLOC_FAILURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
80
lib/llvm-backend/src/platform/win.rs
Normal file
80
lib/llvm-backend/src/platform/win.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
use super::common::round_up_to_page_size;
|
||||||
|
use crate::structs::{LLVMResult, MemProtect};
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use winapi::um::memoryapi::{VirtualAlloc, VirtualFree};
|
||||||
|
use winapi::um::winnt::{
|
||||||
|
MEM_COMMIT, MEM_DECOMMIT, MEM_RESERVE, PAGE_EXECUTE_READ, PAGE_NOACCESS, PAGE_READONLY,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub unsafe fn visit_fde(_addr: *mut u8, _size: usize, _visitor: extern "C" fn(*mut u8)) {
|
||||||
|
// Do nothing on Windows
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn install_signal_handler() {
|
||||||
|
// Do nothing on Windows
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn alloc_memory(
|
||||||
|
size: usize,
|
||||||
|
protect: MemProtect,
|
||||||
|
ptr_out: &mut *mut u8,
|
||||||
|
size_out: &mut usize,
|
||||||
|
) -> LLVMResult {
|
||||||
|
let size = round_up_to_page_size(size);
|
||||||
|
let flags = if protect == MemProtect::NONE {
|
||||||
|
MEM_RESERVE
|
||||||
|
} else {
|
||||||
|
MEM_RESERVE | MEM_COMMIT
|
||||||
|
};
|
||||||
|
let ptr = VirtualAlloc(
|
||||||
|
ptr::null_mut(),
|
||||||
|
size,
|
||||||
|
flags,
|
||||||
|
memprotect_to_protect_const(protect),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
return LLVMResult::ALLOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr_out = ptr as _;
|
||||||
|
*size_out = size;
|
||||||
|
LLVMResult::OK
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult {
|
||||||
|
let size = round_up_to_page_size(size);
|
||||||
|
let ptr = VirtualAlloc(
|
||||||
|
ptr as _,
|
||||||
|
size,
|
||||||
|
MEM_COMMIT,
|
||||||
|
memprotect_to_protect_const(protect),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
LLVMResult::PROTECT_FAILURE
|
||||||
|
} else {
|
||||||
|
LLVMResult::OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult {
|
||||||
|
let success = VirtualFree(ptr as _, size, MEM_DECOMMIT);
|
||||||
|
// If the function succeeds, the return value is nonzero.
|
||||||
|
if success == 1 {
|
||||||
|
LLVMResult::OK
|
||||||
|
} else {
|
||||||
|
LLVMResult::DEALLOC_FAILURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memprotect_to_protect_const(protect: MemProtect) -> u32 {
|
||||||
|
match protect {
|
||||||
|
MemProtect::NONE => PAGE_NOACCESS,
|
||||||
|
MemProtect::READ => PAGE_READONLY,
|
||||||
|
MemProtect::READ_WRITE => PAGE_READWRITE,
|
||||||
|
MemProtect::READ_EXECUTE => PAGE_EXECUTE_READ,
|
||||||
|
}
|
||||||
|
}
|
39
lib/llvm-backend/src/structs.rs
Normal file
39
lib/llvm-backend/src/structs.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use libc::c_char;
|
||||||
|
|
||||||
|
use wasmer_runtime_core::vm;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct LLVMModule {
|
||||||
|
_private: [u8; 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub enum MemProtect {
|
||||||
|
NONE,
|
||||||
|
READ,
|
||||||
|
READ_WRITE,
|
||||||
|
READ_EXECUTE,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub enum LLVMResult {
|
||||||
|
OK,
|
||||||
|
ALLOCATE_FAILURE,
|
||||||
|
PROTECT_FAILURE,
|
||||||
|
DEALLOC_FAILURE,
|
||||||
|
OBJECT_LOAD_FAILURE,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Callbacks {
|
||||||
|
pub alloc_memory: extern "C" fn(usize, MemProtect, &mut *mut u8, &mut usize) -> LLVMResult,
|
||||||
|
pub protect_memory: extern "C" fn(*mut u8, usize, MemProtect) -> LLVMResult,
|
||||||
|
pub dealloc_memory: extern "C" fn(*mut u8, usize) -> LLVMResult,
|
||||||
|
|
||||||
|
pub lookup_vm_symbol: extern "C" fn(*const c_char, usize) -> *const vm::Func,
|
||||||
|
pub visit_fde: extern "C" fn(*mut u8, usize, extern "C" fn(*mut u8)),
|
||||||
|
}
|
@ -27,7 +27,7 @@ tempfile = "3.0.7"
|
|||||||
criterion = "0.2"
|
criterion = "0.2"
|
||||||
wabt = "0.9.0"
|
wabt = "0.9.0"
|
||||||
|
|
||||||
[target.'cfg(not(windows))'.dependencies.wasmer-llvm-backend]
|
[dependencies.wasmer-llvm-backend]
|
||||||
path = "../llvm-backend"
|
path = "../llvm-backend"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user