Skip to content

Commit 0ba27de

Browse files
author
Yuki Okushi
authored
Rollup merge of rust-lang#106639 - RalfJung:miri, r=RalfJung
update Miri Notable PRs: - rust-lang/miri#2748 - rust-lang/miri#2752 r? `@ghost`
2 parents 96e53c0 + cb15925 commit 0ba27de

File tree

17 files changed

+246
-35
lines changed

17 files changed

+246
-35
lines changed

src/tools/miri/cargo-miri/src/phases.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
185185
// explicitly do this even if RUSTC_STAGE is set, since for these builds we do *not* want the
186186
// bootstrap `rustc` thing in our way! Instead, we have MIRI_HOST_SYSROOT to use for host
187187
// builds.
188-
cmd.env("RUSTC", &fs::canonicalize(find_miri()).unwrap());
188+
cmd.env("RUSTC", fs::canonicalize(find_miri()).unwrap());
189189
cmd.env("MIRI_BE_RUSTC", "target"); // we better remember to *unset* this in the other phases!
190190

191191
// Set rustdoc to us as well, so we can run doctests.

src/tools/miri/ci.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ case $HOST_TARGET in
108108
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
109109
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
110110
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
111-
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer
111+
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings
112+
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings
112113
MIRI_TEST_TARGET=thumbv7em-none-eabihf MIRI_NO_STD=1 run_tests_minimal no_std # no_std embedded architecture
113114
MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file
114115
;;

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4f4d0586ad20c66a16d547581ca379beafece93a
1+
c54c8cbac882e149e04a9e1f2d146fd548ae30ae

src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,7 @@ impl fmt::Display for InvalidationCause {
8888
match self {
8989
InvalidationCause::Access(kind) => write!(f, "{kind}"),
9090
InvalidationCause::Retag(perm, kind) =>
91-
if *kind == RetagCause::FnEntry {
92-
write!(f, "{perm:?} FnEntry retag")
93-
} else {
94-
write!(f, "{perm:?} retag")
95-
},
91+
write!(f, "{perm:?} {retag}", retag = kind.summary()),
9692
}
9793
}
9894
}
@@ -193,7 +189,7 @@ struct RetagOp {
193189
#[derive(Debug, Clone, Copy, PartialEq)]
194190
pub enum RetagCause {
195191
Normal,
196-
FnReturn,
192+
FnReturnPlace,
197193
FnEntry,
198194
TwoPhase,
199195
}
@@ -495,8 +491,8 @@ impl RetagCause {
495491
fn summary(&self) -> String {
496492
match self {
497493
RetagCause::Normal => "retag",
498-
RetagCause::FnEntry => "FnEntry retag",
499-
RetagCause::FnReturn => "FnReturn retag",
494+
RetagCause::FnEntry => "function-entry retag",
495+
RetagCause::FnReturnPlace => "return-place retag",
500496
RetagCause::TwoPhase => "two-phase retag",
501497
}
502498
.to_string()

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
998998
access: Some(AccessKind::Write),
999999
protector: Some(ProtectorKind::StrongProtector),
10001000
};
1001-
let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturn)?;
1001+
let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturnPlace)?;
10021002
// And use reborrowed pointer for return place.
10031003
let return_place = this.ref_to_mplace(&val)?;
10041004
this.frame_mut().return_place = return_place.into();

