Skip to content

Commit ef80155

Browse files
committed
Auto merge of #3603 - Luv-Ray:issue-3572, r=RalfJung
Give `FileDescription::{read, write}` access to the `MiriInterpCx ` fixes #3572
2 parents fef1043 + b9215a5 commit ef80155

File tree

3 files changed

+28
-19
lines changed

3 files changed

+28
-19
lines changed

src/shims/unix/fd.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::collections::BTreeMap;
77
use std::io::{self, ErrorKind, IsTerminal, Read, SeekFrom, Write};
88
use std::rc::Rc;
99

10-
use rustc_middle::ty::TyCtxt;
1110
use rustc_target::abi::Size;
1211

1312
use crate::shims::unix::*;
@@ -22,7 +21,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
2221
&mut self,
2322
_communicate_allowed: bool,
2423
_bytes: &mut [u8],
25-
_tcx: TyCtxt<'tcx>,
24+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
2625
) -> InterpResult<'tcx, io::Result<usize>> {
2726
throw_unsup_format!("cannot read from {}", self.name());
2827
}
@@ -32,7 +31,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
3231
&mut self,
3332
_communicate_allowed: bool,
3433
_bytes: &[u8],
35-
_tcx: TyCtxt<'tcx>,
34+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
3635
) -> InterpResult<'tcx, io::Result<usize>> {
3736
throw_unsup_format!("cannot write to {}", self.name());
3837
}
@@ -82,7 +81,7 @@ impl FileDescription for io::Stdin {
8281
&mut self,
8382
communicate_allowed: bool,
8483
bytes: &mut [u8],
85-
_tcx: TyCtxt<'tcx>,
84+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
8685
) -> InterpResult<'tcx, io::Result<usize>> {
8786
if !communicate_allowed {
8887
// We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
@@ -105,7 +104,7 @@ impl FileDescription for io::Stdout {
105104
&mut self,
106105
_communicate_allowed: bool,
107106
bytes: &[u8],
108-
_tcx: TyCtxt<'tcx>,
107+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
109108
) -> InterpResult<'tcx, io::Result<usize>> {
110109
// We allow writing to stderr even with isolation enabled.
111110
let result = Write::write(self, bytes);
@@ -133,7 +132,7 @@ impl FileDescription for io::Stderr {
133132
&mut self,
134133
_communicate_allowed: bool,
135134
bytes: &[u8],
136-
_tcx: TyCtxt<'tcx>,
135+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
137136
) -> InterpResult<'tcx, io::Result<usize>> {
138137
// We allow writing to stderr even with isolation enabled.
139138
// No need to flush, stderr is not buffered.
@@ -158,7 +157,7 @@ impl FileDescription for NullOutput {
158157
&mut self,
159158
_communicate_allowed: bool,
160159
bytes: &[u8],
161-
_tcx: TyCtxt<'tcx>,
160+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
162161
) -> InterpResult<'tcx, io::Result<usize>> {
163162
// We just don't write anything, but report to the user that we did.
164163
Ok(Ok(bytes.len()))
@@ -173,6 +172,14 @@ impl FileDescriptor {
173172
FileDescriptor(Rc::new(RefCell::new(Box::new(fd))))
174173
}
175174

175+
pub fn borrow(&self) -> Ref<'_, dyn FileDescription> {
176+
Ref::map(self.0.borrow(), |fd| fd.as_ref())
177+
}
178+
179+
pub fn borrow_mut(&self) -> RefMut<'_, dyn FileDescription> {
180+
RefMut::map(self.0.borrow_mut(), |fd| fd.as_mut())
181+
}
182+
176183
pub fn close<'ctx>(self, communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
177184
// Destroy this `Rc` using `into_inner` so we can call `close` instead of
178185
// implicitly running the destructor of the file description.
@@ -242,12 +249,12 @@ impl FdTable {
242249

243250
pub fn get(&self, fd: i32) -> Option<Ref<'_, dyn FileDescription>> {
244251
let fd = self.fds.get(&fd)?;
245-
Some(Ref::map(fd.0.borrow(), |fd| fd.as_ref()))
252+
Some(fd.borrow())
246253
}
247254

