Skip to content

Commit 72bd25d

Browse files
committed
Fix merge conflicts
2 parents 283a130 + 1a42107 commit 72bd25d

File tree

13 files changed

+116
-112
lines changed

13 files changed

+116
-112
lines changed

miri

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ build_sysroot() {
5454
# Build once, for the user to see.
5555
cargo run $CARGO_BUILD_FLAGS --bin cargo-miri -- miri setup "$@"
5656
# Call again, to just set env var.
57-
eval $(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --env "$@")
57+
export MIRI_SYSROOT="$(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --print-sysroot "$@")"
5858
}
5959

6060
# Prepare and set MIRI_SYSROOT. Respects `MIRI_TEST_TARGET` and takes into account

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f
1+
7979016aff545f7b41cc517031026020b340989d

src/bin/cargo-miri.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ fn setup(ask_user: bool) {
259259

260260
// First, we need xargo.
261261
if xargo_version().map_or(true, |v| v < (0, 3, 16)) {
262+
if std::env::var("XARGO").is_ok() {
263+
// The user manually gave us a xargo binary; don't do anything automatically.
264+
show_error(format!("Your xargo is too old; please upgrade to the latest version"))
265+
}
262266
let mut cmd = cargo();
263267
cmd.args(&["install", "xargo", "-f"]);
264268
ask_to_run(cmd, ask_user, "install a recent enough xargo");
@@ -310,7 +314,7 @@ path = "lib.rs"
310314
File::create(dir.join("lib.rs")).unwrap();
311315
// Prepare xargo invocation.
312316
let target = get_arg_flag_value("--target");
313-
let print_env = !ask_user && has_arg_flag("--env"); // whether we just print the necessary environment variable
317+
let print_sysroot = !ask_user && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
314318
let mut command = xargo();
315319
command.arg("build").arg("-q");
316320
command.current_dir(&dir);
@@ -339,13 +343,9 @@ path = "lib.rs"
339343
};
340344
let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
341345
std::env::set_var("MIRI_SYSROOT", &sysroot); // pass the env var to the processes we spawn, which will turn it into "--sysroot" flags
342-
if print_env {
343-
// Escape an arbitrary string for the shell: by wrapping it in `'`, the only special
344-
// character we have to worry about is `'` itself. Everything else is taken literally
345-
// in these strings. `'` is encoded as `'"'"'`: the outer `'` end and being a
346-
// `'`-quoted string, respectively; the `"'"` in the middle represents a single `'`.
347-
// (We could use `'\''` instead of `'"'"'` if we wanted but let's avoid backslashes.)
348-
println!("MIRI_SYSROOT='{}'", sysroot.display().to_string().replace('\'', r#"'"'"'"#));
346+
if print_sysroot {
347+
// Print just the sysroot and nothing else; this way we do not need any escaping.
348+
println!("{}", sysroot.display());
349349
} else if !ask_user {
350350
println!("A libstd for Miri is now available in `{}`.", sysroot.display());
351351
}

src/eval.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
162162
MiriMemoryKind::Env.into(),
163163
);
164164
ecx.machine.cmd_line = Some(cmd_ptr);
165-
// Store the UTF-16 string.
165+
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
166166
let char_size = Size::from_bytes(2);
167167
let cmd_alloc = ecx.memory.get_mut(cmd_ptr.alloc_id)?;
168168
let mut cur_ptr = cmd_ptr;
@@ -177,17 +177,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
177177
}
178178
}
179179

180-
assert!(
181-
args.next().is_none(),
182-
"start lang item has more arguments than expected"
183-
);
180+
args.next().expect_none("start lang item has more arguments than expected");
184181

185182
// Set the last_error to 0
186183
let errno_layout = ecx.layout_of(ecx.tcx.types.u32)?;
187184
let errno_place = ecx.allocate(errno_layout, MiriMemoryKind::Static.into());
188185
ecx.write_scalar(Scalar::from_u32(0), errno_place.into())?;
189-
let errno_ptr = ecx.check_mplace_access(errno_place.into(), Some(Size::from_bits(32)))?;
190-
ecx.machine.last_error = errno_ptr;
186+
ecx.machine.last_error = Some(errno_place);
191187

192188
Ok(ecx)
193189
}

