@@ -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,119 +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- interp_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- interp_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 interp_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 interp_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 interp_ok ( Some ( kind) ) ;
818- }
819- }
820- return interp_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 interp_ok ( Some ( kind) ) ;
826- }
827- }
828- return interp_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- /// Helper function that consumes a `std::io::Result<T>` and returns a
843- /// `InterpResult<'tcx, T>` instead. In case the result is an error, this function returns
844- /// `Ok(-1)` and sets the last OS error accordingly.
845- ///
846- /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
847- /// functions return different integer types (like `read`, that returns an `i64`).
848- fn try_unwrap_io_result < T : From < i32 > > (
849- & mut self ,
850- result : std:: io:: Result < T > ,
851- ) -> InterpResult < ' tcx , T > {
852- match result {
853- Ok ( ok) => interp_ok ( ok) ,
854- Err ( e) => {
855- self . eval_context_mut ( ) . set_last_error_from_io_error ( e) ?;
856- interp_ok ( ( -1 ) . into ( ) )
857- }
858- }
859- }
860-
861689 /// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
862690 fn deref_pointer_as (
863691 & self ,
@@ -924,17 +752,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
924752 let nanoseconds_scalar = this. read_scalar ( & nanoseconds_place) ?;
925753 let nanoseconds = nanoseconds_scalar. to_target_isize ( this) ?;
926754
927- interp_ok ( try {
928- // tv_sec must be non-negative.
929- let seconds: u64 = seconds. try_into ( ) . ok ( ) ?;
930- // tv_nsec must be non-negative.
931- let nanoseconds: u32 = nanoseconds. try_into ( ) . ok ( ) ?;
932- if nanoseconds >= 1_000_000_000 {
933- // tv_nsec must not be greater than 999,999,999.
934- None ?
935- }
936- Duration :: new ( seconds, nanoseconds)
937- } )
755+ interp_ok (
756+ try {
757+ // tv_sec must be non-negative.
758+ let seconds: u64 = seconds. try_into ( ) . ok ( ) ?;
759+ // tv_nsec must be non-negative.
760+ let nanoseconds: u32 = nanoseconds. try_into ( ) . ok ( ) ?;
761+ if nanoseconds >= 1_000_000_000 {
762+ // tv_nsec must not be greater than 999,999,999.
763+ None ?
764+ }
765+ Duration :: new ( seconds, nanoseconds)
766+ } ,
767+ )
938768 }
939769
940770 /// Read bytes from a byte slice.
0 commit comments