src/tools/miri/src/helpers.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
943943
link_name: Symbol,
944944
) -> InterpResult<'tcx, ()> {
945945
self.check_abi(abi, exp_abi)?;
946-
if let Some((body, _)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
946+
if let Some((body, instance)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
947+
// If compiler-builtins is providing the symbol, then don't treat it as a clash.
948+
// We'll use our built-in implementation in `emulate_foreign_item_by_name` for increased
949+
// performance. Note that this means we won't catch any undefined behavior in
950+
// compiler-builtins when running other crates, but Miri can still be run on
951+
// compiler-builtins itself (or any crate that uses it as a normal dependency)
952+
if self.eval_context_ref().tcx.is_compiler_builtins(instance.def_id().krate) {
953+
return Ok(());
954+
}
955+
947956
throw_machine_stop!(TerminationInfo::SymbolShimClashing {
948957
link_name,
949958
span: body.span.data(),

src/tools/miri/src/range_map.rs

-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ mod tests {
219219
/// Query the map at every offset in the range and collect the results.
220220
fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
221221
(offset..offset + len)
222-
.into_iter()
223222
.map(|i| {
224223
map.iter(Size::from_bytes(i), Size::from_bytes(1)).next().map(|(_, &t)| t).unwrap()
225224
})

src/tools/miri/src/shims/env.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
166166
// `buf_size` represents the size in characters.
167167
let buf_size = u64::from(this.read_scalar(size_op)?.to_u32()?);
168168
Scalar::from_u32(windows_check_buffer_size(
169-
this.write_os_str_to_wide_str(&var, buf_ptr, buf_size)?,
169+
this.write_os_str_to_wide_str(
170+
&var, buf_ptr, buf_size, /*truncate*/ false,
171+
)?,
170172
))
171173
}
172174
None => {
@@ -366,7 +368,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
366368
match env::current_dir() {
367369
Ok(cwd) =>
368370
return Ok(Scalar::from_u32(windows_check_buffer_size(
369-
this.write_path_to_wide_str(&cwd, buf, size)?,
371+
this.write_path_to_wide_str(&cwd, buf, size, /*truncate*/ false)?,
370372
))),
371373
Err(e) => this.set_last_error_from_io_error(e.kind())?,
372374
}

src/tools/miri/src/shims/os_str.rs

+41-10
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
101101
self.eval_context_mut().write_c_str(bytes, ptr, size)
102102
}
103103

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

131137
let u16_vec = os_str_to_u16vec(os_str)?;
132-
self.eval_context_mut().write_wide_str(&u16_vec, ptr, size)
138+
let (written, size_needed) = self.eval_context_mut().write_wide_str(&u16_vec, ptr, size)?;
139+
if truncate && !written && size > 0 {
140+
// Write the truncated part that fits.
141+
let truncated_data = &u16_vec[..size.saturating_sub(1).try_into().unwrap()];
142+
let (written, written_len) =
143+
self.eval_context_mut().write_wide_str(truncated_data, ptr, size)?;
144+
assert!(written && written_len == size);
145+
}
146+
Ok((written, size_needed))
133147
}
134148

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

144158
let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);
145159
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
146-
assert!(self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap().0);
160+
let (written, _) = self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap();
161+
assert!(written);
147162
Ok(arg_place.ptr)
148163
}
149164

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

159174
let arg_type = this.tcx.mk_array(this.tcx.types.u16, size);
160175
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
161-
assert!(self.write_os_str_to_wide_str(os_str, arg_place.ptr, size).unwrap().0);
176+
let (written, _) =
177+
self.write_os_str_to_wide_str(os_str, arg_place.ptr, size, /*truncate*/ false).unwrap();
178+
assert!(written);
162179
Ok(arg_place.ptr)
163180
}
164181

@@ -212,11 +229,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
212229
path: &Path,
213230
ptr: Pointer<Option<Provenance>>,
214231
size: u64,
232+
truncate: bool,
215233
) -> InterpResult<'tcx, (bool, u64)> {
216234
let this = self.eval_context_mut();
217235
let os_str =
218236
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
219-
this.write_os_str_to_wide_str(&os_str, ptr, size)
237+
this.write_os_str_to_wide_str(&os_str, ptr, size, truncate)
220238
}
221239

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

253+
/// Allocate enough memory to store a Path as a null-terminated sequence of `u16`s,
254+
/// adjusting path separators if needed.
255+
fn alloc_path_as_wide_str(
256+
&mut self,
257+
path: &Path,
258+
memkind: MemoryKind<MiriMemoryKind>,
259+
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
260+
let this = self.eval_context_mut();
261+
let os_str =
262+
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
263+
this.alloc_os_str_as_wide_str(&os_str, memkind)
264+
}
265+
235266
#[allow(clippy::get_first)]
236267
fn convert_path<'a>(
237268
&self,

src/tools/miri/src/shims/windows/foreign_items.rs

+40
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,46 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
381381

382382
this.write_scalar(Scalar::from_u32(1), dest)?;
383383
}
384+
"GetModuleFileNameW" => {
385+
let [handle, filename, size] =
386+
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
387+
this.check_no_isolation("`GetModuleFileNameW`")?;
388+
389+
let handle = this.read_machine_usize(handle)?;
390+
let filename = this.read_pointer(filename)?;
391+
let size = this.read_scalar(size)?.to_u32()?;
392+
393+
if handle != 0 {
394+
throw_unsup_format!("`GetModuleFileNameW` only supports the NULL handle");
395+
}
396+
397+
// Using the host current_exe is a bit off, but consistent with Linux
398+
// (where stdlib reads /proc/self/exe).
399+
// Unfortunately this Windows function has a crazy behavior so we can't just use
400+
// `write_path_to_wide_str`...
401+
let path = std::env::current_exe().unwrap();
402+
let (all_written, size_needed) = this.write_path_to_wide_str(
403+
&path,
404+
filename,
405+
size.into(),
406+
/*truncate*/ true,
407+
)?;
408+
409+
if all_written {
410+
// If the function succeeds, the return value is the length of the string that
411+
// is copied to the buffer, in characters, not including the terminating null
412+
// character.
413+
this.write_int(size_needed.checked_sub(1).unwrap(), dest)?;
414+
} else {
415+
// If the buffer is too small to hold the module name, the string is truncated
416+
// to nSize characters including the terminating null character, the function
417+
// returns nSize, and the function sets the last error to
418+
// ERROR_INSUFFICIENT_BUFFER.
419+
this.write_int(size, dest)?;
420+
let insufficient_buffer = this.eval_windows("c", "ERROR_INSUFFICIENT_BUFFER");
421+
this.set_last_error(insufficient_buffer)?;
422+
}
423+
}
384424

