Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update Miri #106639

Merged
merged 18 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
// explicitly do this even if RUSTC_STAGE is set, since for these builds we do *not* want the
// bootstrap `rustc` thing in our way! Instead, we have MIRI_HOST_SYSROOT to use for host
// builds.
cmd.env("RUSTC", &fs::canonicalize(find_miri()).unwrap());
cmd.env("RUSTC", fs::canonicalize(find_miri()).unwrap());
cmd.env("MIRI_BE_RUSTC", "target"); // we better remember to *unset* this in the other phases!

// Set rustdoc to us as well, so we can run doctests.
Expand Down
3 changes: 2 additions & 1 deletion src/tools/miri/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ case $HOST_TARGET in
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings
MIRI_TEST_TARGET=thumbv7em-none-eabihf MIRI_NO_STD=1 run_tests_minimal no_std # no_std embedded architecture
MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file
;;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4f4d0586ad20c66a16d547581ca379beafece93a
c54c8cbac882e149e04a9e1f2d146fd548ae30ae
12 changes: 4 additions & 8 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,7 @@ impl fmt::Display for InvalidationCause {
match self {
InvalidationCause::Access(kind) => write!(f, "{kind}"),
InvalidationCause::Retag(perm, kind) =>
if *kind == RetagCause::FnEntry {
write!(f, "{perm:?} FnEntry retag")
} else {
write!(f, "{perm:?} retag")
},
write!(f, "{perm:?} {retag}", retag = kind.summary()),
}
}
}
Expand Down Expand Up @@ -193,7 +189,7 @@ struct RetagOp {
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RetagCause {
Normal,
FnReturn,
FnReturnPlace,
FnEntry,
TwoPhase,
}
Expand Down Expand Up @@ -495,8 +491,8 @@ impl RetagCause {
fn summary(&self) -> String {
match self {
RetagCause::Normal => "retag",
RetagCause::FnEntry => "FnEntry retag",
RetagCause::FnReturn => "FnReturn retag",
RetagCause::FnEntry => "function-entry retag",
RetagCause::FnReturnPlace => "return-place retag",
RetagCause::TwoPhase => "two-phase retag",
}
.to_string()
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
access: Some(AccessKind::Write),
protector: Some(ProtectorKind::StrongProtector),
};
let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturn)?;
let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturnPlace)?;
// And use reborrowed pointer for return place.
let return_place = this.ref_to_mplace(&val)?;
this.frame_mut().return_place = return_place.into();
Expand Down
11 changes: 10 additions & 1 deletion src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
link_name: Symbol,
) -> InterpResult<'tcx, ()> {
self.check_abi(abi, exp_abi)?;
if let Some((body, _)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
if let Some((body, instance)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
// If compiler-builtins is providing the symbol, then don't treat it as a clash.
// We'll use our built-in implementation in `emulate_foreign_item_by_name` for increased
// performance. Note that this means we won't catch any undefined behavior in
// compiler-builtins when running other crates, but Miri can still be run on
// compiler-builtins itself (or any crate that uses it as a normal dependency)
if self.eval_context_ref().tcx.is_compiler_builtins(instance.def_id().krate) {
return Ok(());
}

throw_machine_stop!(TerminationInfo::SymbolShimClashing {
link_name,
span: body.span.data(),
Expand Down
1 change: 0 additions & 1 deletion src/tools/miri/src/range_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ mod tests {
/// Query the map at every offset in the range and collect the results.
fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
(offset..offset + len)
.into_iter()
.map(|i| {
map.iter(Size::from_bytes(i), Size::from_bytes(1)).next().map(|(_, &t)| t).unwrap()
})
Expand Down
6 changes: 4 additions & 2 deletions src/tools/miri/src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// `buf_size` represents the size in characters.
let buf_size = u64::from(this.read_scalar(size_op)?.to_u32()?);
Scalar::from_u32(windows_check_buffer_size(
this.write_os_str_to_wide_str(&var, buf_ptr, buf_size)?,
this.write_os_str_to_wide_str(
&var, buf_ptr, buf_size, /*truncate*/ false,
)?,
))
}
None => {
Expand Down Expand Up @@ -366,7 +368,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
match env::current_dir() {
Ok(cwd) =>
return Ok(Scalar::from_u32(windows_check_buffer_size(
this.write_path_to_wide_str(&cwd, buf, size)?,
this.write_path_to_wide_str(&cwd, buf, size, /*truncate*/ false)?,
))),
Err(e) => this.set_last_error_from_io_error(e.kind())?,
}
Expand Down
51 changes: 41 additions & 10 deletions src/tools/miri/src/shims/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
self.eval_context_mut().write_c_str(bytes, ptr, size)
}

/// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what
/// the Windows APIs usually handle. This function returns `Ok((false, length))` without trying
/// to write if `size` is not large enough to fit the contents of `os_string` plus a null
/// terminator. It returns `Ok((true, length))` if the writing process was successful. The
/// string length returned does include the null terminator. Length is measured in units of
/// `u16.`
/// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what the
/// Windows APIs usually handle.
///
/// If `truncate == false` (the usual mode of operation), this function returns `Ok((false,
/// length))` without trying to write if `size` is not large enough to fit the contents of
/// `os_string` plus a null terminator. It returns `Ok((true, length))` if the writing process
/// was successful. The string length returned does include the null terminator. Length is
/// measured in units of `u16.`
///
/// If `truncate == true`, then in case `size` is not large enough it *will* write the first
/// `size.saturating_sub(1)` many items, followed by a null terminator (if `size > 0`).
fn write_os_str_to_wide_str(
&mut self,
os_str: &OsStr,
ptr: Pointer<Option<Provenance>>,
size: u64,
truncate: bool,
) -> InterpResult<'tcx, (bool, u64)> {
#[cfg(windows)]
fn os_str_to_u16vec<'tcx>(os_str: &OsStr) -> InterpResult<'tcx, Vec<u16>> {
Expand All @@ -129,7 +135,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}

let u16_vec = os_str_to_u16vec(os_str)?;
self.eval_context_mut().write_wide_str(&u16_vec, ptr, size)
let (written, size_needed) = self.eval_context_mut().write_wide_str(&u16_vec, ptr, size)?;
if truncate && !written && size > 0 {
// Write the truncated part that fits.
let truncated_data = &u16_vec[..size.saturating_sub(1).try_into().unwrap()];
let (written, written_len) =
self.eval_context_mut().write_wide_str(truncated_data, ptr, size)?;
assert!(written && written_len == size);
}
Ok((written, size_needed))
}

/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of bytes.
Expand All @@ -143,7 +157,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
assert!(self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap().0);
let (written, _) = self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap();
assert!(written);
Ok(arg_place.ptr)
}

Expand All @@ -158,7 +173,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

let arg_type = this.tcx.mk_array(this.tcx.types.u16, size);
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
assert!(self.write_os_str_to_wide_str(os_str, arg_place.ptr, size).unwrap().0);
let (written, _) =
self.write_os_str_to_wide_str(os_str, arg_place.ptr, size, /*truncate*/ false).unwrap();
assert!(written);
Ok(arg_place.ptr)
}

Expand Down Expand Up @@ -212,11 +229,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
path: &Path,
ptr: Pointer<Option<Provenance>>,
size: u64,
truncate: bool,
) -> InterpResult<'tcx, (bool, u64)> {
let this = self.eval_context_mut();
let os_str =
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
this.write_os_str_to_wide_str(&os_str, ptr, size)
this.write_os_str_to_wide_str(&os_str, ptr, size, truncate)
}

