@@ -34,21 +34,23 @@ pub trait FileDescription: std::fmt::Debug + Any {
34
34
_self_ref : & FileDescriptionRef ,
35
35
_communicate_allowed : bool ,
36
36
_ptr : Pointer ,
37
- _len : u64 ,
37
+ _len : usize ,
38
38
_dest : & MPlaceTy < ' tcx > ,
39
39
_ecx : & mut MiriInterpCx < ' tcx > ,
40
40
) -> InterpResult < ' tcx > {
41
41
throw_unsup_format ! ( "cannot read from {}" , self . name( ) ) ;
42
42
}
43
43
44
44
/// 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.
46
47
/// `dest` is where the return value should be stored.
47
48
fn write < ' tcx > (
48
49
& self ,
49
50
_self_ref : & FileDescriptionRef ,
50
51
_communicate_allowed : bool ,
51
- _bytes : & [ u8 ] ,
52
+ _ptr : Pointer ,
53
+ _len : usize ,
52
54
_dest : & MPlaceTy < ' tcx > ,
53
55
_ecx : & mut MiriInterpCx < ' tcx > ,
54
56
) -> InterpResult < ' tcx > {
@@ -65,7 +67,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
65
67
_communicate_allowed : bool ,
66
68
_offset : u64 ,
67
69
_ptr : Pointer ,
68
- _len : u64 ,
70
+ _len : usize ,
69
71
_dest : & MPlaceTy < ' tcx > ,
70
72
_ecx : & mut MiriInterpCx < ' tcx > ,
71
73
) -> InterpResult < ' tcx > {
@@ -74,12 +76,14 @@ pub trait FileDescription: std::fmt::Debug + Any {
74
76
75
77
/// Writes as much as possible from the given buffer starting at a given offset,
76
78
/// 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.
78
81
/// `dest` is where the return value should be stored.
79
82
fn pwrite < ' tcx > (
80
83
& self ,
81
84
_communicate_allowed : bool ,
82
- _bytes : & [ u8 ] ,
85
+ _ptr : Pointer ,
86
+ _len : usize ,
83
87
_offset : u64 ,
84
88
_dest : & MPlaceTy < ' tcx > ,
85
89
_ecx : & mut MiriInterpCx < ' tcx > ,
@@ -142,11 +146,11 @@ impl FileDescription for io::Stdin {
142
146
_self_ref : & FileDescriptionRef ,
143
147
communicate_allowed : bool ,
144
148
ptr : Pointer ,
145
- len : u64 ,
149
+ len : usize ,
146
150
dest : & MPlaceTy < ' tcx > ,
147
151
ecx : & mut MiriInterpCx < ' tcx > ,
148
152
) -> InterpResult < ' tcx > {
149
- let mut bytes = vec ! [ 0 ; usize :: try_from ( len) . unwrap ( ) ] ;
153
+ let mut bytes = vec ! [ 0 ; len] ;
150
154
if !communicate_allowed {
151
155
// We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
152
156
helpers:: isolation_abort_error ( "`read` from stdin" ) ?;
@@ -169,12 +173,14 @@ impl FileDescription for io::Stdout {
169
173
& self ,
170
174
_self_ref : & FileDescriptionRef ,
171
175
_communicate_allowed : bool ,
172
- bytes : & [ u8 ] ,
176
+ ptr : Pointer ,
177
+ len : usize ,
173
178
dest : & MPlaceTy < ' tcx > ,
174
179
ecx : & mut MiriInterpCx < ' tcx > ,
175
180
) -> InterpResult < ' tcx > {
181
+ let bytes = ecx. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?. to_owned ( ) ;
176
182
// 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) ;
178
184
// Stdout is buffered, flush to make sure it appears on the
179
185
// screen. This is the write() syscall of the interpreted
180
186
// program, we want it to correspond to a write() syscall on
@@ -198,13 +204,15 @@ impl FileDescription for io::Stderr {
198
204
& self ,
199
205
_self_ref : & FileDescriptionRef ,
200
206
_communicate_allowed : bool ,
201
- bytes : & [ u8 ] ,
207
+ ptr : Pointer ,
208
+ len : usize ,
202
209
dest : & MPlaceTy < ' tcx > ,
203
210
ecx : & mut MiriInterpCx < ' tcx > ,
204
211
) -> InterpResult < ' tcx > {
212
+ let bytes = ecx. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?. to_owned ( ) ;
205
213
// We allow writing to stderr even with isolation enabled.
206
214
// No need to flush, stderr is not buffered.
207
- let result = Write :: write ( & mut { self } , bytes) ;
215
+ let result = Write :: write ( & mut { self } , & bytes) ;
208
216
ecx. return_written_byte_count_or_error ( result, dest)
209
217
}
210
218
@@ -226,12 +234,13 @@ impl FileDescription for NullOutput {
226
234
& self ,
227
235
_self_ref : & FileDescriptionRef ,
228
236
_communicate_allowed : bool ,
229
- bytes : & [ u8 ] ,
237
+ _ptr : Pointer ,
238
+ len : usize ,
230
239
dest : & MPlaceTy < ' tcx > ,
231
240
ecx : & mut MiriInterpCx < ' tcx > ,
232
241
) -> InterpResult < ' tcx > {
233
242
// 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) ;
235
244
ecx. return_written_byte_count_or_error ( result, dest)
236
245
}
237
246
}
@@ -591,15 +600,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
591
600
// `usize::MAX` because it is bounded by the host's `isize`.
592
601
593
602
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) ?,
595
604
Some ( offset) => {
596
605
let Ok ( offset) = u64:: try_from ( offset) else {
597
606
let einval = this. eval_libc ( "EINVAL" ) ;
598
607
this. set_last_error ( einval) ?;
599
608
this. write_int ( -1 , dest) ?;
600
609
return Ok ( ( ) ) ;
601
610
} ;
602
- fd. pread ( communicate, offset, buf, count, dest, this) ?
611
+ fd. pread ( communicate, offset, buf, usize :: try_from ( count) . unwrap ( ) , dest, this) ?
603
612
}
604
613
} ;
605
614
Ok ( ( ) )
@@ -627,7 +636,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
627
636
. min ( u64:: try_from ( isize:: MAX ) . unwrap ( ) ) ;
628
637
let communicate = this. machine . communicate ( ) ;
629
638
630
- let bytes = this. read_bytes_ptr_strip_provenance ( buf, Size :: from_bytes ( count) ) ?. to_owned ( ) ;
631
639
// We temporarily dup the FD to be able to retain mutable access to `this`.
632
640
let Some ( fd) = this. machine . fds . get ( fd_num) else {
633
641
let res: i32 = this. fd_not_found ( ) ?;
@@ -636,15 +644,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
636
644
} ;
637
645
638
646
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) ?,
640
648
Some ( offset) => {
641
649
let Ok ( offset) = u64:: try_from ( offset) else {
642
650
let einval = this. eval_libc ( "EINVAL" ) ;
643
651
this. set_last_error ( einval) ?;
644
652
this. write_int ( -1 , dest) ?;
645
653
return Ok ( ( ) ) ;
646
654
} ;
647
- fd. pwrite ( communicate, & bytes , offset, dest, this) ?
655
+ fd. pwrite ( communicate, buf , usize :: try_from ( count ) . unwrap ( ) , offset, dest, this) ?
648
656
}
649
657
} ;
650
658
Ok ( ( ) )
0 commit comments