src/helpers.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9595
}
9696
let this = self.eval_context_mut();
9797

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

350+
/// Sets the last error variable.
351+
fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
352+
let this = self.eval_context_mut();
353+
let errno_place = this.machine.last_error.unwrap();
354+
this.write_scalar(scalar, errno_place.into())
355+
}
356+
357+
/// Gets the last error variable.
358+
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
359+
let this = self.eval_context_mut();
360+
let errno_place = this.machine.last_error.unwrap();
361+
this.read_scalar(errno_place.into())?.not_undef()
362+
}
363+
364+
/// Sets the last OS error using a `std::io::Error`. This function tries to produce the most
365+
/// similar OS error from the `std::io::ErrorKind` and sets it as the last OS error.
366+
fn set_last_error_from_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
367+
use std::io::ErrorKind::*;
368+
let this = self.eval_context_mut();
369+
let target = &this.tcx.tcx.sess.target.target;
370+
let last_error = if target.options.target_family == Some("unix".to_owned()) {
371+
this.eval_libc(match e.kind() {
372+
ConnectionRefused => "ECONNREFUSED",
373+
ConnectionReset => "ECONNRESET",
374+
PermissionDenied => "EPERM",
375+
BrokenPipe => "EPIPE",
376+
NotConnected => "ENOTCONN",
377+
ConnectionAborted => "ECONNABORTED",
378+
AddrNotAvailable => "EADDRNOTAVAIL",
379+
AddrInUse => "EADDRINUSE",
380+
NotFound => "ENOENT",
381+
Interrupted => "EINTR",
382+
InvalidInput => "EINVAL",
383+
TimedOut => "ETIMEDOUT",
384+
AlreadyExists => "EEXIST",
385+
WouldBlock => "EWOULDBLOCK",
386+
_ => throw_unsup_format!("The {} error cannot be transformed into a raw os error", e)
387+
})?
388+
} else {
389+
// FIXME: we have to implement the windows' equivalent of this.
390+
throw_unsup_format!("Setting the last OS error from an io::Error is unsupported for {}.", target.target_os)
391+
};
392+
this.set_last_error(last_error)
393+
}
394+
395+
/// Helper function that consumes an `std::io::Result<T>` and returns an
396+
/// `InterpResult<'tcx,T>::Ok` instead. In case the result is an error, this function returns
397+
/// `Ok(-1)` and sets the last OS error accordingly.
398+
///
399+
/// This function uses `T: From<i32>` instead of `i32` directly because some IO related
400+
/// functions return different integer types (like `read`, that returns an `i64`)
401+
fn try_unwrap_io_result<T: From<i32>>(
402+
&mut self,
403+
result: std::io::Result<T>,
404+
) -> InterpResult<'tcx, T> {
405+
match result {
406+
Ok(ok) => Ok(ok),
407+
Err(e) => {
408+
self.eval_context_mut().set_last_error_from_io_error(e)?;
409+
Ok((-1).into())
410+
}
411+
}
412+
}
413+
349414
/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
350415
/// the Unix APIs usually handle.
351416
fn read_os_string_from_c_string(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(rustc_private)]
2+
#![feature(option_expect_none, option_unwrap_none)]
23

34
#![warn(rust_2018_idioms)]
45
#![allow(clippy::cast_lossless)]

src/machine.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ pub struct Evaluator<'tcx> {
9191
pub(crate) argv: Option<Pointer<Tag>>,
9292
pub(crate) cmd_line: Option<Pointer<Tag>>,
9393

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

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

246246
// No more arguments.
247-
assert!(
248-
args.next().is_none(),
249-
"`exchange_malloc` lang item has more arguments than expected"
250-
);
247+
args.next().expect_none("`exchange_malloc` lang item has more arguments than expected");
251248
Ok(())
252249
}
253250

