Skip to content

Commit 3cce78b

Browse files
authored
Rollup merge of #133457 - joboet:miri-tlsfree, r=saethlin
miri: implement `TlsFree` If the variable does not need a destructor, `std` uses racy initialization for creating TLS keys on Windows. With just the right timing, this can lead to `TlsFree` being called. Unfortunately, with #132654 this is hit quite often, so miri should definitely support `TlsFree` ([documentation](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree)). I'm filing this here instead of in the miri repo so that #132654 isn't blocked for so long.
2 parents 04d6333 + 77fccf5 commit 3cce78b

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

src/tools/miri/src/shims/windows/foreign_items.rs

+8
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
382382
// Return success (`1`).
383383
this.write_int(1, dest)?;
384384
}
385+
"TlsFree" => {
386+
let [key] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
387+
let key = u128::from(this.read_scalar(key)?.to_u32()?);
388+
this.machine.tls.delete_tls_key(key)?;
389+
390+
// Return success (`1`).
391+
this.write_int(1, dest)?;
392+
}
385393

386394
// Access to command-line arguments
387395
"GetCommandLineW" => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@only-target: windows # this directly tests windows-only functions
2+
3+
use std::ffi::c_void;
4+
use std::ptr;
5+
6+
extern "system" {
7+
fn TlsAlloc() -> u32;
8+
fn TlsSetValue(key: u32, val: *mut c_void) -> bool;
9+
fn TlsGetValue(key: u32) -> *mut c_void;
10+
fn TlsFree(key: u32) -> bool;
11+
}
12+
13+
fn main() {
14+
let key = unsafe { TlsAlloc() };
15+
assert!(unsafe { TlsSetValue(key, ptr::without_provenance_mut(1)) });
16+
assert_eq!(unsafe { TlsGetValue(key).addr() }, 1);
17+
assert!(unsafe { TlsFree(key) });
18+
}

0 commit comments

Comments
 (0)