@@ -2,7 +2,7 @@ use std::collections::BTreeSet;
22use std:: num:: NonZero ;
33use std:: sync:: Mutex ;
44use std:: time:: Duration ;
5- use std:: { cmp, io , iter} ;
5+ use std:: { cmp, iter} ;
66
77use rand:: RngCore ;
88use rustc_apfloat:: Float ;
@@ -31,65 +31,6 @@ pub enum AccessKind {
3131 Write ,
3232}
3333
34- // This mapping should match `decode_error_kind` in
35- // <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs>.
36- const UNIX_IO_ERROR_TABLE : & [ ( & str , std:: io:: ErrorKind ) ] = {
37- use std:: io:: ErrorKind :: * ;
38- & [
39- ( "E2BIG" , ArgumentListTooLong ) ,
40- ( "EADDRINUSE" , AddrInUse ) ,
41- ( "EADDRNOTAVAIL" , AddrNotAvailable ) ,
42- ( "EBUSY" , ResourceBusy ) ,
43- ( "ECONNABORTED" , ConnectionAborted ) ,
44- ( "ECONNREFUSED" , ConnectionRefused ) ,
45- ( "ECONNRESET" , ConnectionReset ) ,
46- ( "EDEADLK" , Deadlock ) ,
47- ( "EDQUOT" , FilesystemQuotaExceeded ) ,
48- ( "EEXIST" , AlreadyExists ) ,
49- ( "EFBIG" , FileTooLarge ) ,
50- ( "EHOSTUNREACH" , HostUnreachable ) ,
51- ( "EINTR" , Interrupted ) ,
52- ( "EINVAL" , InvalidInput ) ,
53- ( "EISDIR" , IsADirectory ) ,
54- ( "ELOOP" , FilesystemLoop ) ,
55- ( "ENOENT" , NotFound ) ,
56- ( "ENOMEM" , OutOfMemory ) ,
57- ( "ENOSPC" , StorageFull ) ,
58- ( "ENOSYS" , Unsupported ) ,
59- ( "EMLINK" , TooManyLinks ) ,
60- ( "ENAMETOOLONG" , InvalidFilename ) ,
61- ( "ENETDOWN" , NetworkDown ) ,
62- ( "ENETUNREACH" , NetworkUnreachable ) ,
63- ( "ENOTCONN" , NotConnected ) ,
64- ( "ENOTDIR" , NotADirectory ) ,
65- ( "ENOTEMPTY" , DirectoryNotEmpty ) ,
66- ( "EPIPE" , BrokenPipe ) ,
67- ( "EROFS" , ReadOnlyFilesystem ) ,
68- ( "ESPIPE" , NotSeekable ) ,
69- ( "ESTALE" , StaleNetworkFileHandle ) ,
70- ( "ETIMEDOUT" , TimedOut ) ,
71- ( "ETXTBSY" , ExecutableFileBusy ) ,
72- ( "EXDEV" , CrossesDevices ) ,
73- // The following have two valid options. We have both for the forwards mapping; only the
74- // first one will be used for the backwards mapping.
75- ( "EPERM" , PermissionDenied ) ,
76- ( "EACCES" , PermissionDenied ) ,
77- ( "EWOULDBLOCK" , WouldBlock ) ,
78- ( "EAGAIN" , WouldBlock ) ,
79- ]
80- } ;
81- // This mapping should match `decode_error_kind` in
82- // <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/windows/mod.rs>.
83- const WINDOWS_IO_ERROR_TABLE : & [ ( & str , std:: io:: ErrorKind ) ] = {
84- use std:: io:: ErrorKind :: * ;
85- // FIXME: this is still incomplete.
86- & [
87- ( "ERROR_ACCESS_DENIED" , PermissionDenied ) ,
88- ( "ERROR_FILE_NOT_FOUND" , NotFound ) ,
89- ( "ERROR_INVALID_PARAMETER" , InvalidInput ) ,
90- ]
91- } ;
92-
9334/// Gets an instance for a path.
9435///
9536/// A `None` namespace indicates we are looking for a module.
@@ -745,130 +686,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
745686 self . eval_context_ref ( ) . tcx . sess . target . families . iter ( ) . any ( |f| f == "unix" )
746687 }
747688
748- /// Get last error variable as a place, lazily allocating thread-local storage for it if
749- /// necessary.
750- fn last_error_place ( & mut self ) -> InterpResult < ' tcx , MPlaceTy < ' tcx > > {
751- let this = self . eval_context_mut ( ) ;
752- if let Some ( errno_place) = this. active_thread_ref ( ) . last_error . as_ref ( ) {
753- Ok ( errno_place. clone ( ) )
754- } else {
755- // Allocate new place, set initial value to 0.
756- let errno_layout = this. machine . layouts . u32 ;
757- let errno_place = this. allocate ( errno_layout, MiriMemoryKind :: Machine . into ( ) ) ?;
758- this. write_scalar ( Scalar :: from_u32 ( 0 ) , & errno_place) ?;
759- this. active_thread_mut ( ) . last_error = Some ( errno_place. clone ( ) ) ;
760- Ok ( errno_place)
761- }
762- }
763-
764- /// Sets the last error variable.
765- fn set_last_error ( & mut self , scalar : Scalar ) -> InterpResult < ' tcx > {
766- let this = self . eval_context_mut ( ) ;
767- let errno_place = this. last_error_place ( ) ?;
768- this. write_scalar ( scalar, & errno_place)
769- }
770-
771- /// Gets the last error variable.
772- fn get_last_error ( & mut self ) -> InterpResult < ' tcx , Scalar > {
773- let this = self . eval_context_mut ( ) ;
774- let errno_place = this. last_error_place ( ) ?;
775- this. read_scalar ( & errno_place)
776- }
777-
778- /// This function tries to produce the most similar OS error from the `std::io::ErrorKind`
779- /// as a platform-specific errnum.
780- fn io_error_to_errnum ( & self , err : std:: io:: Error ) -> InterpResult < ' tcx , Scalar > {
781- let this = self . eval_context_ref ( ) ;
782- let target = & this. tcx . sess . target ;
783- if target. families . iter ( ) . any ( |f| f == "unix" ) {
784- for & ( name, kind) in UNIX_IO_ERROR_TABLE {
785- if err. kind ( ) == kind {
786- return Ok ( this. eval_libc ( name) ) ;
787- }
788- }
789- throw_unsup_format ! ( "unsupported io error: {err}" )
790- } else if target. families . iter ( ) . any ( |f| f == "windows" ) {
791- for & ( name, kind) in WINDOWS_IO_ERROR_TABLE {
792- if err. kind ( ) == kind {
793- return Ok ( this. eval_windows ( "c" , name) ) ;
794- }
795- }
796- throw_unsup_format ! ( "unsupported io error: {err}" ) ;
797- } else {
798- throw_unsup_format ! (
799- "converting io::Error into errnum is unsupported for OS {}" ,
800- target. os
801- )
802- }
803- }
804-
805- /// The inverse of `io_error_to_errnum`.
806- #[ allow( clippy:: needless_return) ]
807- fn try_errnum_to_io_error (
808- & self ,
809- errnum : Scalar ,
810- ) -> InterpResult < ' tcx , Option < std:: io:: ErrorKind > > {
811- let this = self . eval_context_ref ( ) ;
812- let target = & this. tcx . sess . target ;
813- if target. families . iter ( ) . any ( |f| f == "unix" ) {
814- let errnum = errnum. to_i32 ( ) ?;
815- for & ( name, kind) in UNIX_IO_ERROR_TABLE {
816- if errnum == this. eval_libc_i32 ( name) {
817- return Ok ( Some ( kind) ) ;
818- }
819- }
820- return Ok ( None ) ;
821- } else if target. families . iter ( ) . any ( |f| f == "windows" ) {
822- let errnum = errnum. to_u32 ( ) ?;
823- for & ( name, kind) in WINDOWS_IO_ERROR_TABLE {
824- if errnum == this. eval_windows ( "c" , name) . to_u32 ( ) ? {
825- return Ok ( Some ( kind) ) ;
826- }
827- }
828- return Ok ( None ) ;
829- } else {
830- throw_unsup_format ! (
831- "converting errnum into io::Error is unsupported for OS {}" ,
832- target. os
833- )
834- }
835- }
836-
837- /// Sets the last OS error using a `std::io::ErrorKind`.
838- fn set_last_error_from_io_error ( & mut self , err : std:: io:: Error ) -> InterpResult < ' tcx > {
839- self . set_last_error ( self . io_error_to_errnum ( err) ?)
840- }
841-
842- /// Sets the last OS error using a `std::io::ErrorKind` and writes -1 to dest place.
843- fn set_last_error_and_return (
844- & mut self ,
845- err : impl Into < io:: Error > ,
846- dest : & MPlaceTy < ' tcx > ,
847- ) -> InterpResult < ' tcx > {
848- self . set_last_error ( self . io_error_to_errnum ( err. into ( ) ) ?) ?;
849- self . write_int ( -1 , dest) ?;
850- Ok ( ( ) )
851- }
852-
853- /// Helper function that consumes an `std::io::Result<T>` and returns an
854- /// `InterpResult<'tcx,T>::Ok` instead. In case the result is an error, this function returns
855- /// `Ok(-1)` and sets the last OS error accordingly.
856- ///
857- /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
858- /// functions return different integer types (like `read`, that returns an `i64`).
859- fn try_unwrap_io_result < T : From < i32 > > (
860- & mut self ,
861- result : std:: io:: Result < T > ,
862- ) -> InterpResult < ' tcx , T > {
863- match result {
864- Ok ( ok) => Ok ( ok) ,
865- Err ( e) => {
866- self . eval_context_mut ( ) . set_last_error_from_io_error ( e) ?;
867- Ok ( ( -1 ) . into ( ) )
868- }
869- }
870- }
871-
872689 /// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
873690 fn deref_pointer_as (
874691 & self ,
0 commit comments