diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 81c4f5ffef4ec..5803a88c0e757 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -538,15 +538,23 @@ extern "Rust" {
     fn miri_start_panic(payload: *mut u8) -> !;
 
     /// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
-    /// points to. This is only useful as an input to `miri_print_stacks`, and it is a separate call because
+    /// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.
+    ///
+    /// This is only useful as an input to `miri_print_borrow_stacks`, and it is a separate call because
     /// getting a pointer to an allocation at runtime can change the borrow stacks in the allocation.
+    /// This function should be considered unstable. It exists only to support `miri_print_borrow_stacks` and so
+    /// inherits all of its instability.
     fn miri_get_alloc_id(ptr: *const ()) -> u64;
 
     /// Miri-provided extern function to print (from the interpreter, not the program) the contents of all
-    /// borrow stacks in an allocation. The format of what this emits is unstable and may change at any time.
-    /// In particular, users should be aware that Miri will periodically attempt to garbage collect the
-    /// contents of all stacks. Callers of this function may wish to pass `-Zmiri-tag-gc=0` to disable the GC.
-    fn miri_print_stacks(alloc_id: u64);
+    /// borrow stacks in an allocation. The leftmost tag is the bottom of the stack.
+    /// The format of what this emits is unstable and may change at any time. In particular, users should be
+    /// aware that Miri will periodically attempt to garbage collect the contents of all stacks. Callers of
+    /// this function may wish to pass `-Zmiri-tag-gc=0` to disable the GC.
+    ///
+    /// This function is extremely unstable. At any time the format of its output may change, its signature may
+    /// change, or it may be removed entirely.
+    fn miri_print_borrow_stacks(alloc_id: u64);
 
     /// Miri-provided extern function to print (from the interpreter, not the
     /// program) the contents of a section of program memory, as bytes. Bytes
diff --git a/src/tools/miri/build.rs b/src/tools/miri/build.rs
index 37c626baab58a..0977c0ba016bd 100644
--- a/src/tools/miri/build.rs
+++ b/src/tools/miri/build.rs
@@ -4,5 +4,5 @@ fn main() {
     // Re-export the TARGET environment variable so it can
     // be accessed by miri.
     let target = std::env::var("TARGET").unwrap();
-    println!("cargo:rustc-env=TARGET={}", target);
+    println!("cargo:rustc-env=TARGET={target}");
 }
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index 0c1f039d6cc09..22da80be90211 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -34,7 +34,7 @@ Examples:
 "#;
 
 fn show_help() {
-    println!("{}", CARGO_MIRI_HELP);
+    println!("{CARGO_MIRI_HELP}");
 }
 
 fn show_version() {
@@ -52,7 +52,7 @@ fn forward_patched_extern_arg(args: &mut impl Iterator<Item = String>, cmd: &mut
     let path = args.next().expect("`--extern` should be followed by a filename");
     if let Some(lib) = path.strip_suffix(".rlib") {
         // If this is an rlib, make it an rmeta.
-        cmd.arg(format!("{}.rmeta", lib));
+        cmd.arg(format!("{lib}.rmeta"));
     } else {
         // Some other extern file (e.g. a `.so`). Forward unchanged.
         cmd.arg(path);
@@ -336,7 +336,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
                     "[cargo-miri rustc inside rustdoc] captured input:\n{}",
                     std::str::from_utf8(&env.stdin).unwrap()
                 );
-                eprintln!("[cargo-miri rustc inside rustdoc] going to run:\n{:?}", cmd);
+                eprintln!("[cargo-miri rustc inside rustdoc] going to run:\n{cmd:?}");
             }
 
             exec_with_pipe(cmd, &env.stdin, format!("{}.stdin", out_filename("", "").display()));
@@ -374,7 +374,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
                         val.push("metadata");
                     }
                 }