248255
pub fn get_mut(&self, fd: i32) -> Option<RefMut<'_, dyn FileDescription>> {
249256
let fd = self.fds.get(&fd)?;
250-
Some(RefMut::map(fd.0.borrow_mut(), |fd| fd.as_mut()))
257+
Some(fd.borrow_mut())
251258
}
252259

253260
pub fn dup(&self, fd: i32) -> Option<FileDescriptor> {
@@ -370,7 +377,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
370377
.min(u64::try_from(isize::MAX).unwrap());
371378
let communicate = this.machine.communicate();
372379

373-
let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else {
380+
// We temporarily dup the FD to be able to retain mutable access to `this`.
381+
let Some(file_descriptor) = this.machine.fds.dup(fd) else {
374382
trace!("read: FD not found");
375383
return this.fd_not_found();
376384
};
@@ -383,7 +391,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
383391
// `File::read` never returns a value larger than `count`,
384392
// so this cannot fail.
385393
let result = file_descriptor
386-
.read(communicate, &mut bytes, *this.tcx)?
394+
.borrow_mut()
395+
.read(communicate, &mut bytes, this)?
387396
.map(|c| i64::try_from(c).unwrap());
388397
drop(file_descriptor);
389398

@@ -421,12 +430,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
421430
let communicate = this.machine.communicate();
422431

423432
let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?.to_owned();
424-
let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else {
433+
// We temporarily dup the FD to be able to retain mutable access to `this`.
434+
let Some(file_descriptor) = this.machine.fds.dup(fd) else {
425435
return this.fd_not_found();
426436
};
427437

428438
let result = file_descriptor
429-
.write(communicate, &bytes, *this.tcx)?
439+
.borrow_mut()
440+
.write(communicate, &bytes, this)?
430441
.map(|c| i64::try_from(c).unwrap());
431442
drop(file_descriptor);
432443

src/shims/unix/fs.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::path::{Path, PathBuf};
99
use std::time::SystemTime;
1010

1111
use rustc_data_structures::fx::FxHashMap;
12-
use rustc_middle::ty::TyCtxt;
1312
use rustc_target::abi::Size;
1413

1514
use crate::shims::os_str::bytes_to_os_str;
@@ -34,7 +33,7 @@ impl FileDescription for FileHandle {
3433
&mut self,
3534
communicate_allowed: bool,
3635
bytes: &mut [u8],
37-
_tcx: TyCtxt<'tcx>,
36+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
3837
) -> InterpResult<'tcx, io::Result<usize>> {
3938
assert!(communicate_allowed, "isolation should have prevented even opening a file");
4039
Ok(self.file.read(bytes))
@@ -44,7 +43,7 @@ impl FileDescription for FileHandle {
4443
&mut self,
4544
communicate_allowed: bool,
4645
bytes: &[u8],
47-
_tcx: TyCtxt<'tcx>,
46+
_ecx: &mut MiriInterpCx<'_, 'tcx>,
4847
) -> InterpResult<'tcx, io::Result<usize>> {
4948
assert!(communicate_allowed, "isolation should have prevented even opening a file");
5049
Ok(self.file.write(bytes))

src/shims/unix/linux/eventfd.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! Currently just a stub.
33
use std::io;
44

5-
use rustc_middle::ty::TyCtxt;
65
use rustc_target::abi::Endian;
76

87
use crate::shims::unix::*;
@@ -52,11 +51,11 @@ impl FileDescription for Event {
5251
&mut self,
5352
_communicate_allowed: bool,
5453
bytes: &[u8],
55-
tcx: TyCtxt<'tcx>,
54+
ecx: &mut MiriInterpCx<'_, 'tcx>,
5655
) -> InterpResult<'tcx, io::Result<usize>> {
5756
let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size
5857
// Convert from target endianness to host endianness.
59-
let num = match tcx.sess.target.endian {
58+
let num = match ecx.tcx.sess.target.endian {
6059
Endian::Little => u64::from_le_bytes(bytes),
6160
Endian::Big => u64::from_be_bytes(bytes),
6261
};

0 commit comments

Comments
 (0)