]> git.lizzy.rs Git - rust.git/blobdiff - src/shims/windows/foreign_items.rs
some clippy-induced cleanup
[rust.git] / src / shims / windows / foreign_items.rs
index eaf1136669f1b918dd97ed692a008338d7635af7..08a319159bc590c9827428b20f73604724bc5e65 100644 (file)
 use crate::*;
 use shims::foreign_items::EmulateByNameResult;
 use shims::windows::sync::EvalContextExt as _;
+use smallvec::SmallVec;
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
     fn emulate_foreign_item_by_name(
         &mut self,
-        link_name: &str,
-        link_name_sym: Symbol,
+        link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Tag>],
         dest: &PlaceTy<'tcx, Tag>,
         _ret: mir::BasicBlock,
-    ) -> InterpResult<'tcx, EmulateByNameResult> {
+    ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
         let this = self.eval_context_mut();
 
         // Windows API stubs.
         // HANDLE = isize
+        // NTSTATUS = LONH = i32
         // DWORD = ULONG = u32
         // BOOL = i32
         // BOOLEAN = u8
-        match link_name {
+        match link_name.as_str() {
             // Environment related shims
             "GetEnvironmentVariableW" => {
-                let &[ref name, ref buf, ref size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [name, buf, size] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.GetEnvironmentVariableW(name, buf, size)?;
                 this.write_scalar(Scalar::from_u32(result), dest)?;
             }
             "SetEnvironmentVariableW" => {
-                let &[ref name, ref value] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [name, value] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.SetEnvironmentVariableW(name, value)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
             "GetEnvironmentStringsW" => {
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.GetEnvironmentStringsW()?;
-                this.write_scalar(result, dest)?;
+                this.write_pointer(result, dest)?;
             }
             "FreeEnvironmentStringsW" => {
-                let &[ref env_block] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [env_block] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.FreeEnvironmentStringsW(env_block)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
             "GetCurrentDirectoryW" => {
-                let &[ref size, ref buf] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [size, buf] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.GetCurrentDirectoryW(size, buf)?;
                 this.write_scalar(Scalar::from_u32(result), dest)?;
             }
             "SetCurrentDirectoryW" => {
-                let &[ref path] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [path] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.SetCurrentDirectoryW(path)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
 
-            // File related shims
-            "GetStdHandle" => {
-                let &[ref which] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
-                let which = this.read_scalar(which)?.to_i32()?;
-                // We just make this the identity function, so we know later in `WriteFile`
-                // which one it is.
-                this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
-            }
-            "WriteFile" => {
-                let &[ref handle, ref buf, ref n, ref written_ptr, ref overlapped] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
-                this.read_scalar(overlapped)?.to_machine_usize(this)?; // this is a poiner, that we ignore
-                let handle = this.read_scalar(handle)?.to_machine_isize(this)?;
-                let buf = this.read_scalar(buf)?.check_init()?;
-                let n = this.read_scalar(n)?.to_u32()?;
-                let written_place = this.deref_operand(written_ptr)?;
-                // Spec says to always write `0` first.
-                this.write_null(&written_place.into())?;
-                let written = if handle == -11 || handle == -12 {
-                    // stdout/stderr
-                    use std::io::{self, Write};
-
-                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(u64::from(n)))?;
-                    let res = if handle == -11 {
-                        io::stdout().write(buf_cont)
-                    } else {
-                        io::stderr().write(buf_cont)
-                    };
-                    res.ok().map(|n| n as u32)
-                } else {
-                    throw_unsup_format!(
-                        "on Windows, writing to anything except stdout/stderr is not supported"
-                    )
-                };
-                // If there was no error, write back how much was written.
-                if let Some(n) = written {
-                    this.write_scalar(Scalar::from_u32(n), &written_place.into())?;
-                }
-                // Return whether this was a success.
-                this.write_scalar(Scalar::from_i32(if written.is_some() { 1 } else { 0 }), dest)?;
-            }
-
             // Allocation
             "HeapAlloc" => {
-                let &[ref handle, ref flags, ref size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [handle, flags, size] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(handle)?.to_machine_isize(this)?;
                 let flags = this.read_scalar(flags)?.to_u32()?;
                 let size = this.read_scalar(size)?.to_machine_usize(this)?;
                 let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
-                let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
-                this.write_scalar(res, dest)?;
+                let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?;
+                this.write_pointer(res, dest)?;
             }
             "HeapFree" => {
-                let &[ref handle, ref flags, ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [handle, flags, ptr] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(handle)?.to_machine_isize(this)?;
                 this.read_scalar(flags)?.to_u32()?;
-                let ptr = this.read_scalar(ptr)?.check_init()?;
+                let ptr = this.read_pointer(ptr)?;
                 this.free(ptr, MiriMemoryKind::WinHeap)?;
                 this.write_scalar(Scalar::from_i32(1), dest)?;
             }
             "HeapReAlloc" => {
-                let &[ref handle, ref flags, ref ptr, ref size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [handle, flags, ptr, size] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(handle)?.to_machine_isize(this)?;
                 this.read_scalar(flags)?.to_u32()?;
-                let ptr = this.read_scalar(ptr)?.check_init()?;
+                let ptr = this.read_pointer(ptr)?;
                 let size = this.read_scalar(size)?.to_machine_usize(this)?;
                 let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
-                this.write_scalar(res, dest)?;
+                this.write_pointer(res, dest)?;
             }
 
             // errno
             "SetLastError" => {
-                let &[ref error] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [error] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let error = this.read_scalar(error)?.check_init()?;
                 this.set_last_error(error)?;
             }
             "GetLastError" => {
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let last_error = this.get_last_error()?;
                 this.write_scalar(last_error, dest)?;
             }
 
             // Querying system information
             "GetSystemInfo" => {
-                let &[ref system_info] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [system_info] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let system_info = this.deref_operand(system_info)?;
                 // Initialize with `0`.
-                this.memory.write_bytes(
+                this.write_bytes_ptr(
                     system_info.ptr,
                     iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
                 )?;
+                // Set selected fields.
+                let word_layout = this.machine.layouts.u16;
+                let dword_layout = this.machine.layouts.u32;
+                let usize_layout = this.machine.layouts.usize;
+
+                // Using `mplace_field` is error-prone, see: https://github.com/rust-lang/miri/issues/2136.
+                // Pointer fields have different sizes on different targets.
+                // To avoid all these issue we calculate the offsets ourselves.
+                let field_sizes = [
+                    word_layout.size,  // 0,  wProcessorArchitecture      : WORD
+                    word_layout.size,  // 1,  wReserved                   : WORD
+                    dword_layout.size, // 2,  dwPageSize                  : DWORD
+                    usize_layout.size, // 3,  lpMinimumApplicationAddress : LPVOID
+                    usize_layout.size, // 4,  lpMaximumApplicationAddress : LPVOID
+                    usize_layout.size, // 5,  dwActiveProcessorMask       : DWORD_PTR
+                    dword_layout.size, // 6,  dwNumberOfProcessors        : DWORD
+                    dword_layout.size, // 7,  dwProcessorType             : DWORD
+                    dword_layout.size, // 8,  dwAllocationGranularity     : DWORD
+                    word_layout.size,  // 9,  wProcessorLevel             : WORD
+                    word_layout.size,  // 10, wProcessorRevision          : WORD
+                ];
+                let field_offsets: SmallVec<[Size; 11]> = field_sizes
+                    .iter()
+                    .copied()
+                    .scan(Size::ZERO, |a, x| {
+                        let res = Some(*a);
+                        *a += x;
+                        res
+                    })
+                    .collect();
+
+                // Set page size.
+                let page_size = system_info.offset(
+                    field_offsets[2],
+                    MemPlaceMeta::None,
+                    dword_layout,
+                    &this.tcx,
+                )?;
+                this.write_scalar(
+                    Scalar::from_int(PAGE_SIZE, dword_layout.size),
+                    &page_size.into(),
+                )?;
                 // Set number of processors.
-                let dword_size = Size::from_bytes(4);
-                let num_cpus = this.mplace_field(&system_info, 6)?;
-                this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), &num_cpus.into())?;
+                let num_cpus = system_info.offset(
+                    field_offsets[6],
+                    MemPlaceMeta::None,
+                    dword_layout,
+                    &this.tcx,
+                )?;
+                this.write_scalar(Scalar::from_int(NUM_CPUS, dword_layout.size), &num_cpus.into())?;
             }
 
             // Thread-local storage
@@ -175,26 +177,24 @@ fn emulate_foreign_item_by_name(
                 // This just creates a key; Windows does not natively support TLS destructors.
 
                 // Create key and return it.
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let key = this.machine.tls.create_tls_key(None, dest.layout.size)?;
                 this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
             }
             "TlsGetValue" => {
-                let &[ref key] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [key] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let key = u128::from(this.read_scalar(key)?.to_u32()?);
                 let active_thread = this.get_active_thread();
                 let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
                 this.write_scalar(ptr, dest)?;
             }
             "TlsSetValue" => {
-                let &[ref key, ref new_ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [key, new_ptr] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let key = u128::from(this.read_scalar(key)?.to_u32()?);
                 let active_thread = this.get_active_thread();
-                let new_ptr = this.read_scalar(new_ptr)?.check_init()?;
-                this.machine.tls.store_tls(key, active_thread, this.test_null(new_ptr)?)?;
+                let new_data = this.read_scalar(new_ptr)?.check_init()?;
+                this.machine.tls.store_tls(key, active_thread, new_data, &*this.tcx)?;
 
                 // Return success (`1`).
                 this.write_scalar(Scalar::from_i32(1), dest)?;
@@ -202,10 +202,9 @@ fn emulate_foreign_item_by_name(
 
             // Access to command-line arguments
             "GetCommandLineW" => {
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
-                this.write_scalar(
-                    this.machine.cmd_line.expect("machine must be initialized"),
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                this.write_pointer(
+                    this.machine.cmd_line.expect("machine must be initialized").ptr,
                     dest,
                 )?;
             }
@@ -213,55 +212,49 @@ fn emulate_foreign_item_by_name(
             // Time related shims
             "GetSystemTimeAsFileTime" => {
                 #[allow(non_snake_case)]
-                let &[ref LPFILETIME] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [LPFILETIME] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.GetSystemTimeAsFileTime(LPFILETIME)?;
             }
             "QueryPerformanceCounter" => {
                 #[allow(non_snake_case)]
-                let &[ref lpPerformanceCount] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [lpPerformanceCount] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.QueryPerformanceCounter(lpPerformanceCount)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
             "QueryPerformanceFrequency" => {
                 #[allow(non_snake_case)]
-                let &[ref lpFrequency] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [lpFrequency] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let result = this.QueryPerformanceFrequency(lpFrequency)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
 
             // Synchronization primitives
             "AcquireSRWLockExclusive" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.AcquireSRWLockExclusive(ptr)?;
             }
             "ReleaseSRWLockExclusive" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.ReleaseSRWLockExclusive(ptr)?;
             }
             "TryAcquireSRWLockExclusive" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let ret = this.TryAcquireSRWLockExclusive(ptr)?;
                 this.write_scalar(Scalar::from_u8(ret), dest)?;
             }
             "AcquireSRWLockShared" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.AcquireSRWLockShared(ptr)?;
             }
             "ReleaseSRWLockShared" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.ReleaseSRWLockShared(ptr)?;
             }
             "TryAcquireSRWLockShared" => {
-                let &[ref ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let ret = this.TryAcquireSRWLockShared(ptr)?;
                 this.write_scalar(Scalar::from_u8(ret), dest)?;
             }
@@ -269,13 +262,13 @@ fn emulate_foreign_item_by_name(
             // Dynamic symbol loading
             "GetProcAddress" => {
                 #[allow(non_snake_case)]
-                let &[ref hModule, ref lpProcName] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [hModule, lpProcName] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(hModule)?.to_machine_isize(this)?;
-                let name = this.read_c_str(this.read_scalar(lpProcName)?.check_init()?)?;
+                let name = this.read_c_str(this.read_pointer(lpProcName)?)?;
                 if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? {
-                    let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));
-                    this.write_scalar(Scalar::from(ptr), dest)?;
+                    let ptr = this.create_fn_alloc_ptr(FnVal::Other(dlsym));
+                    this.write_pointer(ptr, dest)?;
                 } else {
                     this.write_null(dest)?;
                 }
@@ -284,18 +277,18 @@ fn emulate_foreign_item_by_name(
             // Miscellaneous
             "SystemFunction036" => {
                 // This is really 'RtlGenRandom'.
-                let &[ref ptr, ref len] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
-                let ptr = this.read_scalar(ptr)?.check_init()?;
+                let [ptr, len] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let ptr = this.read_pointer(ptr)?;
                 let len = this.read_scalar(len)?.to_u32()?;
                 this.gen_random(ptr, len.into())?;
                 this.write_scalar(Scalar::from_bool(true), dest)?;
             }
             "BCryptGenRandom" => {
-                let &[ref algorithm, ref ptr, ref len, ref flags] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [algorithm, ptr, len, flags] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 let algorithm = this.read_scalar(algorithm)?;
-                let ptr = this.read_scalar(ptr)?.check_init()?;
+                let ptr = this.read_pointer(ptr)?;
                 let len = this.read_scalar(len)?.to_u32()?;
                 let flags = this.read_scalar(flags)?.to_u32()?;
                 if flags != 2 {
@@ -314,8 +307,8 @@ fn emulate_foreign_item_by_name(
             }
             "GetConsoleScreenBufferInfo" => {
                 // `term` needs this, so we fake it.
-                let &[ref console, ref buffer_info] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [console, buffer_info] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(console)?.to_machine_isize(this)?;
                 this.deref_operand(buffer_info)?;
                 // Indicate an error.
@@ -324,8 +317,8 @@ fn emulate_foreign_item_by_name(
             }
             "GetConsoleMode" => {
                 // Windows "isatty" (in libtest) needs this, so we fake it.
-                let &[ref console, ref mode] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [console, mode] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_scalar(console)?.to_machine_isize(this)?;
                 this.deref_operand(mode)?;
                 // Indicate an error.
@@ -333,20 +326,25 @@ fn emulate_foreign_item_by_name(
                 this.write_null(dest)?;
             }
             "SwitchToThread" => {
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 // Note that once Miri supports concurrency, this will need to return a nonzero
                 // value if this call does result in switching to another thread.
                 this.write_null(dest)?;
             }
+            "GetStdHandle" => {
+                let [which] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let which = this.read_scalar(which)?.to_i32()?;
+                // We just make this the identity function, so we know later in `NtWriteFile` which
+                // one it is. This is very fake, but libtest needs it so we cannot make it a
+                // std-only shim.
+                this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
+            }
 
             // Better error for attempts to create a thread
             "CreateThread" => {
-                this.check_abi_and_shim_symbol_clash(
-                    abi,
-                    Abi::System { unwind: false },
-                    link_name_sym,
-                )?;
+                let [_, _, _, _, _, _] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
 
                 this.handle_unsupported("can't create threads on Windows")?;
                 return Ok(EmulateByNameResult::AlreadyJumped);
@@ -355,29 +353,35 @@ fn emulate_foreign_item_by_name(
             // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
             // These shims are enabled only when the caller is in the standard library.
             "GetProcessHeap" if this.frame_in_std() => {
-                let &[] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 // Just fake a HANDLE
                 this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
             }
+            "GetModuleHandleA" if this.frame_in_std() => {
+                #[allow(non_snake_case)]
+                let [_lpModuleName] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                // We need to return something non-null here to make `compat_fn!` work.
+                this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
+            }
             "SetConsoleTextAttribute" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
-                let &[ref _hConsoleOutput, ref _wAttribute] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [_hConsoleOutput, _wAttribute] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 // Pretend these does not exist / nothing happened, by returning zero.
                 this.write_null(dest)?;
             }
             "AddVectoredExceptionHandler" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
-                let &[ref _First, ref _Handler] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [_First, _Handler] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
                 this.write_scalar(Scalar::from_machine_usize(1, this), dest)?;
             }
             "SetThreadStackGuarantee" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
-                let &[_StackSizeInBytes] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [_StackSizeInBytes] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
                 this.write_scalar(Scalar::from_u32(1), dest)?;
             }
@@ -388,8 +392,8 @@ fn emulate_foreign_item_by_name(
                 if this.frame_in_std() =>
             {
                 #[allow(non_snake_case)]
-                let &[ref _lpCriticalSection] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [_lpCriticalSection] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 assert_eq!(
                     this.get_total_thread_count(),
                     1,
@@ -401,8 +405,8 @@ fn emulate_foreign_item_by_name(
             }
             "TryEnterCriticalSection" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
-                let &[ref _lpCriticalSection] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name_sym, args)?;
+                let [_lpCriticalSection] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 assert_eq!(
                     this.get_total_thread_count(),
                     1,
@@ -411,6 +415,10 @@ fn emulate_foreign_item_by_name(
                 // There is only one thread, so this always succeeds and returns TRUE.
                 this.write_scalar(Scalar::from_i32(1), dest)?;
             }
+            "GetCurrentThread" if this.frame_in_std() => {
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
+            }
 
             _ => return Ok(EmulateByNameResult::NotSupported),
         }