-                cmd.arg(format!("{}={}", emit_flag, val.join(",")));
+                cmd.arg(format!("{emit_flag}={}", val.join(",")));
             } else if arg == "--extern" {
                 // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
                 // https://github.com/rust-lang/miri/issues/1705
@@ -535,7 +535,7 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
     // Run it.
     debug_cmd("[cargo-miri runner]", verbose, &cmd);
     match phase {
-        RunnerPhase::Rustdoc => exec_with_pipe(cmd, &info.stdin, format!("{}.stdin", binary)),
+        RunnerPhase::Rustdoc => exec_with_pipe(cmd, &info.stdin, format!("{binary}.stdin")),
         RunnerPhase::Cargo => exec(cmd),
     }
 }
diff --git a/src/tools/miri/cargo-miri/src/util.rs b/src/tools/miri/cargo-miri/src/util.rs
index aabe5547e5c9a..60f39cb36abaa 100644
--- a/src/tools/miri/cargo-miri/src/util.rs
+++ b/src/tools/miri/cargo-miri/src/util.rs
@@ -83,7 +83,7 @@ pub fn escape_for_toml(s: &str) -> String {
     // We want to surround this string in quotes `"`. So we first escape all quotes,
     // and also all backslashes (that are used to escape quotes).
     let s = s.replace('\\', r#"\\"#).replace('"', r#"\""#);
-    format!("\"{}\"", s)
+    format!("\"{s}\"")
 }
 
 /// Returns the path to the `miri` binary
@@ -175,7 +175,7 @@ pub fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
     let is_ci = env::var_os("CI").is_some() || env::var_os("TF_BUILD").is_some();
     if ask && !is_ci {
         let mut buf = String::new();
-        print!("I will run `{:?}` to {}. Proceed? [Y/n] ", cmd, text);
+        print!("I will run `{cmd:?}` to {text}. Proceed? [Y/n] ");
         io::stdout().flush().unwrap();
         io::stdin().read_line(&mut buf).unwrap();
         match buf.trim().to_lowercase().as_ref() {
@@ -185,10 +185,10 @@ pub fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
             a => show_error!("invalid answer `{}`", a),
         };
     } else {
-        eprintln!("Running `{:?}` to {}.", cmd, text);
+        eprintln!("Running `{cmd:?}` to {text}.");
     }
 
-    if cmd.status().unwrap_or_else(|_| panic!("failed to execute {:?}", cmd)).success().not() {
+    if cmd.status().unwrap_or_else(|_| panic!("failed to execute {cmd:?}")).success().not() {
         show_error!("failed to {}", text);
     }
 }
@@ -276,12 +276,12 @@ pub fn debug_cmd(prefix: &str, verbose: usize, cmd: &Command) {
         // Print only what has been changed for this `cmd`.
         for (var, val) in cmd.get_envs() {
             if let Some(val) = val {
-                writeln!(out, "{}={:?} \\", var.to_string_lossy(), val).unwrap();
+                writeln!(out, "{}={val:?} \\", var.to_string_lossy()).unwrap();
             } else {
                 writeln!(out, "--unset={}", var.to_string_lossy()).unwrap();
             }
         }
     }
     write!(out, "{cmd:?}").unwrap();
-    eprintln!("{}", out);
+    eprintln!("{out}");
 }
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index eb0301bee2ac6..d0e98a8b0dba9 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-b1ab3b738ac718da74cd4aa0bb7f362d0adbdf84
+85d089b41e2a0c0f07ab34f6c5a7c451389f25e6
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 2e114c71d662a..bd01ea655dd70 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -192,7 +192,7 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
             if log::Level::from_str(&var).is_ok() {
                 env::set_var(
                     "RUSTC_LOG",
-                    &format!(
+                    format!(
                         "rustc_middle::mir::interpret={0},rustc_const_eval::interpret={0}",
                         var
                     ),
@@ -243,7 +243,7 @@ fn host_sysroot() -> Option<String> {
                     )
                 }
             }
-            format!("{}/toolchains/{}", home, toolchain)
+            format!("{home}/toolchains/{toolchain}")
         }
         _ => option_env!("RUST_SYSROOT")
             .unwrap_or_else(|| {
@@ -330,7 +330,7 @@ fn main() {
         } else if crate_kind == "host" {
             false
         } else {
-            panic!("invalid `MIRI_BE_RUSTC` value: {:?}", crate_kind)
+            panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}")
         };
 
         // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 3432f10f7a925..ac5dcbf0f4f2f 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -870,6 +870,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         this.machine.threads.active_thread_stack_mut()
     }
 
