Skip to content

Commit 422d3a6

Browse files
authored
Rollup merge of rust-lang#95775 - RalfJung:miri-windows-compat, r=ChrisDenton
make windows compat_fn (crudely) work on Miri With rust-lang#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 rust-lang#95627 `@ChrisDenton`
2 parents 80005f2 + c599a4c commit 422d3a6

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

library/std/src/sys/windows/compat.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ macro_rules! compat_fn {
7777
static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
7878

7979
unsafe extern "C" fn init() {
80+
PTR = get_f();
81+
}
82+
83+
unsafe extern "C" fn get_f() -> Option<F> {
8084
// There is no locking here. This code is executed before main() is entered, and
8185
// is guaranteed to be single-threaded.
8286
//
@@ -88,13 +92,13 @@ macro_rules! compat_fn {
8892
let symbol_name: *const u8 = concat!(stringify!($symbol), "\0").as_ptr();
8993
let module_handle = $crate::sys::c::GetModuleHandleA(module_name as *const i8);
9094
if !module_handle.is_null() {
91-
match $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8).addr() {
92-
0 => {}
93-
n => {
94-
PTR = Some(mem::transmute::<usize, F>(n));
95-
}
95+
let ptr = $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8);
96+
if !ptr.is_null() {
97+
// Transmute to the right function pointer type.
98+
return Some(mem::transmute(ptr));
9699
}
97100
}
101+
return None;
98102
}
99103

100104
#[allow(dead_code)]
@@ -105,10 +109,15 @@ macro_rules! compat_fn {
105109
#[allow(dead_code)]
106110
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
107111
if let Some(ptr) = PTR {
108-
ptr($($argname),*)
109-
} else {
110-
$fallback_body
112+
return ptr($($argname),*);
113+
}
114+
if cfg!(miri) {
115+
// Miri does not run `init`, so we just call `get_f` each time.
116+
if let Some(ptr) = get_f() {
117+
return ptr($($argname),*);
118+
}
111119
}
120+
$fallback_body
112121
}
113122
}
114123

0 commit comments

Comments
 (0)