/// Allocate enough memory to store a Path as a null-terminated sequence of bytes,
Expand All @@ -232,6 +250,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.alloc_os_str_as_c_str(&os_str, memkind)
}

/// Allocate enough memory to store a Path as a null-terminated sequence of `u16`s,
/// adjusting path separators if needed.
fn alloc_path_as_wide_str(
&mut self,
path: &Path,
memkind: MemoryKind<MiriMemoryKind>,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
let os_str =
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
this.alloc_os_str_as_wide_str(&os_str, memkind)
}

#[allow(clippy::get_first)]
fn convert_path<'a>(
&self,
Expand Down
40 changes: 40 additions & 0 deletions src/tools/miri/src/shims/windows/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,46 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

this.write_scalar(Scalar::from_u32(1), dest)?;
}
"GetModuleFileNameW" => {
let [handle, filename, size] =
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
this.check_no_isolation("`GetModuleFileNameW`")?;

let handle = this.read_machine_usize(handle)?;
let filename = this.read_pointer(filename)?;
let size = this.read_scalar(size)?.to_u32()?;

if handle != 0 {
throw_unsup_format!("`GetModuleFileNameW` only supports the NULL handle");
}

// Using the host current_exe is a bit off, but consistent with Linux
// (where stdlib reads /proc/self/exe).
// Unfortunately this Windows function has a crazy behavior so we can't just use
// `write_path_to_wide_str`...
let path = std::env::current_exe().unwrap();
let (all_written, size_needed) = this.write_path_to_wide_str(
&path,
filename,
size.into(),
/*truncate*/ true,
)?;

if all_written {
// If the function succeeds, the return value is the length of the string that
// is copied to the buffer, in characters, not including the terminating null
// character.
this.write_int(size_needed.checked_sub(1).unwrap(), dest)?;
} else {
// If the buffer is too small to hold the module name, the string is truncated
// to nSize characters including the terminating null character, the function
// returns nSize, and the function sets the last error to
// ERROR_INSUFFICIENT_BUFFER.
this.write_int(size, dest)?;
let insufficient_buffer = this.eval_windows("c", "ERROR_INSUFFICIENT_BUFFER");
this.set_last_error(insufficient_buffer)?;
}
}

// Threading
"CreateThread" => {
Expand Down
81 changes: 79 additions & 2 deletions src/tools/miri/test_dependencies/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"

[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"

[[package]]
name = "bytes"
version = "1.3.0"
Expand Down Expand Up @@ -44,8 +50,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]

[[package]]
Expand All @@ -57,6 +65,15 @@ dependencies = [
"libc",
]

[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]

[[package]]
name = "libc"
version = "0.2.139"
Expand Down Expand Up @@ -123,6 +140,12 @@ dependencies = [
"libc",
]

[[package]]
name = "once_cell"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"

[[package]]
name = "page_size"
version = "0.5.0"
Expand Down Expand Up @@ -269,9 +292,9 @@ dependencies = [

[[package]]
name = "tokio"
version = "1.23.0"
version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
checksum = "38a54aca0c15d014013256222ba0ebed095673f89345dd79119d912eb561b7a8"
dependencies = [
"autocfg",
"bytes",
Expand Down Expand Up @@ -316,6 +339,60 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]

[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"

[[package]]
name = "winapi"
version = "0.3.9"
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/test_dependencies/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ libc = "0.2"
num_cpus = "1.10.1"

getrandom_1 = { package = "getrandom", version = "0.1" }
getrandom = { version = "0.2" }
getrandom = { version = "0.2", features = ["js"] }
rand = { version = "0.8", features = ["small_rng"] }

[target.'cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))'.dependencies]
page_size = "0.5"
tokio = { version = "1.0", features = ["full"] }
tokio = { version = "1.23", features = ["full"] }

[workspace]
Loading