+    /// Set the name of the current thread. The buffer must not include the null terminator.
     #[inline]
     fn set_thread_name(&mut self, thread: ThreadId, new_thread_name: Vec<u8>) {
         let this = self.eval_context_mut();
diff --git a/src/tools/miri/src/concurrency/vector_clock.rs b/src/tools/miri/src/concurrency/vector_clock.rs
index 32449f8eb1884..e7e5b35ac2cd2 100644
--- a/src/tools/miri/src/concurrency/vector_clock.rs
+++ b/src/tools/miri/src/concurrency/vector_clock.rs
@@ -399,7 +399,7 @@ mod tests {
 
         //Test partial_cmp
         let compare = l.partial_cmp(&r);
-        assert_eq!(compare, o, "Invalid comparison\n l: {:?}\n r: {:?}", l, r);
+        assert_eq!(compare, o, "Invalid comparison\n l: {l:?}\n r: {r:?}");
         let alt_compare = r.partial_cmp(&l);
         assert_eq!(
             alt_compare,
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index ecfe0cd3f8a65..ec81ffd3cd5c9 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -263,7 +263,7 @@ pub fn report_error<'tcx, 'mir>(
     msg.insert(0, e.to_string());
     report_msg(
         DiagLevel::Error,
-        &if let Some(title) = title { format!("{}: {}", title, msg[0]) } else { msg[0].clone() },
+        &if let Some(title) = title { format!("{title}: {}", msg[0]) } else { msg[0].clone() },
         msg,
         vec![],
         helps,
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 15833fe42adc9..f98727186c48d 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1,6 +1,7 @@
 pub mod convert;
 
 use std::cmp;
+use std::iter;
 use std::mem;
 use std::num::NonZeroUsize;
 use std::time::Duration;
@@ -107,7 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     /// Gets an instance for a path.
     fn resolve_path(&self, path: &[&str]) -> ty::Instance<'tcx> {
         self.try_resolve_path(path)
-            .unwrap_or_else(|| panic!("failed to find required Rust item: {:?}", path))
+            .unwrap_or_else(|| panic!("failed to find required Rust item: {path:?}"))
     }
 
     /// Evaluates the scalar at the specified path. Returns Some(val)
@@ -505,7 +506,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             RejectOpWith::WarningWithoutBacktrace => {
                 this.tcx
                     .sess
-                    .warn(&format!("{} was made to return an error due to isolation", op_name));
+                    .warn(format!("{op_name} was made to return an error due to isolation"));
                 Ok(())
             }
             RejectOpWith::Warning => {
@@ -735,6 +736,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         })
     }
 
+    /// Read a sequence of bytes until the first null terminator.
     fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, &'a [u8]>
     where
         'tcx: 'a,
@@ -761,6 +763,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         this.read_bytes_ptr_strip_provenance(ptr, len)
     }
 
+    /// Helper function to write a sequence of bytes with an added null-terminator, which is what
+    /// the Unix APIs usually handle. This function returns `Ok((false, length))` without trying
+    /// to write if `size` is not large enough to fit the contents of `c_str` plus a null
+    /// terminator. It returns `Ok((true, length))` if the writing process was successful. The
+    /// string length returned does include the null terminator.
+    fn write_c_str(
+        &mut self,
+        c_str: &[u8],
+        ptr: Pointer<Option<Provenance>>,
+        size: u64,
+    ) -> InterpResult<'tcx, (bool, u64)> {
+        // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
+        // terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
+        let string_length = u64::try_from(c_str.len()).unwrap();
+        let string_length = string_length.checked_add(1).unwrap();
+        if size < string_length {
+            return Ok((false, string_length));
+        }
+        self.eval_context_mut()
+            .write_bytes_ptr(ptr, c_str.iter().copied().chain(iter::once(0u8)))?;
+        Ok((true, string_length))
+    }
+
+    /// Read a sequence of u16 until the first null terminator.
     fn read_wide_str(&self, mut ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Vec<u16>> {
         let this = self.eval_context_ref();
         let size2 = Size::from_bytes(2);
@@ -783,6 +809,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(wchars)
     }
 
+    /// Helper function to write a sequence of u16 with an added 0x0000-terminator, which is what
+    /// the Windows APIs usually handle. This function returns `Ok((false, length))` without trying
+    /// to write if `size` is not large enough to fit the contents of `os_string` plus a null
+    /// terminator. It returns `Ok((true, length))` if the writing process was successful. The
+    /// string length returned does include the null terminator. Length is measured in units of
+    /// `u16.`
+    fn write_wide_str(
+        &mut self,
+        wide_str: &[u16],
+        ptr: Pointer<Option<Provenance>>,
+        size: u64,
+    ) -> InterpResult<'tcx, (bool, u64)> {
+        // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required
+        // 0x0000 terminator to memory would cause an out-of-bounds access.
+        let string_length = u64::try_from(wide_str.len()).unwrap();
+        let string_length = string_length.checked_add(1).unwrap();
+        if size < string_length {
+            return Ok((false, string_length));
+        }
+
+        // Store the UTF-16 string.
+        let size2 = Size::from_bytes(2);
+        let this = self.eval_context_mut();
+        let mut alloc = this
+            .get_ptr_alloc_mut(ptr, size2 * string_length, Align::from_bytes(2).unwrap())?
+            .unwrap(); // not a ZST, so we will get a result
+        for (offset, wchar) in wide_str.iter().copied().chain(iter::once(0x0000)).enumerate() {
+            let offset = u64::try_from(offset).unwrap();
+            alloc.write_scalar(alloc_range(size2 * offset, size2), Scalar::from_u16(wchar))?;
+        }
+        Ok((true, string_length))
+    }
+
     /// Check that the ABI is what we expect.
     fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> {
         if self.eval_context_ref().machine.enforce_abi && abi != exp_abi {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index fc9a1170d2942..e014e2db1e1f2 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -191,12 +191,12 @@ impl interpret::Provenance for Provenance {
             Provenance::Concrete { alloc_id, sb } => {
                 // Forward `alternate` flag to `alloc_id` printing.
                 if f.alternate() {
-                    write!(f, "[{:#?}]", alloc_id)?;
+                    write!(f, "[{alloc_id:#?}]")?;
                 } else {
-                    write!(f, "[{:?}]", alloc_id)?;
+                    write!(f, "[{alloc_id:?}]")?;
                 }
                 // Print Stacked Borrows tag.
-                write!(f, "{:?}", sb)?;
+                write!(f, "{sb:?}")?;
             }
             Provenance::Wildcard => {
                 write!(f, "[wildcard]")?;
diff --git a/src/tools/miri/src/range_map.rs b/src/tools/miri/src/range_map.rs
index 4742a365ec38b..c8ff06a36652d 100644
--- a/src/tools/miri/src/range_map.rs
+++ b/src/tools/miri/src/range_map.rs
@@ -40,7 +40,7 @@ impl<T> RangeMap<T> {
         let mut left = 0usize; // inclusive
         let mut right = self.v.len(); // exclusive
         loop {
-            debug_assert!(left < right, "find_offset: offset {} is out-of-bounds", offset);
+            debug_assert!(left < right, "find_offset: offset {offset} is out-of-bounds");
             let candidate = left.checked_add(right).unwrap() / 2;
             let elem = &self.v[candidate];
             if offset < elem.range.start {
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index a49e6ba4ce386..1b3205aabc99d 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -321,7 +321,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     return Ok(Some(body));
                 }
 
-                this.handle_unsupported(format!("can't call foreign function: {}", link_name))?;
+                this.handle_unsupported(format!("can't call foreign function: {link_name}"))?;
                 return Ok(None);
             }
         }
@@ -420,10 +420,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "miri_get_alloc_id" => {
                 let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
-                let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr)?;
+                let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr).map_err(|_e| {
+                    err_machine_stop!(TerminationInfo::Abort(
+                        format!("pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}")
+                    ))
+                })?;
                 this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
             }
-            "miri_print_stacks" => {
+            "miri_print_borrow_stacks" => {
                 let [id] = this.check_shim(abi, Abi::Rust, link_name, args)?;
                 let id = this.read_scalar(id)?.to_u64()?;
                 if let Some(id) = std::num::NonZeroU64::new(id) {
diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs
index 407dab970ad7d..99b3605c60175 100644
--- a/src/tools/miri/src/shims/os_str.rs
+++ b/src/tools/miri/src/shims/os_str.rs
@@ -1,6 +1,5 @@
 use std::borrow::Cow;
 use std::ffi::{OsStr, OsString};
-use std::iter;
 use std::path::{Path, PathBuf};
 
 #[cfg(unix)]
@@ -9,7 +8,6 @@ use std::os::unix::ffi::{OsStrExt, OsStringExt};
 use std::os::windows::ffi::{OsStrExt, OsStringExt};
 
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_target::abi::{Align, Size};
 
 use crate::*;
 
@@ -100,16 +98,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         size: u64,
     ) -> InterpResult<'tcx, (bool, u64)> {
         let bytes = os_str_to_bytes(os_str)?;
-        // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
-        // terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
-        let string_length = u64::try_from(bytes.len()).unwrap();
-        let string_length = string_length.checked_add(1).unwrap();
-        if size < string_length {
-            return Ok((false, string_length));
-        }
-        self.eval_context_mut()
-            .write_bytes_ptr(ptr, bytes.iter().copied().chain(iter::once(0u8)))?;
-        Ok((true, string_length))
+        self.eval_context_mut().write_c_str(bytes, ptr, size)
     }
 
     /// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what
@@ -140,25 +129,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
 
         let u16_vec = os_str_to_u16vec(os_str)?;
-        // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required
-        // 0x0000 terminator to memory would cause an out-of-bounds access.
-        let string_length = u64::try_from(u16_vec.len()).unwrap();
-        let string_length = string_length.checked_add(1).unwrap();
-        if size < string_length {
-            return Ok((false, string_length));
-        }
-
-        // Store the UTF-16 string.
-        let size2 = Size::from_bytes(2);
-        let this = self.eval_context_mut();
-        let mut alloc = this
-            .get_ptr_alloc_mut(ptr, size2 * string_length, Align::from_bytes(2).unwrap())?
-            .unwrap(); // not a ZST, so we will get a result
-        for (offset, wchar) in u16_vec.into_iter().chain(iter::once(0x0000)).enumerate() {
-            let offset = u64::try_from(offset).unwrap();
-            alloc.write_scalar(alloc_range(size2 * offset, size2), Scalar::from_u16(wchar))?;
-        }
-        Ok((true, string_length))
+        self.eval_context_mut().write_wide_str(&u16_vec, ptr, size)
     }
 
     /// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of bytes.
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 70798f9817453..d755e5f10bae8 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -26,8 +26,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "pthread_set_name_np" => {
                 let [thread, name] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let res =
-                    this.pthread_setname_np(this.read_scalar(thread)?, this.read_scalar(name)?)?;
+                let max_len = usize::MAX; // freebsd does not seem to have a limit.
+                let res = this.pthread_setname_np(
+                    this.read_scalar(thread)?,
+                    this.read_scalar(name)?,
+                    max_len,
+                )?;
                 this.write_scalar(res, dest)?;
             }
 
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 0610f65db113f..b152082b4deb8 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -621,7 +621,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             return Ok(-1);
         }
 
-        let fd = options.open(&path).map(|file| {
+        let fd = options.open(path).map(|file| {
             let fh = &mut this.machine.file_handler;
             fh.insert_fd(Box::new(FileHandle { file, writable }))
         });
@@ -1862,7 +1862,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
             let possibly_unique = std::env::temp_dir().join::<PathBuf>(p.into());
 
-            let file = fopts.open(&possibly_unique);
+            let file = fopts.open(possibly_unique);
 
             match file {
                 Ok(f) => {
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 5d000f9d121d4..2b53152688bb7 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -68,8 +68,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "pthread_setname_np" => {
                 let [thread, name] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let res =
-                    this.pthread_setname_np(this.read_scalar(thread)?, this.read_scalar(name)?)?;
+                let max_len = 16;
+                let res = this.pthread_setname_np(
+                    this.read_scalar(thread)?,
+                    this.read_scalar(name)?,
+                    max_len,
+                )?;
+                this.write_scalar(res, dest)?;
+            }
+            "pthread_getname_np" => {
+                let [thread, name, len] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let res = this.pthread_getname_np(
+                    this.read_scalar(thread)?,
+                    this.read_scalar(name)?,
+                    this.read_scalar(len)?,
+                )?;
                 this.write_scalar(res, dest)?;
             }
 
@@ -126,7 +140,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                         futex(this, &args[1..], dest)?;
                     }
                     id => {
-                        this.handle_unsupported(format!("can't execute syscall with ID {}", id))?;
+                        this.handle_unsupported(format!("can't execute syscall with ID {id}"))?;
                         return Ok(EmulateByNameResult::AlreadyJumped);
                     }
                 }
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 38d791fba98a4..371f56ca35550 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -176,7 +176,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "pthread_setname_np" => {
                 let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let thread = this.pthread_self()?;
-                this.pthread_setname_np(thread, this.read_scalar(name)?)?;
+                let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?;
+                this.pthread_setname_np(
+                    thread,
+                    this.read_scalar(name)?,
+                    max_len.try_into().unwrap(),
+                )?;
+            }
+            "pthread_getname_np" => {
+                let [thread, name, len] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let res = this.pthread_getname_np(
+                    this.read_scalar(thread)?,
+                    this.read_scalar(name)?,
+                    this.read_scalar(len)?,
+                )?;
+                this.write_scalar(res, dest)?;
             }
 
             // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs
index 59474d8d10ad7..b43682710bbe5 100644
--- a/src/tools/miri/src/shims/unix/thread.rs
+++ b/src/tools/miri/src/shims/unix/thread.rs
@@ -67,10 +67,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(Scalar::from_machine_usize(thread_id.into(), this))
     }
 
+    /// Set the name of the current thread. `max_name_len` is the maximal length of the name
+    /// including the null terminator.
     fn pthread_setname_np(
         &mut self,
         thread: Scalar<Provenance>,
         name: Scalar<Provenance>,
+        max_name_len: usize,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
@@ -78,11 +81,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let name = name.to_pointer(this)?;
 
         let name = this.read_c_str(name)?.to_owned();
+
+        // Comparing with `>=` to account for null terminator.
+        if name.len() >= max_name_len {
+            return this.eval_libc("ERANGE");
+        }
+
         this.set_thread_name(thread, name);
 
         Ok(Scalar::from_u32(0))
     }
 
+    fn pthread_getname_np(
+        &mut self,
+        thread: Scalar<Provenance>,
+        name_out: Scalar<Provenance>,
+        len: Scalar<Provenance>,
+    ) -> InterpResult<'tcx, Scalar<Provenance>> {
+        let this = self.eval_context_mut();
+
+        let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap();
+        let name_out = name_out.to_pointer(this)?;
+        let len = len.to_machine_usize(this)?;
+
+        let name = this.get_thread_name(thread).to_owned();
+        let (success, _written) = this.write_c_str(&name, name_out, len)?;
+
+        if success { Ok(Scalar::from_u32(0)) } else { this.eval_libc("ERANGE") }
+    }
+
     fn sched_yield(&mut self) -> InterpResult<'tcx, i32> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 184ba997fc861..2a34a3a47bbb5 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -418,13 +418,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 // Indicate an error.
                 this.write_null(dest)?;
             }
