diff options
| author | Chris Denton <chris@chrisdenton.dev> | 2023-02-20 10:41:26 +0000 |
|---|---|---|
| committer | Chris Denton <chris@chrisdenton.dev> | 2023-02-20 14:16:43 +0000 |
| commit | 8123eb49d4f222c84e243f18e77d01ba44aad578 (patch) | |
| tree | 31a15dcfdfdc3c966f96723cc4104389f32640ac | |
| parent | 77de724f92ab111b9cbf48b968552a974168d983 (diff) | |
| download | rust-8123eb49d4f222c84e243f18e77d01ba44aad578.tar.gz rust-8123eb49d4f222c84e243f18e77d01ba44aad578.zip | |
Move `NtWriteFile` miri shim to `foreign_items`
| -rw-r--r-- | src/tools/miri/src/shims/windows/dlsym.rs | 69 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/windows/foreign_items.rs | 68 |
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] = |
