about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/miri/src/helpers.rs2
-rw-r--r--src/tools/miri/src/lib.rs4
-rw-r--r--src/tools/miri/src/machine.rs12
-rw-r--r--src/tools/miri/src/shims/dlsym.rs48
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs42
-rw-r--r--src/tools/miri/src/shims/mod.rs4
-rw-r--r--src/tools/miri/src/shims/unix/android/dlsym.rs54
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs21
-rw-r--r--src/tools/miri/src/shims/unix/android/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/dlsym.rs55
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs31
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/dlsym.rs36
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs7
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/linux/dlsym.rs40
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/unix/linux/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/macos/dlsym.rs51
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs31
-rw-r--r--src/tools/miri/src/shims/unix/macos/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/mod.rs1
-rw-r--r--src/tools/miri/src/shims/windows/dlsym.rs82
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs95
-rw-r--r--src/tools/miri/src/shims/windows/mod.rs1
24 files changed, 168 insertions, 461 deletions
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index fd9d57c487c..4146a9b41ae 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -960,7 +960,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         self.check_abi(abi, exp_abi)?;
         if let Some((body, instance)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
             // If compiler-builtins is providing the symbol, then don't treat it as a clash.
-            // We'll use our built-in implementation in `emulate_foreign_item_by_name` for increased
+            // We'll use our built-in implementation in `emulate_foreign_item_inner` for increased
             // performance. Note that this means we won't catch any undefined behavior in
             // compiler-builtins when running other crates, but Miri can still be run on
             // compiler-builtins itself (or any crate that uses it as a normal dependency)
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 816055cc4fe..f1d8ce01bc2 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(yeet_expr)]
 #![feature(nonzero_ops)]
 #![feature(round_ties_even)]
+#![feature(let_chains)]
 #![feature(lint_reasons)]
 #![feature(trait_upcasting)]
 // Configure clippy and other lints
@@ -86,9 +87,8 @@ pub use rustc_const_eval::interpret::*;
 // Resolve ambiguity.
 pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};
 
-pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
 pub use crate::shims::env::{EnvVars, EvalContextExt as _};
