Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed Oct 21, 2019
2 parents 283a130 + 1a42107 commit 72bd25d
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 112 deletions.
2 changes: 1 addition & 1 deletion miri
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ build_sysroot() {
# Build once, for the user to see.
cargo run $CARGO_BUILD_FLAGS --bin cargo-miri -- miri setup "$@"
# Call again, to just set env var.
eval $(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --env "$@")
export MIRI_SYSROOT="$(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --print-sysroot "$@")"
}

# Prepare and set MIRI_SYSROOT. Respects `MIRI_TEST_TARGET` and takes into account
Expand Down
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f
7979016aff545f7b41cc517031026020b340989d
16 changes: 8 additions & 8 deletions src/bin/cargo-miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ fn setup(ask_user: bool) {

// First, we need xargo.
if xargo_version().map_or(true, |v| v < (0, 3, 16)) {
if std::env::var("XARGO").is_ok() {
// The user manually gave us a xargo binary; don't do anything automatically.
show_error(format!("Your xargo is too old; please upgrade to the latest version"))
}
let mut cmd = cargo();
cmd.args(&["install", "xargo", "-f"]);
ask_to_run(cmd, ask_user, "install a recent enough xargo");
Expand Down Expand Up @@ -310,7 +314,7 @@ path = "lib.rs"
File::create(dir.join("lib.rs")).unwrap();
// Prepare xargo invocation.
let target = get_arg_flag_value("--target");
let print_env = !ask_user && has_arg_flag("--env"); // whether we just print the necessary environment variable
let print_sysroot = !ask_user && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
let mut command = xargo();
command.arg("build").arg("-q");
command.current_dir(&dir);
Expand Down Expand Up @@ -339,13 +343,9 @@ path = "lib.rs"
};
let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
std::env::set_var("MIRI_SYSROOT", &sysroot); // pass the env var to the processes we spawn, which will turn it into "--sysroot" flags
if print_env {
// Escape an arbitrary string for the shell: by wrapping it in `'`, the only special
// character we have to worry about is `'` itself. Everything else is taken literally
// in these strings. `'` is encoded as `'"'"'`: the outer `'` end and being a
// `'`-quoted string, respectively; the `"'"` in the middle represents a single `'`.
// (We could use `'\''` instead of `'"'"'` if we wanted but let's avoid backslashes.)
println!("MIRI_SYSROOT='{}'", sysroot.display().to_string().replace('\'', r#"'"'"'"#));
if print_sysroot {
// Print just the sysroot and nothing else; this way we do not need any escaping.
println!("{}", sysroot.display());
} else if !ask_user {
println!("A libstd for Miri is now available in `{}`.", sysroot.display());
}
Expand Down
10 changes: 3 additions & 7 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
MiriMemoryKind::Env.into(),
);
ecx.machine.cmd_line = Some(cmd_ptr);
// Store the UTF-16 string.
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
let char_size = Size::from_bytes(2);
let cmd_alloc = ecx.memory.get_mut(cmd_ptr.alloc_id)?;
let mut cur_ptr = cmd_ptr;
Expand All @@ -177,17 +177,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
}
}

assert!(
args.next().is_none(),
"start lang item has more arguments than expected"
);
args.next().expect_none("start lang item has more arguments than expected");

// Set the last_error to 0
let errno_layout = ecx.layout_of(ecx.tcx.types.u32)?;
let errno_place = ecx.allocate(errno_layout, MiriMemoryKind::Static.into());
ecx.write_scalar(Scalar::from_u32(0), errno_place.into())?;
let errno_ptr = ecx.check_mplace_access(errno_place.into(), Some(Size::from_bits(32)))?;
ecx.machine.last_error = errno_ptr;
ecx.machine.last_error = Some(errno_place);

Ok(ecx)
}
Expand Down
65 changes: 65 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
let this = self.eval_context_mut();

// Don't forget the bounds check.
let ptr = this.memory.check_ptr_access(
ptr,
Size::from_bytes(len as u64),
Expand Down Expand Up @@ -346,6 +347,70 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
Ok(())
}

/// Sets the last error variable.
fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let errno_place = this.machine.last_error.unwrap();
this.write_scalar(scalar, errno_place.into())
}

/// Gets the last error variable.
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
let this = self.eval_context_mut();
let errno_place = this.machine.last_error.unwrap();
this.read_scalar(errno_place.into())?.not_undef()
}

/// Sets the last OS error using a `std::io::Error`. This function tries to produce the most
/// similar OS error from the `std::io::ErrorKind` and sets it as the last OS error.
fn set_last_error_from_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
use std::io::ErrorKind::*;
let this = self.eval_context_mut();
let target = &this.tcx.tcx.sess.target.target;
let last_error = if target.options.target_family == Some("unix".to_owned()) {
this.eval_libc(match e.kind() {
ConnectionRefused => "ECONNREFUSED",
ConnectionReset => "ECONNRESET",
PermissionDenied => "EPERM",
BrokenPipe => "EPIPE",
NotConnected => "ENOTCONN",
ConnectionAborted => "ECONNABORTED",
AddrNotAvailable => "EADDRNOTAVAIL",
AddrInUse => "EADDRINUSE",
NotFound => "ENOENT",
Interrupted => "EINTR",
InvalidInput => "EINVAL",
TimedOut => "ETIMEDOUT",
AlreadyExists => "EEXIST",
WouldBlock => "EWOULDBLOCK",
_ => throw_unsup_format!("The {} error cannot be transformed into a raw os error", e)
})?
} else {
// FIXME: we have to implement the windows' equivalent of this.
throw_unsup_format!("Setting the last OS error from an io::Error is unsupported for {}.", target.target_os)
};
this.set_last_error(last_error)
}