-            "GetFileInformationByHandleEx" if this.frame_in_std() => {
-                #[allow(non_snake_case)]
-                let [_hFile, _FileInformationClass, _lpFileInformation, _dwBufferSize] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
-                // Just make it fail.
-                this.write_null(dest)?;
-            }
             "GetFileType" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_hFile] =
diff --git a/src/tools/miri/src/stacked_borrows/diagnostics.rs b/src/tools/miri/src/stacked_borrows/diagnostics.rs
index 2cc7a88704ea3..d3843b030347f 100644
--- a/src/tools/miri/src/stacked_borrows/diagnostics.rs
+++ b/src/tools/miri/src/stacked_borrows/diagnostics.rs
@@ -86,12 +86,12 @@ impl Invalidation {
 impl fmt::Display for InvalidationCause {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            InvalidationCause::Access(kind) => write!(f, "{}", kind),
+            InvalidationCause::Access(kind) => write!(f, "{kind}"),
             InvalidationCause::Retag(perm, kind) =>
                 if *kind == RetagCause::FnEntry {
-                    write!(f, "{:?} FnEntry retag", perm)
+                    write!(f, "{perm:?} FnEntry retag")
                 } else {
-                    write!(f, "{:?} retag", perm)
+                    write!(f, "{perm:?} retag")
                 },
         }
     }