-pub use crate::shims::foreign_items::EvalContextExt as _;
+pub use crate::shims::foreign_items::{DynSym, EvalContextExt as _};
 pub use crate::shims::intrinsics::EvalContextExt as _;
 pub use crate::shims::os_str::EvalContextExt as _;
 pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index fb56e0135b4..54f90b2c039 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -709,9 +709,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
             "android" => {
                 // "signal"
                 let layout = this.machine.layouts.const_raw_ptr;
-                let dlsym = Dlsym::from_str("signal".as_bytes(), &this.tcx.sess.target.os)?
-                    .expect("`signal` must be an actual dlsym on android");
-                let ptr = this.fn_ptr(FnVal::Other(dlsym));
+                let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
                 let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
                 Self::alloc_extern_static(this, "signal", val)?;
                 // A couple zero-initialized pointer-sized extern statics.
@@ -867,7 +865,7 @@ impl<'mir, 'tcx> MiriInterpCxExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {
 /// Machine hook implementations.
 impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     type MemoryKind = MiriMemoryKind;
-    type ExtraFnVal = Dlsym;
+    type ExtraFnVal = DynSym;
 
     type FrameExtra = FrameExtra<'tcx>;
     type AllocExtra = AllocExtra<'tcx>;
@@ -939,15 +937,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     #[inline(always)]
     fn call_extra_fn(
         ecx: &mut MiriInterpCx<'mir, 'tcx>,
-        fn_val: Dlsym,
+        fn_val: DynSym,
         abi: Abi,
         args: &[FnArg<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
-        _unwind: mir::UnwindAction,
+        unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
         let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
-        ecx.call_dlsym(fn_val, abi, &args, dest, ret)
+        ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind)
     }
 
     #[inline(always)]
diff --git a/src/tools/miri/src/shims/dlsym.rs b/src/tools/miri/src/shims/dlsym.rs
deleted file mode 100644
index 8bf6d24f85f..00000000000
--- a/src/tools/miri/src/shims/dlsym.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use rustc_middle::mir;
-use rustc_target::spec::abi::Abi;
-
-use crate::helpers::target_os_is_unix;
-use crate::*;
-use shims::unix::dlsym as unix;
-use shims::windows::dlsym as windows;
-
-#[derive(Debug, Copy, Clone)]
-#[allow(non_camel_case_types)]
-pub enum Dlsym {
-    Posix(unix::Dlsym),
-    Windows(windows::Dlsym),
-}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &[u8], target_os: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        let name = &*String::from_utf8_lossy(name);
-        Ok(match target_os {
-            target if target_os_is_unix(target) =>
-                unix::Dlsym::from_str(name, target)?.map(Dlsym::Posix),
-            "windows" => windows::Dlsym::from_str(name)?.map(Dlsym::Windows),
-            os => bug!("dlsym not implemented for target_os {}", os),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        abi: Abi,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        match dlsym {
-            Dlsym::Posix(dlsym) =>
-                unix::EvalContextExt::call_dlsym(this, dlsym, abi, args, dest, ret),
-            Dlsym::Windows(dlsym) =>
-                windows::EvalContextExt::call_dlsym(this, dlsym, abi, args, dest, ret),
-        }
-    }
-}
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 0c92ede40fd..e93521ac774 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -6,7 +6,7 @@ use rustc_apfloat::Float;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_hir::{
     def::DefKind,
-    def_id::{CrateNum, DefId, LOCAL_CRATE},
+    def_id::{CrateNum, LOCAL_CRATE},
 };
 use rustc_middle::middle::{
     codegen_fn_attrs::CodegenFnAttrFlags, dependency_format::Linkage,
@@ -25,7 +25,18 @@ use super::backtrace::EvalContextExt as _;
 use crate::helpers::target_os_is_unix;
 use crate::*;
 
-/// Returned by `emulate_foreign_item_by_name`.
+/// Type of dynamic symbols (for `dlsym` et al)
+#[derive(Debug, Copy, Clone)]
+pub struct DynSym(Symbol);
+
+#[allow(clippy::should_implement_trait)]
+impl DynSym {
+    pub fn from_str(name: &str) -> Self {
+        DynSym(Symbol::intern(name))
+    }
+}
+
+/// Returned by `emulate_foreign_item_inner`.
 pub enum EmulateByNameResult<'mir, 'tcx> {
     /// The caller is expected to jump to the return block.
     NeedsJumping,
@@ -254,7 +265,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     /// is delegated to another function.
     fn emulate_foreign_item(
         &mut self,
-        def_id: DefId,
+        link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
@@ -262,7 +273,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
         let this = self.eval_context_mut();
-        let link_name = this.item_link_name(def_id);
         let tcx = this.tcx.tcx;
 
         // First: functions that diverge.
@@ -322,7 +332,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         };
 
         // Second: functions that return immediately.
-        match this.emulate_foreign_item_by_name(link_name, abi, args, dest)? {
+        match this.emulate_foreign_item_inner(link_name, abi, args, dest)? {
             EmulateByNameResult::NeedsJumping => {
                 trace!("{:?}", this.dump_place(dest));
                 this.go_to_block(ret);
@@ -345,6 +355,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(None)
     }
 
+    /// Emulates a call to a `DynSym`.
+    fn emulate_dyn_sym(
+        &mut self,
+        sym: DynSym,
+        abi: Abi,
+        args: &[OpTy<'tcx, Provenance>],
+        dest: &PlaceTy<'tcx, Provenance>,
+        ret: Option<mir::BasicBlock>,
+        unwind: mir::UnwindAction,
+    ) -> InterpResult<'tcx> {
+        let res = self.emulate_foreign_item(sym.0, abi, args, dest, ret, unwind)?;
+        assert!(res.is_none(), "DynSyms that delegate are not supported");
+        Ok(())
+    }
+
     /// Emulates calling the internal __rust_* allocator functions
     fn emulate_allocator(
         &mut self,
@@ -373,8 +398,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
-    /// Emulates calling a foreign item using its name.
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
@@ -1045,11 +1069,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             _ =>
                 return match this.tcx.sess.target.os.as_ref() {
                     target_os if target_os_is_unix(target_os) =>
-                        shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
+                        shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
                             this, link_name, abi, args, dest,
                         ),
                     "windows" =>
-                        shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
+                        shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
                             this, link_name, abi, args, dest,
                         ),
                     _ => Ok(EmulateByNameResult::NotSupported),
diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs
index 5a9574766f3..a031a2a25c9 100644
--- a/src/tools/miri/src/shims/mod.rs
+++ b/src/tools/miri/src/shims/mod.rs
@@ -9,7 +9,6 @@ pub mod unix;
 pub mod windows;
 mod x86;
 
-pub mod dlsym;
 pub mod env;
 pub mod os_str;
 pub mod panic;
@@ -58,7 +57,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // foreign function
             // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
             let args = this.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
-            return this.emulate_foreign_item(instance.def_id(), abi, &args, dest, ret, unwind);
+            let link_name = this.item_link_name(instance.def_id());
+            return this.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
         }
 
         // Otherwise, load the MIR.
diff --git a/src/tools/miri/src/shims/unix/android/dlsym.rs b/src/tools/miri/src/shims/unix/android/dlsym.rs
deleted file mode 100644
index 451bc0bd5e1..00000000000
--- a/src/tools/miri/src/shims/unix/android/dlsym.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use rustc_middle::mir;
-
-use crate::helpers::check_arg_count;
-use crate::*;
-
-#[derive(Debug, Copy, Clone)]
-#[allow(non_camel_case_types)]
-pub enum Dlsym {
-    signal,
-}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        Ok(match name {
-            "signal" => Some(Dlsym::signal),
-            "android_set_abort_message" => None,
-            _ => throw_unsup_format!("unsupported Android dlsym: {}", name),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let ret = ret.expect("we don't support any diverging dlsym");
-        assert!(this.tcx.sess.target.os == "android");
-
-        match dlsym {
-            Dlsym::signal => {
-                if !this.frame_in_std() {
-                    throw_unsup_format!(
-                        "`signal` support is crude and just enough for libstd to work"
-                    );
-                }
-
-                let [_sig, _func] = check_arg_count(args)?;
-                this.write_null(dest)?;
-            }
-        }
-
-        log::trace!("{:?}", this.dump_place(dest));
-        this.go_to_block(ret);
-        Ok(())
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
index 756aed369f1..b610cf97750 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -6,17 +6,26 @@ use shims::foreign_items::EmulateByNameResult;
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 
+pub fn is_dyn_sym(name: &str) -> bool {
+    matches!(name, "signal")
+}
+
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        _abi: Abi,
-        _args: &[OpTy<'tcx, Provenance>],
-        _dest: &PlaceTy<'tcx, Provenance>,
+        abi: Abi,
+        args: &[OpTy<'tcx, Provenance>],
+        dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
-        let _this = self.eval_context_mut();
-        #[allow(clippy::match_single_binding)]
+        let this = self.eval_context_mut();
+
         match link_name.as_str() {
+            "signal" if this.frame_in_std() => {
+                let [_sig, _func] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                this.write_null(dest)?;
+            }
             _ => return Ok(EmulateByNameResult::NotSupported),
         }
 
diff --git a/src/tools/miri/src/shims/unix/android/mod.rs b/src/tools/miri/src/shims/unix/android/mod.rs
index 434f5f30b5a..09c6507b24f 100644
--- a/src/tools/miri/src/shims/unix/android/mod.rs
+++ b/src/tools/miri/src/shims/unix/android/mod.rs
@@ -1,2 +1 @@
-pub mod dlsym;
 pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/dlsym.rs b/src/tools/miri/src/shims/unix/dlsym.rs
deleted file mode 100644
index 8bc19d18f2b..00000000000
--- a/src/tools/miri/src/shims/unix/dlsym.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use rustc_middle::mir;
-use rustc_target::spec::abi::Abi;
-
-use crate::*;
-use shims::unix::android::dlsym as android;
-use shims::unix::freebsd::dlsym as freebsd;
-use shims::unix::linux::dlsym as linux;
-use shims::unix::macos::dlsym as macos;
-
-#[derive(Debug, Copy, Clone)]
-pub enum Dlsym {
-    Android(android::Dlsym),
-    FreeBsd(freebsd::Dlsym),
-    Linux(linux::Dlsym),
-    MacOs(macos::Dlsym),
-}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str, target_os: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        Ok(match target_os {
-            "android" => android::Dlsym::from_str(name)?.map(Dlsym::Android),
-            "freebsd" => freebsd::Dlsym::from_str(name)?.map(Dlsym::FreeBsd),
-            "linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
-            "macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
-            _ => panic!("unsupported Unix OS {target_os}"),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        abi: Abi,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-
-        this.check_abi(abi, Abi::C { unwind: false })?;
-
-        match dlsym {
-            Dlsym::Android(dlsym) =>
-                android::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
-            Dlsym::FreeBsd(dlsym) =>
-                freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
-            Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
-            Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
-        }
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 4bcca5076ca..06ffdbff4e6 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -1,4 +1,5 @@
 use std::ffi::OsStr;
+use std::str;
 
 use log::trace;
 
@@ -14,9 +15,14 @@ use shims::unix::mem::EvalContextExt as _;
 use shims::unix::sync::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
+use shims::unix::android::foreign_items as android;
+use shims::unix::freebsd::foreign_items as freebsd;
+use shims::unix::linux::foreign_items as linux;
+use shims::unix::macos::foreign_items as macos;
+
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
@@ -25,7 +31,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
         let this = self.eval_context_mut();
 
-        // See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
+        // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
         #[rustfmt::skip]
         match link_name.as_str() {
             // Environment related shims
@@ -230,9 +236,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 this.read_target_usize(handle)?;
                 let symbol = this.read_pointer(symbol)?;
-                let symbol_name = this.read_c_str(symbol)?;
-                if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? {
-                    let ptr = this.fn_ptr(FnVal::Other(dlsym));
+                let name = this.read_c_str(symbol)?;
+                let is_dyn_sym = |name| match &*this.tcx.sess.target.os {
+                    "android" => android::is_dyn_sym(name),
+                    "freebsd" => freebsd::is_dyn_sym(name),
+                    "linux" => linux::is_dyn_sym(name),
+                    "macos" => macos::is_dyn_sym(name),
+                    target_os => panic!("unsupported Unix OS {target_os}"),
+                };
+                if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) {
+                    let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name)));
                     this.write_pointer(ptr, dest)?;
                 } else {
                     this.write_null(dest)?;
@@ -609,10 +622,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             _ => {
                 let target_os = &*this.tcx.sess.target.os;
                 return match target_os {
-                    "android" => shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
-                    "freebsd" => shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
-                    "linux" => shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
-                    "macos" => shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
+                    "android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
+                    "freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
+                    "linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
+                    "macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     _ => Ok(EmulateByNameResult::NotSupported),
                 };
             }
diff --git a/src/tools/miri/src/shims/unix/freebsd/dlsym.rs b/src/tools/miri/src/shims/unix/freebsd/dlsym.rs
deleted file mode 100644
index d759ffb8994..00000000000
--- a/src/tools/miri/src/shims/unix/freebsd/dlsym.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use rustc_middle::mir;
-
-use crate::*;
-
-#[derive(Debug, Copy, Clone)]
-#[allow(non_camel_case_types)]
-pub enum Dlsym {}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        throw_unsup_format!("unsupported FreeBSD dlsym: {}", name)
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        _args: &[OpTy<'tcx, Provenance>],
-        _dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let _ret = ret.expect("we don't support any diverging dlsym");
-        assert!(this.tcx.sess.target.os == "freebsd");
-
-        match dlsym {}
-
-        //trace!("{:?}", this.dump_place(**dest));
-        //this.go_to_block(ret);
-        //Ok(())
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index d755e5f10ba..388b2052679 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -5,10 +5,13 @@ use crate::*;
 use shims::foreign_items::EmulateByNameResult;
 use shims::unix::thread::EvalContextExt as _;
 
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
+pub fn is_dyn_sym(_name: &str) -> bool {
+    false
+}
 
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
diff --git a/src/tools/miri/src/shims/unix/freebsd/mod.rs b/src/tools/miri/src/shims/unix/freebsd/mod.rs
index 434f5f30b5a..09c6507b24f 100644
--- a/src/tools/miri/src/shims/unix/freebsd/mod.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/mod.rs
@@ -1,2 +1 @@
-pub mod dlsym;
 pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/linux/dlsym.rs b/src/tools/miri/src/shims/unix/linux/dlsym.rs
deleted file mode 100644
index a96c14c142b..00000000000
--- a/src/tools/miri/src/shims/unix/linux/dlsym.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use rustc_middle::mir;
-
-use crate::*;
-
-#[derive(Debug, Copy, Clone)]
-pub enum Dlsym {}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        Ok(match name {
-            "__pthread_get_minstack" => None,
-            "getrandom" => None, // std falls back to syscall(SYS_getrandom, ...) when this is NULL.
-            "statx" => None,     // std falls back to syscall(SYS_statx, ...) when this is NULL.
-            _ => throw_unsup_format!("unsupported Linux dlsym: {}", name),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        _args: &[OpTy<'tcx, Provenance>],
-        _dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let _ret = ret.expect("we don't support any diverging dlsym");
-        assert!(this.tcx.sess.target.os == "linux");
-
-        match dlsym {}
-
-        //trace!("{:?}", this.dump_place(**dest));
-        //this.go_to_block(ret);
-        //Ok(())
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 1bd751c5981..9f5f6ea9bd0 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -12,9 +12,13 @@ use shims::unix::linux::sync::futex;
 use shims::unix::sync::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
+pub fn is_dyn_sym(_name: &str) -> bool {
+    false
+}
+
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
@@ -23,7 +27,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
         let this = self.eval_context_mut();
 
-        // See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
+        // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
 
         match link_name.as_str() {
             // errno
diff --git a/src/tools/miri/src/shims/unix/linux/mod.rs b/src/tools/miri/src/shims/unix/linux/mod.rs
index 856ec226de8..fe18f1a32fd 100644
--- a/src/tools/miri/src/shims/unix/linux/mod.rs
+++ b/src/tools/miri/src/shims/unix/linux/mod.rs
@@ -1,4 +1,3 @@
-pub mod dlsym;
 pub mod fd;
 pub mod foreign_items;
 pub mod mem;
diff --git a/src/tools/miri/src/shims/unix/macos/dlsym.rs b/src/tools/miri/src/shims/unix/macos/dlsym.rs
deleted file mode 100644
index fa809452875..00000000000
--- a/src/tools/miri/src/shims/unix/macos/dlsym.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use rustc_middle::mir;
-
-use log::trace;
-
-use super::foreign_items::EvalContextExt as _;
-use crate::*;
-use helpers::check_arg_count;
-
-#[derive(Debug, Copy, Clone)]
-#[allow(non_camel_case_types)]
-pub enum Dlsym {
-    getentropy,
-}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        Ok(match name {
-            "getentropy" => Some(Dlsym::getentropy),
-            _ => throw_unsup_format!("unsupported macOS dlsym: {}", name),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let ret = ret.expect("we don't support any diverging dlsym");
-        assert!(this.tcx.sess.target.os == "macos");
-
-        match dlsym {
-            Dlsym::getentropy => {
-                let [ptr, len] = check_arg_count(args)?;
-                let result = this.getentropy(ptr, len)?;
-                this.write_scalar(result, dest)?;
-            }
-        }
-
-        trace!("{:?}", this.dump_place(dest));
-        this.go_to_block(ret);
-        Ok(())
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index b514097c5df..cb0af4c8279 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -6,9 +6,13 @@ use shims::foreign_items::EmulateByNameResult;
 use shims::unix::fs::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
+pub fn is_dyn_sym(name: &str) -> bool {
+    matches!(name, "getentropy")
+}
+
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
@@ -17,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
         let this = self.eval_context_mut();
 
-        // See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
+        // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
 
         match link_name.as_str() {
             // errno
@@ -113,8 +117,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "getentropy" => {
                 let [buf, bufsize] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.getentropy(buf, bufsize)?;
-                this.write_scalar(result, dest)?;
+                let buf = this.read_pointer(buf)?;
+                let bufsize = this.read_target_usize(bufsize)?;
+
+                this.gen_random(buf, bufsize)?;
+
+                this.write_scalar(Scalar::from_i32(0), dest)?; // KERN_SUCCESS
             }
 
             // Access to command-line arguments
@@ -206,19 +214,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         Ok(EmulateByNameResult::NeedsJumping)
     }
-
-    fn getentropy(
-        &mut self,
-        buffer_op: &OpTy<'tcx, Provenance>,
-        length_op: &OpTy<'tcx, Provenance>,
-    ) -> InterpResult<'tcx, Scalar<Provenance>> {
-        let this = self.eval_context_mut();
-        this.assert_target_os("macos", "getentropy");
-
-        let ptr = this.read_pointer(buffer_op)?;
-        let len = this.read_target_usize(length_op)?;
-        this.gen_random(ptr, len)?;
-
-        Ok(Scalar::from_i32(0)) // KERN_SUCCESS
-    }
 }
diff --git a/src/tools/miri/src/shims/unix/macos/mod.rs b/src/tools/miri/src/shims/unix/macos/mod.rs
index 434f5f30b5a..09c6507b24f 100644
--- a/src/tools/miri/src/shims/unix/macos/mod.rs
+++ b/src/tools/miri/src/shims/unix/macos/mod.rs
@@ -1,2 +1 @@
-pub mod dlsym;
 pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/mod.rs b/src/tools/miri/src/shims/unix/mod.rs
index a8ebd369aba..2f801493352 100644
--- a/src/tools/miri/src/shims/unix/mod.rs
+++ b/src/tools/miri/src/shims/unix/mod.rs
@@ -1,4 +1,3 @@
-pub mod dlsym;
 pub mod foreign_items;
 
 mod fs;
diff --git a/src/tools/miri/src/shims/windows/dlsym.rs b/src/tools/miri/src/shims/windows/dlsym.rs
deleted file mode 100644
index e5afee35905..00000000000
--- a/src/tools/miri/src/shims/windows/dlsym.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-use rustc_middle::mir;
-use rustc_target::spec::abi::Abi;
-
-use log::trace;
-
-use crate::helpers::check_arg_count;
-use crate::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
-use crate::shims::windows::sync::EvalContextExt as _;
-use crate::*;
-
-#[derive(Debug, Copy, Clone)]
-pub enum Dlsym {
-    SetThreadDescription,
-    WaitOnAddress,
-    WakeByAddressSingle,
-}
-
-impl Dlsym {
-    // Returns an error for unsupported symbols, and None if this symbol
-    // should become a NULL pointer (pretend it does not exist).
-    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
-        Ok(match name {
-            "GetSystemTimePreciseAsFileTime" => None,
-            "SetThreadDescription" => Some(Dlsym::SetThreadDescription),
-            "WaitOnAddress" => Some(Dlsym::WaitOnAddress),
-            "WakeByAddressSingle" => Some(Dlsym::WakeByAddressSingle),
-            _ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
-        })
-    }
-}
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn call_dlsym(
-        &mut self,
-        dlsym: Dlsym,
-        abi: Abi,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let ret = ret.expect("we don't support any diverging dlsym");
-        assert!(this.tcx.sess.target.os == "windows");
-
-        this.check_abi(abi, Abi::System { unwind: false })?;
-
-        match dlsym {
-            Dlsym::SetThreadDescription => {
-                let [handle, name] = check_arg_count(args)?;
-
-                let handle = this.read_scalar(handle)?;
-
-                let name = this.read_wide_str(this.read_pointer(name)?)?;
-
-                let thread = match Handle::from_scalar(handle, this)? {
-                    Some(Handle::Thread(thread)) => thread,
-                    Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.get_active_thread(),
-                    _ => this.invalid_handle("SetThreadDescription")?,
-                };
-
-                this.set_thread_name_wide(thread, &name);
-
-                this.write_null(dest)?;
-            }
-            Dlsym::WaitOnAddress => {
-                let [ptr_op, compare_op, size_op, timeout_op] = check_arg_count(args)?;
-
-                this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
-            }
-            Dlsym::WakeByAddressSingle => {
-                let [ptr_op] = check_arg_count(args)?;
-
-                this.WakeByAddressSingle(ptr_op)?;
-            }
-        }
-
-        trace!("{:?}", this.dump_place(dest));
-        this.go_to_block(ret);
-        Ok(())
-    }
-}
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index d76d01b0789..fe2f48638b8 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -1,4 +1,5 @@
 use std::iter;
+use std::str;
 
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
@@ -10,9 +11,13 @@ use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
 use shims::windows::sync::EvalContextExt as _;
 use shims::windows::thread::EvalContextExt as _;
 
+fn is_dyn_sym(name: &str) -> bool {
+    matches!(name, "SetThreadDescription" | "WaitOnAddress" | "WakeByAddressSingle")
+}
+
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn emulate_foreign_item_by_name(
+    fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
         abi: Abi,
@@ -21,7 +26,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
         let this = self.eval_context_mut();
 
-        // See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
+        // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
 
         // Windows API stubs.
         // HANDLE = isize
@@ -326,6 +331,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
                 this.WakeAllConditionVariable(condvar)?;
             }
+            "WaitOnAddress" => {
+                let [ptr_op, compare_op, size_op, timeout_op] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
+            }
+            "WakeByAddressSingle" => {
+                let [ptr_op] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                this.WakeByAddressSingle(ptr_op)?;
+            }
 
             // Dynamic symbol loading
             "GetProcAddress" => {
@@ -334,14 +351,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(hModule)?;
                 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.fn_ptr(FnVal::Other(dlsym));
+                if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) {
+                    let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name)));
                     this.write_pointer(ptr, dest)?;
                 } else {
                     this.write_null(dest)?;
                 }
             }
 
+            // Threading
+            "CreateThread" => {
+                let [security, stacksize, start, arg, flags, thread] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                let thread_id =
+                    this.CreateThread(security, stacksize, start, arg, flags, thread)?;
+
+                this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?;
+            }
+            "WaitForSingleObject" => {
+                let [handle, timeout] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                let ret = this.WaitForSingleObject(handle, timeout)?;
+                this.write_scalar(Scalar::from_u32(ret), dest)?;
+            }
+            "GetCurrentThread" => {
+                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                this.write_scalar(
+                    Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this),
+                    dest,
+                )?;
+            }
+            "SetThreadDescription" => {
+                let [handle, name] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+
+                let handle = this.read_scalar(handle)?;
+
+                let name = this.read_wide_str(this.read_pointer(name)?)?;
+
+                let thread = match Handle::from_scalar(handle, this)? {
+                    Some(Handle::Thread(thread)) => thread,
+                    Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.get_active_thread(),
+                    _ => this.invalid_handle("SetThreadDescription")?,
+                };
+
+                this.set_thread_name_wide(thread, &name);
+
+                this.write_null(dest)?;
+            }
+
             // Miscellaneous
             "SystemFunction036" => {
                 // This is really 'RtlGenRandom'.
@@ -456,32 +517,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 }
             }
 
-            // Threading
-            "CreateThread" => {
-                let [security, stacksize, start, arg, flags, thread] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
-
-                let thread_id =
-                    this.CreateThread(security, stacksize, start, arg, flags, thread)?;
-
-                this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?;
-            }
-            "WaitForSingleObject" => {
-                let [handle, timeout] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
-
-                let ret = this.WaitForSingleObject(handle, timeout)?;
-                this.write_scalar(Scalar::from_u32(ret), dest)?;
-            }
-            "GetCurrentThread" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
-
-                this.write_scalar(
-                    Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this),
-                    dest,
-                )?;
-            }
-
             // 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() => {
diff --git a/src/tools/miri/src/shims/windows/mod.rs b/src/tools/miri/src/shims/windows/mod.rs
index 40fe71b2dbd..7688abe412b 100644
--- a/src/tools/miri/src/shims/windows/mod.rs
+++ b/src/tools/miri/src/shims/windows/mod.rs
@@ -1,4 +1,3 @@
-pub mod dlsym;
 pub mod foreign_items;
 
 mod handle;