windows fastcall (x64) call convention (#314)
* initial set of work for windows fastcall (x64) call convention - call conventions: rename `fastcall` to `windows_fastcall` - add initial set of filetests - ensure arguments are written after the shadow space/store (offset-wise) The shadow space available before the arguments (range 0..32) is not used as spill space yet. * address review feedback
This commit is contained in:
committed by
Dan Gohman
parent
09f883182d
commit
5aa84a744b
@@ -9,6 +9,8 @@ use cretonne_native;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use libc;
|
||||
#[cfg(windows)]
|
||||
use winapi;
|
||||
use memory::Memory;
|
||||
|
||||
/// A builder for `SimpleJITBackend`.
|
||||
@@ -344,6 +346,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
||||
fn finish(self) -> () {}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn lookup_with_dlsym(name: &str) -> *const u8 {
|
||||
let c_str = CString::new(name).unwrap();
|
||||
let c_str_ptr = c_str.as_ptr();
|
||||
@@ -354,6 +357,38 @@ fn lookup_with_dlsym(name: &str) -> *const u8 {
|
||||
sym as *const u8
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn lookup_with_dlsym(name: &str) -> *const u8 {
|
||||
const MSVCRT_DLL: &[u8] = b"msvcrt.dll\0";
|
||||
|
||||
let c_str = CString::new(name).unwrap();
|
||||
let c_str_ptr = c_str.as_ptr();
|
||||
|
||||
unsafe {
|
||||
let handles = [
|
||||
// try to find the searched symbol in the currently running executable
|
||||
ptr::null_mut(),
|
||||
// try to find the searched symbol in local c runtime
|
||||
winapi::um::libloaderapi::GetModuleHandleA(MSVCRT_DLL.as_ptr() as *const i8),
|
||||
];
|
||||
|
||||
for handle in &handles {
|
||||
let addr = winapi::um::libloaderapi::GetProcAddress(*handle, c_str_ptr);
|
||||
if addr.is_null() {
|
||||
continue;
|
||||
}
|
||||
return addr as *const u8;
|
||||
}
|
||||
|
||||
let msg = if handles[1].is_null() {
|
||||
"(msvcrt not loaded)"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
panic!("cannot resolve address of symbol {} {}", name, msg);
|
||||
}
|
||||
}
|
||||
|
||||
struct SimpleJITRelocSink {
|
||||
pub relocs: Vec<RelocRecord>,
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ extern crate errno;
|
||||
extern crate region;
|
||||
extern crate libc;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
extern crate winapi;
|
||||
|
||||
mod backend;
|
||||
mod memory;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ impl PtrLen {
|
||||
|
||||
/// Create a new `PtrLen` pointing to at least `size` bytes of memory,
|
||||
/// suitably sized and aligned for memory protection.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn with_size(size: usize) -> Result<Self, String> {
|
||||
let page_size = region::page::size();
|
||||
let alloc_size = round_up_to_page_size(size, page_size);
|
||||
@@ -42,6 +43,32 @@ impl PtrLen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn with_size(size: usize) -> Result<Self, String> {
|
||||
use winapi::um::memoryapi::VirtualAlloc;
|
||||
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE};
|
||||
|
||||
let page_size = region::page::size();
|
||||
|
||||
// VirtualAlloc always rounds up to the next multiple of the page size
|
||||
let ptr = unsafe {
|
||||
VirtualAlloc(
|
||||
ptr::null_mut(),
|
||||
size,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE,
|
||||
)
|
||||
};
|
||||
if !ptr.is_null() {
|
||||
Ok(Self {
|
||||
ptr: ptr as *mut u8,
|
||||
len: round_up_to_page_size(size, page_size),
|
||||
})
|
||||
} else {
|
||||
Err(errno::errno().to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// JIT memory manager. This manages pages of suitably aligned and
|
||||
|
||||
Reference in New Issue
Block a user