about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Denton <chris@chrisdenton.dev>2023-02-20 10:41:26 +0000
committerChris Denton <chris@chrisdenton.dev>2023-02-20 14:16:43 +0000
commit8123eb49d4f222c84e243f18e77d01ba44aad578 (patch)
tree31a15dcfdfdc3c966f96723cc4104389f32640ac
parent77de724f92ab111b9cbf48b968552a974168d983 (diff)
downloadrust-8123eb49d4f222c84e243f18e77d01ba44aad578.tar.gz
rust-8123eb49d4f222c84e243f18e77d01ba44aad578.zip
Move `NtWriteFile` miri shim to `foreign_items`
-rw-r--r--src/tools/miri/src/shims/windows/dlsym.rs69
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs68
2 files changed, 68 insertions, 69 deletions
diff --git a/src/tools/miri/src/shims/windows/dlsym.rs b/src/tools/miri/src/shims/windows/dlsym.rs
index 60dd299c438..7e2051fc98a 100644
--- a/src/tools/miri/src/shims/windows/dlsym.rs
+++ b/src/tools/miri/src/shims/windows/dlsym.rs
@@ -1,5 +1,4 @@
 use rustc_middle::mir;
-use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
 
 use log::trace;
@@ -11,7 +10,6 @@ use crate::*;
 
 #[derive(Debug, Copy, Clone)]
 pub enum Dlsym {
-    NtWriteFile,
     SetThreadDescription,
     WaitOnAddress,
     WakeByAddressSingle,
@@ -23,7 +21,6 @@ impl Dlsym {
     pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
         Ok(match name {
             "GetSystemTimePreciseAsFileTime" => None,
-            "NtWriteFile" => Some(Dlsym::NtWriteFile),
             "SetThreadDescription" => Some(Dlsym::SetThreadDescription),
             "WaitOnAddress" => Some(Dlsym::WaitOnAddress),
             "WakeByAddressSingle" => Some(Dlsym::WakeByAddressSingle),
@@ -49,72 +46,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         this.check_abi(abi, Abi::System { unwind: false })?;
 
         match dlsym {
-            Dlsym::NtWriteFile => {
-                if !this.frame_in_std() {
-                    throw_unsup_format!(
-                        "`NtWriteFile` support is crude and just enough for stdout to work"
-                    );
-                }
-
-                let [
-                    handle,
-                    _event,
-                    _apc_routine,
-                    _apc_context,
-                    io_status_block,
-                    buf,
-                    n,
-                    byte_offset,
-                    _key,
-                ] = check_arg_count(args)?;
-                let handle = this.read_target_isize(handle)?;
-                let buf = this.read_pointer(buf)?;
-                let n = this.read_scalar(n)?.to_u32()?;
-                let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer
-                let io_status_block = this.deref_operand(io_status_block)?;
-
-                if byte_offset != 0 {
-                    throw_unsup_format!(
-                        "`NtWriteFile` `ByteOffset` paremeter is non-null, which is unsupported"
-                    );
-                }
-
-                let written = if handle == -11 || handle == -12 {
-                    // stdout/stderr
-                    use std::io::{self, Write};
-
-                    let buf_cont =
-                        this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(u64::from(n)))?;
-                    let res = if this.machine.mute_stdout_stderr {
-                        Ok(buf_cont.len())
-                    } else if handle == -11 {
-                        io::stdout().write(buf_cont)
-                    } else {
-                        io::stderr().write(buf_cont)
-                    };
-                    // We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
-                    res.ok().map(|n| u32::try_from(n).unwrap())
-                } else {
-                    throw_unsup_format!(
-                        "on Windows, writing to anything except stdout/stderr is not supported"
-                    )
-                };
-                // We have to put the result into io_status_block.
-                if let Some(n) = written {
-                    let io_status_information =
-                        this.mplace_field_named(&io_status_block, "Information")?;
-                    this.write_scalar(
-                        Scalar::from_target_usize(n.into(), this),
-                        &io_status_information.into(),
-                    )?;
-                }
-                // Return whether this was a success. >= 0 is success.
-                // For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
-                this.write_scalar(
-                    Scalar::from_u32(if written.is_some() { 0 } else { 0xC0000185u32 }),
-                    dest,
-                )?;
-            }
             Dlsym::SetThreadDescription => {
                 let [handle, name] = check_arg_count(args)?;
 
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index a3d7176a976..665c7ed438f 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -69,6 +69,74 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.write_scalar(result, dest)?;
             }
 
+            // File related shims
+            "NtWriteFile" => {
+                if !this.frame_in_std() {
+                    throw_unsup_format!(
+                        "`NtWriteFile` support is crude and just enough for stdout to work"
+                    );
+                }
+
+                let [
+                    handle,
+                    _event,
+                    _apc_routine,
+                    _apc_context,
+                    io_status_block,
+                    buf,
+                    n,
+                    byte_offset,
+                    _key,
+                ] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let handle = this.read_target_isize(handle)?;
+                let buf = this.read_pointer(buf)?;
+                let n = this.read_scalar(n)?.to_u32()?;
+                let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer
+                let io_status_block = this.deref_operand(io_status_block)?;
+
+                if byte_offset != 0 {
+                    throw_unsup_format!(
+                        "`NtWriteFile` `ByteOffset` paremeter is non-null, which is unsupported"
+                    );
+                }
+
+                let written = if handle == -11 || handle == -12 {
+                    // stdout/stderr
+                    use std::io::{self, Write};
+
+                    let buf_cont =
+                        this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(u64::from(n)))?;
+                    let res = if this.machine.mute_stdout_stderr {
+                        Ok(buf_cont.len())
+                    } else if handle == -11 {
+                        io::stdout().write(buf_cont)
+                    } else {
+                        io::stderr().write(buf_cont)
+                    };
+                    // We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
+                    res.ok().map(|n| u32::try_from(n).unwrap())
+                } else {
+                    throw_unsup_format!(
+                        "on Windows, writing to anything except stdout/stderr is not supported"
+                    )
+                };
+                // We have to put the result into io_status_block.
+                if let Some(n) = written {
+                    let io_status_information =
+                        this.mplace_field_named(&io_status_block, "Information")?;
+                    this.write_scalar(
+                        Scalar::from_target_usize(n.into(), this),
+                        &io_status_information.into(),
+                    )?;
+                }
+                // Return whether this was a success. >= 0 is success.
+                // For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
+                this.write_scalar(
+                    Scalar::from_u32(if written.is_some() { 0 } else { 0xC0000185u32 }),
+                    dest,
+                )?;
+            }
+
             // Allocation
             "HeapAlloc" => {
                 let [handle, flags, size] =