11use std:: collections:: HashMap ;
2+ use std:: convert:: TryFrom ;
23use std:: fs:: { remove_file, File , OpenOptions } ;
34use std:: io:: { Read , Write } ;
4- use std:: convert:: TryFrom ;
55
66use rustc:: ty:: layout:: Size ;
77
@@ -166,7 +166,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
166166
167167 this. check_no_isolation ( "read" ) ?;
168168
169- let count = this. read_scalar ( count_op) ?. to_machine_usize ( & * this. tcx ) ?;
169+ let ptr_size = this. pointer_size ( ) . bits ( ) ;
170+
171+ let count = this
172+ . read_scalar ( count_op) ?
173+ . to_machine_usize ( & * this. tcx ) ?
174+ . min ( 1 << ( ptr_size - 1 ) ) ;
170175 // Reading zero bytes should not change `buf`.
171176 if count == 0 {
172177 return Ok ( 0 ) ;
@@ -175,22 +180,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
175180 let buf = this. read_scalar ( buf_op) ?. not_undef ( ) ?;
176181
177182 if let Some ( handle) = this. machine . file_handler . handles . get_mut ( & fd) {
178- let count = isize:: try_from ( count)
179- . map_err ( |_| err_unsup_format ! ( "Program tries to read into buffer too big for this host platform" ) ) ?;
183+ let count = isize:: try_from ( count) . unwrap ( ) ;
180184 // We want to read at most `count` bytes. We are sure that `count` is not negative
181185 // because it was a target's `usize`. Also we are sure that its smaller than
182186 // `usize::max_value()` because it is a host's `isize`.
183187 let mut bytes = vec ! [ 0 ; count as usize ] ;
184- let result = handle. file . read ( & mut bytes) ;
188+ let result = handle
189+ . file
190+ . read ( & mut bytes)
191+ . map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
185192
186193 match result {
187- Ok ( c) => {
188- let read_bytes = i64:: try_from ( c)
189- . map_err ( |_| err_unsup_format ! ( "Number of read bytes {} cannot be transformed to i64" , c) ) ?;
194+ Ok ( read_bytes) => {
190195 // If reading to `bytes` did not fail, we write those bytes to the buffer.
191196 this. memory . write_bytes ( buf, bytes) ?;
192197 Ok ( read_bytes)
193- } ,
198+ }
194199 Err ( e) => {
195200 this. set_last_error_from_io_error ( e) ?;
196201 Ok ( -1 )
@@ -211,7 +216,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
211216
212217 this. check_no_isolation ( "write" ) ?;
213218
214- let count = this. read_scalar ( count_op) ?. to_machine_usize ( & * this. tcx ) ?;
219+ let ptr_size = this. pointer_size ( ) . bits ( ) ;
220+
221+ let count = this
222+ . read_scalar ( count_op) ?
223+ . to_machine_usize ( & * this. tcx ) ?
224+ . min ( 1 << ( ptr_size - 1 ) ) ;
215225 // Writing zero bytes should not change `buf`.
216226 if count == 0 {
217227 return Ok ( 0 ) ;
@@ -221,16 +231,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
221231
222232 if let Some ( handle) = this. machine . file_handler . handles . get_mut ( & fd) {
223233 let bytes = this. memory . read_bytes ( buf, Size :: from_bytes ( count) ) ?;
224- let result = handle. file . write ( & bytes) ;
225-
226- match result {
227- Ok ( c) => i64:: try_from ( c)
228- . map_err ( |_| err_unsup_format ! ( "Number of written bytes {} cannot be transformed to i64" , c) . into ( ) ) ,
229- Err ( e) => {
230- this. set_last_error_from_io_error ( e) ?;
231- Ok ( -1 )
232- }
233- }
234+ let result = handle. file . write ( & bytes) . map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
235+ this. try_unwrap_io_result ( result)
234236 } else {
235237 this. handle_not_found ( )
236238 }
0 commit comments