@@ -339,7 +339,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir
                 // this allocation.
                 if self.history.base.0.tag() == tag {
                     Some((
-                        format!("{:?} was created here, as the base tag for {:?}", tag, self.history.id),
+                        format!("{tag:?} was created here, as the base tag for {:?}", self.history.id),
                         self.history.base.1.data()
                     ))
                 } else {
@@ -381,7 +381,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir
             self.offset.bytes(),
         );
         err_sb_ub(
-            format!("{}{}", action, error_cause(stack, op.orig_tag)),
+            format!("{action}{}", error_cause(stack, op.orig_tag)),
             Some(operation_summary(&op.cause.summary(), self.history.id, op.range)),
             op.orig_tag.and_then(|orig_tag| self.get_logs_relevant_to(orig_tag, None)),
         )
@@ -401,7 +401,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir
             offset = self.offset.bytes(),
         );
         err_sb_ub(
-            format!("{}{}", action, error_cause(stack, op.tag)),
+            format!("{action}{}", error_cause(stack, op.tag)),
             Some(operation_summary("an access", self.history.id, op.range)),
             op.tag.and_then(|tag| self.get_logs_relevant_to(tag, None)),
         )
diff --git a/src/tools/miri/src/stacked_borrows/mod.rs b/src/tools/miri/src/stacked_borrows/mod.rs
index 959e351d1a145..cc27b71eb5604 100644
--- a/src/tools/miri/src/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/stacked_borrows/mod.rs
@@ -1153,7 +1153,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let alloc_extra = this.get_alloc_extra(alloc_id)?;
         let stacks = alloc_extra.stacked_borrows.as_ref().unwrap().borrow();
         for (range, stack) in stacks.stacks.iter_all() {
-            print!("{:?}: [", range);
+            print!("{range:?}: [");
+            if let Some(bottom) = stack.unknown_bottom() {
+                print!(" unknown-bottom(..{bottom:?})");
+            }
             for i in 0..stack.len() {
                 let item = stack.get(i).unwrap();
                 print!(" {:?}{:?}", item.perm(), item.tag());
diff --git a/src/tools/miri/tests/pass-dep/shims/pthreads.rs b/src/tools/miri/tests/pass-dep/shims/pthreads.rs
index d062eda7e90c8..bbddca74754c5 100644
--- a/src/tools/miri/tests/pass-dep/shims/pthreads.rs
+++ b/src/tools/miri/tests/pass-dep/shims/pthreads.rs
@@ -1,10 +1,14 @@
 //@ignore-target-windows: No libc on Windows
+#![feature(cstr_from_bytes_until_nul)]
+use std::ffi::CStr;
+use std::thread;
 
 fn main() {
     test_mutex_libc_init_recursive();
     test_mutex_libc_init_normal();
     test_mutex_libc_init_errorcheck();
     test_rwlock_libc_static_initializer();
+    test_named_thread_truncation();
 
     #[cfg(any(target_os = "linux"))]
     test_mutex_libc_static_initializer_recursive();
@@ -125,3 +129,24 @@ fn test_rwlock_libc_static_initializer() {
         assert_eq!(libc::pthread_rwlock_destroy(rw.get()), 0);
     }
 }
+
+fn test_named_thread_truncation() {
+    let long_name = std::iter::once("test_named_thread_truncation")
+        .chain(std::iter::repeat(" yada").take(100))
+        .collect::<String>();
+
+    let result = thread::Builder::new().name(long_name.clone()).spawn(move || {
+        // Rust remembers the full thread name itself.
+        assert_eq!(thread::current().name(), Some(long_name.as_str()));
+
+        // But the system is limited -- make sure we successfully set a truncation.
+        let mut buf = vec![0u8; long_name.len() + 1];
+        unsafe {
+            libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len());
+        }
+        let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
+        assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars
+        assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
+    });
+    result.unwrap().join().unwrap();
+}
diff --git a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
index 8d96a2e1ca991..3ca937ae13db8 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zmiri-permissive-provenance
+#![feature(strict_provenance)]
 use std::{
     alloc::{self, Layout},
     mem::ManuallyDrop,
@@ -5,25 +7,40 @@ use std::{
 
 extern "Rust" {
     fn miri_get_alloc_id(ptr: *const u8) -> u64;
-    fn miri_print_stacks(alloc_id: u64);
+    fn miri_print_borrow_stacks(alloc_id: u64);
+}
+
+fn get_alloc_id(ptr: *const u8) -> u64 {
+    unsafe { miri_get_alloc_id(ptr) }
+}
+
+fn print_borrow_stacks(alloc_id: u64) {
+    unsafe { miri_print_borrow_stacks(alloc_id) }
 }
 
 fn main() {
     let ptr = unsafe { alloc::alloc(Layout::new::<u8>()) };
-    let alloc_id = unsafe { miri_get_alloc_id(ptr) };
-    unsafe { miri_print_stacks(alloc_id) };
+    let alloc_id = get_alloc_id(ptr);
+    print_borrow_stacks(alloc_id);
 
     assert!(!ptr.is_null());
-    unsafe { miri_print_stacks(alloc_id) };
+    print_borrow_stacks(alloc_id);
 
     unsafe { *ptr = 42 };
-    unsafe { miri_print_stacks(alloc_id) };
+    print_borrow_stacks(alloc_id);
 
     let _b = unsafe { ManuallyDrop::new(Box::from_raw(ptr)) };
-    unsafe { miri_print_stacks(alloc_id) };
+    print_borrow_stacks(alloc_id);
 
     let _ptr = unsafe { &*ptr };
-    unsafe { miri_print_stacks(alloc_id) };
+    print_borrow_stacks(alloc_id);
+
+    // Create an unknown bottom, and print it
+    let ptr = ptr as usize as *mut u8;
+    unsafe {
+        *ptr = 5;
+    }
+    print_borrow_stacks(alloc_id);
 
     unsafe { alloc::dealloc(ptr, Layout::new::<u8>()) };
 }
diff --git a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout
index 660ee71e6f58b..838733078209d 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout
+++ b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout
@@ -3,3 +3,4 @@
 0..1: [ SharedReadWrite<TAG> ]
 0..1: [ SharedReadWrite<TAG> Unique<TAG> Unique<TAG> Unique<TAG> Unique<TAG> Unique<TAG> ]
 0..1: [ SharedReadWrite<TAG> Disabled<TAG> Disabled<TAG> Disabled<TAG> Disabled<TAG> Disabled<TAG> SharedReadOnly<TAG> ]
+0..1: [ unknown-bottom(..<TAG>) ]