@@ -34,21 +34,23 @@ pub trait FileDescription: std::fmt::Debug + Any {
3434 _self_ref : & FileDescriptionRef ,
3535 _communicate_allowed : bool ,
3636 _ptr : Pointer ,
37- _len : u64 ,
37+ _len : usize ,
3838 _dest : & MPlaceTy < ' tcx > ,
3939 _ecx : & mut MiriInterpCx < ' tcx > ,
4040 ) -> InterpResult < ' tcx > {
4141 throw_unsup_format ! ( "cannot read from {}" , self . name( ) ) ;
4242 }
4343
4444 /// Writes as much as possible from the given buffer, and returns the number of bytes written.
45- /// `bytes` is the buffer of bytes supplied by the caller to be written.
45+ /// `ptr` is the pointer to the user supplied read buffer.
46+ /// `len` indicates how many bytes the user requested.
4647 /// `dest` is where the return value should be stored.
4748 fn write < ' tcx > (
4849 & self ,
4950 _self_ref : & FileDescriptionRef ,
5051 _communicate_allowed : bool ,
51- _bytes : & [ u8 ] ,
52+ _ptr : Pointer ,
53+ _len : usize ,
5254 _dest : & MPlaceTy < ' tcx > ,
5355 _ecx : & mut MiriInterpCx < ' tcx > ,
5456 ) -> InterpResult < ' tcx > {
@@ -65,7 +67,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
6567 _communicate_allowed : bool ,
6668 _offset : u64 ,
6769 _ptr : Pointer ,
68- _len : u64 ,
70+ _len : usize ,
6971 _dest : & MPlaceTy < ' tcx > ,
7072 _ecx : & mut MiriInterpCx < ' tcx > ,
7173 ) -> InterpResult < ' tcx > {
@@ -74,12 +76,14 @@ pub trait FileDescription: std::fmt::Debug + Any {
7476
7577 /// Writes as much as possible from the given buffer starting at a given offset,
7678 /// and returns the number of bytes written.
77- /// `bytes` is the buffer of bytes supplied by the caller to be written.
79+ /// `ptr` is the pointer to the user supplied read buffer.
80+ /// `len` indicates how many bytes the user requested.
7881 /// `dest` is where the return value should be stored.
7982 fn pwrite < ' tcx > (
8083 & self ,
8184 _communicate_allowed : bool ,
82- _bytes : & [ u8 ] ,
85+ _ptr : Pointer ,
86+ _len : usize ,
8387 _offset : u64 ,
8488 _dest : & MPlaceTy < ' tcx > ,
8589 _ecx : & mut MiriInterpCx < ' tcx > ,
@@ -142,11 +146,11 @@ impl FileDescription for io::Stdin {
142146 _self_ref : & FileDescriptionRef ,
143147 communicate_allowed : bool ,
144148 ptr : Pointer ,
145- len : u64 ,
149+ len : usize ,
146150 dest : & MPlaceTy < ' tcx > ,
147151 ecx : & mut MiriInterpCx < ' tcx > ,
148152 ) -> InterpResult < ' tcx > {
149- let mut bytes = vec ! [ 0 ; usize :: try_from ( len) . unwrap ( ) ] ;
153+ let mut bytes = vec ! [ 0 ; len] ;
150154 if !communicate_allowed {
151155 // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
152156 helpers:: isolation_abort_error ( "`read` from stdin" ) ?;
@@ -169,12 +173,14 @@ impl FileDescription for io::Stdout {
169173 & self ,
170174 _self_ref : & FileDescriptionRef ,
171175 _communicate_allowed : bool ,
172- bytes : & [ u8 ] ,
176+ ptr : Pointer ,
177+ len : usize ,
173178 dest : & MPlaceTy < ' tcx > ,
174179 ecx : & mut MiriInterpCx < ' tcx > ,
175180 ) -> InterpResult < ' tcx > {
181+ let bytes = ecx. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?. to_owned ( ) ;
176182 // We allow writing to stderr even with isolation enabled.
177- let result = Write :: write ( & mut { self } , bytes) ;
183+ let result = Write :: write ( & mut { self } , & bytes) ;
178184 // Stdout is buffered, flush to make sure it appears on the
179185 // screen. This is the write() syscall of the interpreted
180186 // program, we want it to correspond to a write() syscall on
@@ -198,13 +204,15 @@ impl FileDescription for io::Stderr {
198204 & self ,
199205 _self_ref : & FileDescriptionRef ,
200206 _communicate_allowed : bool ,
201- bytes : & [ u8 ] ,
207+ ptr : Pointer ,
208+ len : usize ,
202209 dest : & MPlaceTy < ' tcx > ,
203210 ecx : & mut MiriInterpCx < ' tcx > ,
204211 ) -> InterpResult < ' tcx > {
212+ let bytes = ecx. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?. to_owned ( ) ;
205213 // We allow writing to stderr even with isolation enabled.
206214 // No need to flush, stderr is not buffered.
207- let result = Write :: write ( & mut { self } , bytes) ;
215+ let result = Write :: write ( & mut { self } , & bytes) ;
208216 ecx. return_written_byte_count_or_error ( result, dest)
209217 }
210218
@@ -226,12 +234,13 @@ impl FileDescription for NullOutput {
226234 & self ,
227235 _self_ref : & FileDescriptionRef ,
228236 _communicate_allowed : bool ,
229- bytes : & [ u8 ] ,
237+ _ptr : Pointer ,
238+ len : usize ,
230239 dest : & MPlaceTy < ' tcx > ,
231240 ecx : & mut MiriInterpCx < ' tcx > ,
232241 ) -> InterpResult < ' tcx > {
233242 // We just don't write anything, but report to the user that we did.
234- let result = Ok ( bytes . len ( ) ) ;
243+ let result = Ok ( len) ;
235244 ecx. return_written_byte_count_or_error ( result, dest)
236245 }
237246}
@@ -591,15 +600,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
591600 // `usize::MAX` because it is bounded by the host's `isize`.
592601
593602 match offset {
594- None => fd. read ( & fd, communicate, buf, count, dest, this) ?,
603+ None => fd. read ( & fd, communicate, buf, usize :: try_from ( count) . unwrap ( ) , dest, this) ?,
595604 Some ( offset) => {
596605 let Ok ( offset) = u64:: try_from ( offset) else {
597606 let einval = this. eval_libc ( "EINVAL" ) ;
598607 this. set_last_error ( einval) ?;
599608 this. write_int ( -1 , dest) ?;
600609 return Ok ( ( ) ) ;
601610 } ;
602- fd. pread ( communicate, offset, buf, count, dest, this) ?
611+ fd. pread ( communicate, offset, buf, usize :: try_from ( count) . unwrap ( ) , dest, this) ?
603612 }
604613 } ;
605614 Ok ( ( ) )
@@ -627,7 +636,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
627636 . min ( u64:: try_from ( isize:: MAX ) . unwrap ( ) ) ;
628637 let communicate = this. machine . communicate ( ) ;
629638
630- let bytes = this. read_bytes_ptr_strip_provenance ( buf, Size :: from_bytes ( count) ) ?. to_owned ( ) ;
631639 // We temporarily dup the FD to be able to retain mutable access to `this`.
632640 let Some ( fd) = this. machine . fds . get ( fd_num) else {
633641 let res: i32 = this. fd_not_found ( ) ?;
@@ -636,15 +644,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
636644 } ;
637645
638646 match offset {
639- None => fd. write ( & fd, communicate, & bytes , dest, this) ?,
647+ None => fd. write ( & fd, communicate, buf , usize :: try_from ( count ) . unwrap ( ) , dest, this) ?,
640648 Some ( offset) => {
641649 let Ok ( offset) = u64:: try_from ( offset) else {
642650 let einval = this. eval_libc ( "EINVAL" ) ;
643651 this. set_last_error ( einval) ?;
644652 this. write_int ( -1 , dest) ?;
645653 return Ok ( ( ) ) ;
646654 } ;
647- fd. pwrite ( communicate, & bytes , offset, dest, this) ?
655+ fd. pwrite ( communicate, buf , usize :: try_from ( count ) . unwrap ( ) , offset, dest, this) ?
648656 }
649657 } ;
650658 Ok ( ( ) )
0 commit comments