about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/miri/src/shims/unix/fd.rs26
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs4
-rw-r--r--src/tools/miri/src/shims/unix/unnamed_socket.rs8
3 files changed, 25 insertions, 13 deletions
diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs
index 5f719991b37..4b87ce60c8b 100644
--- a/src/tools/miri/src/shims/unix/fd.rs
+++ b/src/tools/miri/src/shims/unix/fd.rs
@@ -26,7 +26,9 @@ pub trait FileDescription: std::fmt::Debug + Any {
     fn name(&self) -> &'static str;
 
     /// Reads as much as possible into the given buffer, and returns the number of bytes read.
-    /// `ptr` is the pointer to user supplied read buffer.
+    /// `ptr` is the pointer to the user supplied read buffer.
+    /// `len` indicates how many bytes the user requested.
+    /// `dest` is where the return value should be stored.
     fn read<'tcx>(
         &self,
         _self_ref: &FileDescriptionRef,
@@ -40,6 +42,8 @@ pub trait FileDescription: std::fmt::Debug + Any {
     }
 
     /// Writes as much as possible from the given buffer, and returns the number of bytes written.
+    /// `bytes` is the buffer of bytes supplied by the caller to be written.
+    /// `dest` is where the return value should be stored.
     fn write<'tcx>(
         &self,
         _self_ref: &FileDescriptionRef,
@@ -53,6 +57,9 @@ pub trait FileDescription: std::fmt::Debug + Any {
 
     /// Reads as much as possible into the given buffer from a given offset,
     /// and returns the number of bytes read.
+    /// `ptr` is the pointer to the user supplied read buffer.
+    /// `len` indicates how many bytes the user requested.
+    /// `dest` is where the return value should be stored.
     fn pread<'tcx>(
         &self,
         _communicate_allowed: bool,
@@ -67,6 +74,8 @@ pub trait FileDescription: std::fmt::Debug + Any {
 
     /// Writes as much as possible from the given buffer starting at a given offset,
     /// and returns the number of bytes written.
+    /// `bytes` is the buffer of bytes supplied by the caller to be written.
+    /// `dest` is where the return value should be stored.
     fn pwrite<'tcx>(
         &self,
         _communicate_allowed: bool,
@@ -143,7 +152,7 @@ impl FileDescription for io::Stdin {
             helpers::isolation_abort_error("`read` from stdin")?;
         }
         let result = Read::read(&mut { self }, &mut bytes);
-        ecx.return_read_bytes_and_count(ptr, bytes, result, dest)
+        ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
     }
 
     fn is_tty(&self, communicate_allowed: bool) -> bool {
@@ -641,12 +650,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         Ok(())
     }
 
-    /// This function either writes to the user supplied buffer and to dest place, or sets the
-    /// last libc error and writes -1 to dest.
+    /// Helper to implement `FileDescription::read`:
+    /// `result` should be the return value of some underlying `read` call that used `bytes` as its output buffer.
+    /// The length of `bytes` must not exceed either the host's or the target's `isize`.
+    /// If `Result` indicates success, `bytes` is written to `buf` and the size is written to `dest`.
+    /// Otherwise, `-1` is written to `dest` and the last libc error is set appropriately.
     fn return_read_bytes_and_count(
         &mut self,
         buf: Pointer,
-        bytes: Vec<u8>,
+        bytes: &[u8],
         result: io::Result<usize>,
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx> {
@@ -657,7 +669,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Crucially, if fewer than `bytes.len()` bytes were read, only write
                 // that much into the output buffer!
                 this.write_bytes_ptr(buf, bytes[..read_bytes].iter().copied())?;
-                // The actual read size is always lesser than `count` so this cannot fail.
+                // The actual read size is always less than what got originally requested so this cannot fail.
                 this.write_int(u64::try_from(read_bytes).unwrap(), dest)?;
                 return Ok(());
             }
@@ -669,7 +681,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
     }
 
-    /// This function writes the number of written bytes to dest place, or sets the
+    /// This function writes the number of written bytes (given in `result`) to `dest`, or sets the
     /// last libc error and writes -1 to dest.
     fn return_written_byte_count_or_error(
         &mut self,
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index cf709d5e6da..e1ac9b0adfb 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -42,7 +42,7 @@ impl FileDescription for FileHandle {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
         let mut bytes = vec![0; usize::try_from(len).unwrap()];
         let result = (&mut &self.file).read(&mut bytes);
-        ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
+        ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
     }
 
     fn write<'tcx>(
@@ -83,7 +83,7 @@ impl FileDescription for FileHandle {
             res
         };
         let result = f();
-        ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
+        ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
     }
 
     fn pwrite<'tcx>(
diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs
index 76350254e30..d5b061ea3cd 100644
--- a/src/tools/miri/src/shims/unix/unnamed_socket.rs
+++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs
@@ -137,7 +137,7 @@ impl FileDescription for AnonSocket {
         // Always succeed on read size 0.
         if request_byte_size == 0 {
             let result = Ok(0);
-            return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
+            return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
         }
 
         let Some(readbuf) = &self.readbuf else {
@@ -151,7 +151,7 @@ impl FileDescription for AnonSocket {
                 // Socketpair with no peer and empty buffer.
                 // 0 bytes successfully read indicates end-of-file.
                 let result = Ok(0);
-                return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
+                return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
             } else {
                 if self.is_nonblock {
                     // Non-blocking socketpair with writer and empty buffer.
@@ -160,7 +160,7 @@ impl FileDescription for AnonSocket {
                     // POSIX.1-2001 allows either error to be returned for this case.
                     // Since there is no ErrorKind for EAGAIN, WouldBlock is used.
                     let result = Err(Error::from(ErrorKind::WouldBlock));
-                    return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
+                    return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
                 } else {
                     // Blocking socketpair with writer and empty buffer.
                     // FIXME: blocking is currently not supported
@@ -193,7 +193,7 @@ impl FileDescription for AnonSocket {
         }
 
         let result = Ok(actual_read_size);
-        ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
+        ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
     }
 
     fn write<'tcx>(