Skip to content

Commit

Permalink
Auto merge of #2055 - RalfJung:rustup, r=RalfJung
Browse files Browse the repository at this point in the history
Rustup

Fixes #1717
  • Loading branch information
bors committed Apr 8, 2022
2 parents f3a9856 + 3a59a15 commit be72564
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 50 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bbe9d27b8ff36da56638aa43d6d0cdfdf89a4e57
1a4b9a85634c17a60e8802307510c300a35a4b9b
3 changes: 3 additions & 0 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {

#[inline(always)]
fn memory_read(
_tcx: TyCtxt<'tcx>,
machine: &Self,
alloc_extra: &AllocExtra,
tag: Tag,
Expand All @@ -627,6 +628,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {

#[inline(always)]
fn memory_written(
_tcx: TyCtxt<'tcx>,
machine: &mut Self,
alloc_extra: &mut AllocExtra,
tag: Tag,
Expand All @@ -649,6 +651,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {

#[inline(always)]
fn memory_deallocated(
_tcx: TyCtxt<'tcx>,
machine: &mut Self,
alloc_extra: &mut AllocExtra,
tag: Tag,
Expand Down
82 changes: 78 additions & 4 deletions src/shims/windows/dlsym.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
use rustc_middle::mir;
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;

use log::trace;

use crate::helpers::check_arg_count;
use crate::*;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {}
pub enum Dlsym {
NtWriteFile,
}

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(name: &str) -> InterpResult<'static, Option<Dlsym>> {
Ok(match name {
"GetSystemTimePreciseAsFileTime" => None,
"NtWriteFile" => Some(Dlsym::NtWriteFile),
_ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
})
}
Expand All @@ -23,15 +30,82 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
&mut self,
dlsym: Dlsym,
abi: Abi,
_args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Tag>],
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (_dest, _ret) = ret.expect("we don't support any diverging dlsym");
let (dest, 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 {}
match dlsym {
Dlsym::NtWriteFile => {
if !this.frame_in_std() {
throw_unsup_format!(
"NtWriteFile support is crude and just enough for stdout to work"
);
}

let &[
ref handle,
ref _event,
ref _apc_routine,
ref _apc_context,
ref io_status_block,
ref buf,
ref n,
ref byte_offset,
ref _key,
] = check_arg_count(args)?;
let handle = this.read_scalar(handle)?.to_machine_isize(this)?;
let buf = this.read_pointer(buf)?;
let n = this.read_scalar(n)?.to_u32()?;
let byte_offset = this.read_scalar(byte_offset)?.to_machine_usize(this)?; // 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(buf, Size::from_bytes(u64::from(n)))?;
let res = if handle == -11 {
io::stdout().write(buf_cont)
} else {
io::stderr().write(buf_cont)
};
res.ok().map(|n| n as u32)
} else {
throw_unsup_format!(
"on Windows, writing to anything except stdout/stderr is not supported"
)
};
// 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_machine_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_i32(if written.is_some() { 0 } else { 0xC0000185u32 as i32 }),
dest,
)?;
}
}

trace!("{:?}", this.dump_place(**dest));
this.go_to_block(ret);
Ok(())
}
}
60 changes: 17 additions & 43 deletions src/shims/windows/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// Windows API stubs.
// HANDLE = isize
// NTSTATUS = LONH = i32
// DWORD = ULONG = u32
// BOOL = i32
// BOOLEAN = u8
Expand Down Expand Up @@ -64,49 +65,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(Scalar::from_i32(result), dest)?;
}

// File related shims
"GetStdHandle" => {
let &[ref which] =
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
let which = this.read_scalar(which)?.to_i32()?;
// We just make this the identity function, so we know later in `WriteFile`
// which one it is.
this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
}
"WriteFile" => {
let &[ref handle, ref buf, ref n, ref written_ptr, ref overlapped] =
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
this.read_scalar(overlapped)?.to_machine_usize(this)?; // this is a poiner, that we ignore
let handle = this.read_scalar(handle)?.to_machine_isize(this)?;
let buf = this.read_pointer(buf)?;
let n = this.read_scalar(n)?.to_u32()?;
let written_place = this.deref_operand(written_ptr)?;
// Spec says to always write `0` first.
this.write_null(&written_place.into())?;
let written = if handle == -11 || handle == -12 {
// stdout/stderr
use std::io::{self, Write};

let buf_cont = this.read_bytes_ptr(buf, Size::from_bytes(u64::from(n)))?;
let res = if handle == -11 {
io::stdout().write(buf_cont)
} else {
io::stderr().write(buf_cont)
};
res.ok().map(|n| n as u32)
} else {
throw_unsup_format!(
"on Windows, writing to anything except stdout/stderr is not supported"
)
};
// If there was no error, write back how much was written.
if let Some(n) = written {
this.write_scalar(Scalar::from_u32(n), &written_place.into())?;
}
// Return whether this was a success.
this.write_scalar(Scalar::from_i32(if written.is_some() { 1 } else { 0 }), dest)?;
}

// Allocation
"HeapAlloc" => {
let &[ref handle, ref flags, ref size] =
Expand Down Expand Up @@ -333,6 +291,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// value if this call does result in switching to another thread.
this.write_null(dest)?;
}
"GetStdHandle" => {
let &[ref which] =
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
let which = this.read_scalar(which)?.to_i32()?;
// We just make this the identity function, so we know later in `NtWriteFile` which
// one it is. This is very fake, but libtest needs it so we cannot make it a
// std-only shim.
this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
}

// Better error for attempts to create a thread
"CreateThread" => {
Expand All @@ -350,6 +317,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Just fake a HANDLE
this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
}
"GetModuleHandleA" if this.frame_in_std() => {
#[allow(non_snake_case)]
let &[_lpModuleName] =
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
// We need to return something non-null here to make `compat_fn!` work.
this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
}
"SetConsoleTextAttribute" if this.frame_in_std() => {
#[allow(non_snake_case)]
let &[ref _hConsoleOutput, ref _wAttribute] =
Expand Down
2 changes: 1 addition & 1 deletion tests/run-pass/concurrency/simple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore-windows: Concurrency on Windows is not supported yet.
// compile-flags: -Zmiri-check-number-validity
// compile-flags: -Zmiri-strict-provenance

use std::thread;

Expand Down
2 changes: 1 addition & 1 deletion tests/run-pass/vecdeque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {
assert_eq!(**a, 2);
}

// Regression test for Debug and Diaplay impl's
// Regression test for Debug impl's
println!("{:?} {:?}", dst, dst.iter());
println!("{:?}", VecDeque::<u32>::new().iter());

Expand Down

0 comments on commit be72564

Please sign in to comment.