385425
// Threading
386426
"CreateThread" => {

src/tools/miri/test_dependencies/Cargo.lock

+79-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ version = "1.3.2"
1414
source = "registry+https://github.com/rust-lang/crates.io-index"
1515
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
1616

17+
[[package]]
18+
name = "bumpalo"
19+
version = "3.11.1"
20+
source = "registry+https://github.com/rust-lang/crates.io-index"
21+
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
22+
1723
[[package]]
1824
name = "bytes"
1925
version = "1.3.0"
@@ -44,8 +50,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
4450
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
4551
dependencies = [
4652
"cfg-if",
53+
"js-sys",
4754
"libc",
4855
"wasi 0.11.0+wasi-snapshot-preview1",
56+
"wasm-bindgen",
4957
]
5058

5159
[[package]]
@@ -57,6 +65,15 @@ dependencies = [
5765
"libc",
5866
]
5967

68+
[[package]]
69+
name = "js-sys"
70+
version = "0.3.60"
71+
source = "registry+https://github.com/rust-lang/crates.io-index"
72+
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
73+
dependencies = [
74+
"wasm-bindgen",
75+
]
76+
6077
[[package]]
6178
name = "libc"
6279
version = "0.2.139"
@@ -123,6 +140,12 @@ dependencies = [
123140
"libc",
124141
]
125142

143+
[[package]]
144+
name = "once_cell"
145+
version = "1.17.0"
146+
source = "registry+https://github.com/rust-lang/crates.io-index"
147+
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
148+
126149
[[package]]
127150
name = "page_size"
128151
version = "0.5.0"
@@ -269,9 +292,9 @@ dependencies = [
269292

270293
[[package]]
271294
name = "tokio"
272-
version = "1.23.0"
295+
version = "1.23.1"
273296
source = "registry+https://github.com/rust-lang/crates.io-index"
274-
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
297+
checksum = "38a54aca0c15d014013256222ba0ebed095673f89345dd79119d912eb561b7a8"
275298
dependencies = [
276299
"autocfg",
277300
"bytes",
@@ -316,6 +339,60 @@ version = "0.11.0+wasi-snapshot-preview1"
316339
source = "registry+https://github.com/rust-lang/crates.io-index"
317340
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
318341

342+
[[package]]
343+
name = "wasm-bindgen"
344+
version = "0.2.83"
345+
source = "registry+https://github.com/rust-lang/crates.io-index"
346+
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
347+
dependencies = [
348+
"cfg-if",
349+
"wasm-bindgen-macro",
350+
]
351+
352+
[[package]]
353+
name = "wasm-bindgen-backend"
354+
version = "0.2.83"
355+
source = "registry+https://github.com/rust-lang/crates.io-index"
356+
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
357+
dependencies = [
358+
"bumpalo",
359+
"log",
360+
"once_cell",
361+
"proc-macro2",
362+
"quote",
363+
"syn",
364+
"wasm-bindgen-shared",
365+
]
366+
367+
[[package]]
368+
name = "wasm-bindgen-macro"
369+
version = "0.2.83"
370+
source = "registry+https://github.com/rust-lang/crates.io-index"
371+
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
372+
dependencies = [
373+
"quote",
374+
"wasm-bindgen-macro-support",
375+
]
376+
377+
[[package]]
378+
name = "wasm-bindgen-macro-support"
379+
version = "0.2.83"
380+
source = "registry+https://github.com/rust-lang/crates.io-index"
381+
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
382+
dependencies = [
383+
"proc-macro2",
384+
"quote",
385+
"syn",
386+
"wasm-bindgen-backend",
387+
"wasm-bindgen-shared",
388+
]
389+
390+
[[package]]
391+
name = "wasm-bindgen-shared"
392+
version = "0.2.83"
393+
source = "registry+https://github.com/rust-lang/crates.io-index"
394+
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
395+
319396
[[package]]
320397
name = "winapi"
321398
version = "0.3.9"

src/tools/miri/test_dependencies/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ libc = "0.2"
1313
num_cpus = "1.10.1"
1414

1515
getrandom_1 = { package = "getrandom", version = "0.1" }
16-
getrandom = { version = "0.2" }
16+
getrandom = { version = "0.2", features = ["js"] }
1717
rand = { version = "0.8", features = ["small_rng"] }
1818

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

2323
[workspace]

0 commit comments

Comments
 (0)