mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #95775 - RalfJung:miri-windows-compat, r=ChrisDenton
make windows compat_fn (crudely) work on Miri With https://github.com/rust-lang/rust/pull/95469, Windows `compat_fn!` now has to be supported by Miri to even make stdout work. Unfortunately, it relies on some outside-of-Rust linker hacks (`#[link_section = ".CRT$XCU"]`) that are rather hard to make work in Miri. So I came up with this crude hack to make this stuff work in Miri regardless. It should come at no cost for regular executions, so I hope this is okay. Cc https://github.com/rust-lang/rust/issues/95627 `@ChrisDenton`
This commit is contained in:
commit
1a4b9a8563
@ -77,6 +77,10 @@ macro_rules! compat_fn {
|
|||||||
static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
|
static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
|
||||||
|
|
||||||
unsafe extern "C" fn init() {
|
unsafe extern "C" fn init() {
|
||||||
|
PTR = get_f();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn get_f() -> Option<F> {
|
||||||
// There is no locking here. This code is executed before main() is entered, and
|
// There is no locking here. This code is executed before main() is entered, and
|
||||||
// is guaranteed to be single-threaded.
|
// is guaranteed to be single-threaded.
|
||||||
//
|
//
|
||||||
@ -88,13 +92,13 @@ macro_rules! compat_fn {
|
|||||||
let symbol_name: *const u8 = concat!(stringify!($symbol), "\0").as_ptr();
|
let symbol_name: *const u8 = concat!(stringify!($symbol), "\0").as_ptr();
|
||||||
let module_handle = $crate::sys::c::GetModuleHandleA(module_name as *const i8);
|
let module_handle = $crate::sys::c::GetModuleHandleA(module_name as *const i8);
|
||||||
if !module_handle.is_null() {
|
if !module_handle.is_null() {
|
||||||
match $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8).addr() {
|
let ptr = $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8);
|
||||||
0 => {}
|
if !ptr.is_null() {
|
||||||
n => {
|
// Transmute to the right function pointer type.
|
||||||
PTR = Some(mem::transmute::<usize, F>(n));
|
return Some(mem::transmute(ptr));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -105,10 +109,15 @@ macro_rules! compat_fn {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
|
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
|
||||||
if let Some(ptr) = PTR {
|
if let Some(ptr) = PTR {
|
||||||
ptr($($argname),*)
|
return ptr($($argname),*);
|
||||||
} else {
|
|
||||||
$fallback_body
|
|
||||||
}
|
}
|
||||||
|
if cfg!(miri) {
|
||||||
|
// Miri does not run `init`, so we just call `get_f` each time.
|
||||||
|
if let Some(ptr) = get_f() {
|
||||||
|
return ptr($($argname),*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$fallback_body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user