src/shims/env.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
134134
let erange = this.eval_libc("ERANGE")?;
135135
this.set_last_error(erange)?;
136136
}
137-
Err(e) => this.consume_io_error(e)?,
137+
Err(e) => this.set_last_error_from_io_error(e)?,
138138
}
139139
Ok(Scalar::ptr_null(&*this.tcx))
140140
}
@@ -149,7 +149,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
149149
match env::set_current_dir(path) {
150150
Ok(()) => Ok(0),
151151
Err(e) => {
152-
this.consume_io_error(e)?;
152+
this.set_last_error_from_io_error(e)?;
153153
Ok(-1)
154154
}
155155
}

src/shims/foreign_items.rs

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5050
.memory
5151
.allocate(Size::from_bytes(size), align, kind.into());
5252
if zero_init {
53-
// We just allocated this, the access cannot fail
53+
// We just allocated this, the access is definitely in-bounds.
5454
this.memory
5555
.get_mut(ptr.alloc_id)
5656
.unwrap()
@@ -227,7 +227,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
227227
Align::from_bytes(align).unwrap(),
228228
MiriMemoryKind::Rust.into(),
229229
);
230-
// We just allocated this, the access cannot fail
230+
// We just allocated this, the access is definitely in-bounds.
231231
this.memory
232232
.get_mut(ptr.alloc_id)
233233
.unwrap()
@@ -349,10 +349,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
349349
let arg_dest = this.local_place(arg_local)?;
350350
this.write_scalar(data, arg_dest)?;
351351

352-
assert!(
353-
args.next().is_none(),
354-
"__rust_maybe_catch_panic argument has more arguments than expected"
355-
);
352+
args.next().expect_none("__rust_maybe_catch_panic argument has more arguments than expected");
356353

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

419416
"__errno_location" | "__error" => {
420-
let errno_scalar: Scalar<Tag> = this.machine.last_error.unwrap().into();
421-
this.write_scalar(errno_scalar, dest)?;
417+
let errno_place = this.machine.last_error.unwrap();
418+
this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;
422419
}
423420

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

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

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

671-
let key_ptr = this
672-
.memory
673-
.check_ptr_access(key_ptr, key_layout.size, key_layout.align.abi)?
674-
.expect("cannot be a ZST");
675-
this.memory.get_mut(key_ptr.alloc_id)?.write_scalar(
676-
tcx,
677-
key_ptr,
678-
Scalar::from_uint(key, key_layout.size).into(),
679-
key_layout.size,
680-
)?;
668+
this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;
681669

682670
// Return success (`0`).
683671
this.write_null(dest)?;
@@ -856,6 +844,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
856844
let system_info_ptr = this
857845
.check_mplace_access(system_info, None)?
858846
.expect("cannot be a ZST");
847+
// We rely on `deref_operand` doing bounds checks for us.
859848
// Initialize with `0`.
860849
this.memory
861850
.get_mut(system_info_ptr.alloc_id)?
@@ -988,33 +977,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
988977
}
989978
return Ok(None);
990979
}
991-
992-
fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
993-
let this = self.eval_context_mut();
994-
let errno_ptr = this.machine.last_error.unwrap();
995-
this.memory.get_mut(errno_ptr.alloc_id)?.write_scalar(
996-
&*this.tcx,
997-
errno_ptr,
998-
scalar.into(),
999-
Size::from_bits(32),
1000-
)
1001-
}
1002-
1003-
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
1004-
let this = self.eval_context_mut();
1005-
let errno_ptr = this.machine.last_error.unwrap();
1006-
this.memory
1007-
.get(errno_ptr.alloc_id)?
1008-
.read_scalar(&*this.tcx, errno_ptr, Size::from_bits(32))?
1009-
.not_undef()
1010-
}
1011-
1012-
fn consume_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
1013-
self.eval_context_mut().set_last_error(Scalar::from_int(
1014-
e.raw_os_error().unwrap(),
1015-
Size::from_bits(32),
1016-
))
1017-
}
1018980
}
1019981

1020982
// Shims the linux 'getrandom()' syscall.

0 commit comments

Comments
 (0)