/// Helper function that consumes an `std::io::Result<T>` and returns an
/// `InterpResult<'tcx,T>::Ok` instead. In case the result is an error, this function returns
/// `Ok(-1)` and sets the last OS error accordingly.
///
/// This function uses `T: From<i32>` instead of `i32` directly because some IO related
/// functions return different integer types (like `read`, that returns an `i64`)
fn try_unwrap_io_result<T: From<i32>>(
&mut self,
result: std::io::Result<T>,
) -> InterpResult<'tcx, T> {
match result {
Ok(ok) => Ok(ok),
Err(e) => {
self.eval_context_mut().set_last_error_from_io_error(e)?;
Ok((-1).into())
}
}
}

/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
/// the Unix APIs usually handle.
fn read_os_string_from_c_string(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(rustc_private)]
#![feature(option_expect_none, option_unwrap_none)]

#![warn(rust_2018_idioms)]
#![allow(clippy::cast_lossless)]
Expand Down
9 changes: 3 additions & 6 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ pub struct Evaluator<'tcx> {
pub(crate) argv: Option<Pointer<Tag>>,
pub(crate) cmd_line: Option<Pointer<Tag>>,

/// Last OS error.
pub(crate) last_error: Option<Pointer<Tag>>,
/// Last OS error location in memory. It is a 32-bit integer.
pub(crate) last_error: Option<MPlaceTy<'tcx, Tag>>,

/// TLS state.
pub(crate) tls: TlsData<'tcx>,
Expand Down Expand Up @@ -244,10 +244,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
ecx.write_scalar(Scalar::from_uint(align, arg.layout.size), arg)?;

// No more arguments.
assert!(
args.next().is_none(),
"`exchange_malloc` lang item has more arguments than expected"
);
args.next().expect_none("`exchange_malloc` lang item has more arguments than expected");
Ok(())
}

Expand Down
4 changes: 2 additions & 2 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let erange = this.eval_libc("ERANGE")?;
this.set_last_error(erange)?;
}
Err(e) => this.consume_io_error(e)?,
Err(e) => this.set_last_error_from_io_error(e)?,
}
Ok(Scalar::ptr_null(&*this.tcx))
}
Expand All @@ -149,7 +149,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
match env::set_current_dir(path) {
Ok(()) => Ok(0),
Err(e) => {
this.consume_io_error(e)?;
this.set_last_error_from_io_error(e)?;
Ok(-1)
}
}
Expand Down
54 changes: 8 additions & 46 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
.memory
.allocate(Size::from_bytes(size), align, kind.into());
if zero_init {
// We just allocated this, the access cannot fail
// We just allocated this, the access is definitely in-bounds.
this.memory
.get_mut(ptr.alloc_id)
.unwrap()
Expand Down Expand Up @@ -227,7 +227,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into(),
);
// We just allocated this, the access cannot fail
// We just allocated this, the access is definitely in-bounds.
this.memory
.get_mut(ptr.alloc_id)
.unwrap()
Expand Down Expand Up @@ -349,10 +349,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let arg_dest = this.local_place(arg_local)?;
this.write_scalar(data, arg_dest)?;

assert!(
args.next().is_none(),
"__rust_maybe_catch_panic argument has more arguments than expected"
);
args.next().expect_none("__rust_maybe_catch_panic argument has more arguments than expected");

// We ourselves will return `0`, eventually (because we will not return if we paniced).
this.write_null(dest)?;
Expand Down Expand Up @@ -417,8 +414,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}

"__errno_location" | "__error" => {
let errno_scalar: Scalar<Tag> = this.machine.last_error.unwrap().into();
this.write_scalar(errno_scalar, dest)?;
let errno_place = this.machine.last_error.unwrap();
this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;
}

"getenv" => {
Expand Down Expand Up @@ -643,7 +640,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// Hook pthread calls that go to the thread-local storage memory subsystem.
"pthread_key_create" => {
let key_ptr = this.read_scalar(args[0])?.not_undef()?;
let key_place = this.deref_operand(args[0])?;

// Extract the function type out of the signature (that seems easier than constructing it ourselves).
let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {
Expand All @@ -668,16 +665,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
throw_unsup!(OutOfTls);
}

let key_ptr = this
.memory
.check_ptr_access(key_ptr, key_layout.size, key_layout.align.abi)?
.expect("cannot be a ZST");
this.memory.get_mut(key_ptr.alloc_id)?.write_scalar(
tcx,
key_ptr,
Scalar::from_uint(key, key_layout.size).into(),
key_layout.size,
)?;
this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;

// Return success (`0`).
this.write_null(dest)?;
Expand Down Expand Up @@ -856,6 +844,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let system_info_ptr = this
.check_mplace_access(system_info, None)?
.expect("cannot be a ZST");
// We rely on `deref_operand` doing bounds checks for us.
// Initialize with `0`.
this.memory
.get_mut(system_info_ptr.alloc_id)?
Expand Down Expand Up @@ -988,33 +977,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
return Ok(None);
}

fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let errno_ptr = this.machine.last_error.unwrap();
this.memory.get_mut(errno_ptr.alloc_id)?.write_scalar(
&*this.tcx,
errno_ptr,
scalar.into(),
Size::from_bits(32),
)
}

fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
let this = self.eval_context_mut();
let errno_ptr = this.machine.last_error.unwrap();
this.memory
.get(errno_ptr.alloc_id)?
.read_scalar(&*this.tcx, errno_ptr, Size::from_bits(32))?
.not_undef()
}

fn consume_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
self.eval_context_mut().set_last_error(Scalar::from_int(
e.raw_os_error().unwrap(),
Size::from_bits(32),
))
}
}

// Shims the linux 'getrandom()' syscall.
Expand Down
Loading

0 comments on commit 72bd25d

Please sign in to comment.