From 9154f8b22c56c071e78e1f3d706fd75f43ff218c Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Wed, 3 Aug 2022 10:39:43 -0400 Subject: [PATCH 1/2] Add additional raw error mappings for the nightly `io_error_more` feature Some crates are using nightly and failing when mapping these errors, for example : ``` error: unsupported operation: io error NotADirectory cannot be translated into a raw os error --> /root/.rustup/toolchains/miri/lib/rustlib/src/rust/library/std/src/sys/unix/fs.rs:1203:19 ``` --- src/helpers.rs | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index acc2367afa2..ee2c39b5115 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -23,26 +23,49 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} +// This mapping is the reverse of `decode_error_kind` in +// +// and should be kept in sync. const UNIX_IO_ERROR_TABLE: &[(std::io::ErrorKind, &str)] = { use std::io::ErrorKind::*; &[ + (ArgumentListTooLong, "E2BIG"), + (AddrInUse, "EADDRINUSE"), + (AddrNotAvailable, "EADDRNOTAVAIL"), + (ResourceBusy, "EBUSY"), + (ConnectionAborted, "ECONNABORTED"), (ConnectionRefused, "ECONNREFUSED"), (ConnectionReset, "ECONNRESET"), - (PermissionDenied, "EPERM"), - (BrokenPipe, "EPIPE"), - (NotConnected, "ENOTCONN"), - (ConnectionAborted, "ECONNABORTED"), - (AddrNotAvailable, "EADDRNOTAVAIL"), - (AddrInUse, "EADDRINUSE"), - (NotFound, "ENOENT"), + (Deadlock, "EDEADLK"), + (FilesystemQuotaExceeded, "EDQUOT"), + (AlreadyExists, "EEXIST"), + (FileTooLarge, "EFBIG"), + (HostUnreachable, "EHOSTUNREACH"), (Interrupted, "EINTR"), (InvalidInput, "EINVAL"), - (InvalidFilename, "ENAMETOOLONG"), - (TimedOut, "ETIMEDOUT"), - (AlreadyExists, "EEXIST"), - (WouldBlock, "EWOULDBLOCK"), - (DirectoryNotEmpty, "ENOTEMPTY"), + (IsADirectory, "EISDIR"), (FilesystemLoop, "ELOOP"), + (NotFound, "ENOENT"), + (OutOfMemory, "ENOMEM"), + (StorageFull, "ENOSPC"), + (Unsupported, "ENOSYS"), + (TooManyLinks, "EMLINK"), + (InvalidFilename, "ENAMETOOLONG"), + (NetworkDown, "ENETDOWN"), + (NetworkUnreachable, "ENETUNREACH"), + (NotConnected, "ENOTCONN"), + (NotADirectory, "ENOTDIR"), + (DirectoryNotEmpty, "ENOTEMPTY"), + (BrokenPipe, "EPIPE"), + (ReadOnlyFilesystem, "EROFS"), + (NotSeekable, "ESPIPE"), + (StaleNetworkFileHandle, "ESTALE"), + (TimedOut, "ETIMEDOUT"), + (ExecutableFileBusy, "ETXTBSY"), + (CrossesDevices, "EXDEV"), + // The following have two valid options...we pick one. + (PermissionDenied, "EPERM"), + (WouldBlock, "EWOULDBLOCK"), ] }; From e1e1f42f39801c4f9195443fc5f1ac6e8505310e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 3 Aug 2022 11:51:39 -0400 Subject: [PATCH 2/2] make errno table syntactically more similar to rustc library code --- src/helpers.rs | 88 ++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index ee2c39b5115..8523af84d06 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -23,49 +23,51 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} -// This mapping is the reverse of `decode_error_kind` in -// -// and should be kept in sync. -const UNIX_IO_ERROR_TABLE: &[(std::io::ErrorKind, &str)] = { +// This mapping should match `decode_error_kind` in +// . +const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = { use std::io::ErrorKind::*; &[ - (ArgumentListTooLong, "E2BIG"), - (AddrInUse, "EADDRINUSE"), - (AddrNotAvailable, "EADDRNOTAVAIL"), - (ResourceBusy, "EBUSY"), - (ConnectionAborted, "ECONNABORTED"), - (ConnectionRefused, "ECONNREFUSED"), - (ConnectionReset, "ECONNRESET"), - (Deadlock, "EDEADLK"), - (FilesystemQuotaExceeded, "EDQUOT"), - (AlreadyExists, "EEXIST"), - (FileTooLarge, "EFBIG"), - (HostUnreachable, "EHOSTUNREACH"), - (Interrupted, "EINTR"), - (InvalidInput, "EINVAL"), - (IsADirectory, "EISDIR"), - (FilesystemLoop, "ELOOP"), - (NotFound, "ENOENT"), - (OutOfMemory, "ENOMEM"), - (StorageFull, "ENOSPC"), - (Unsupported, "ENOSYS"), - (TooManyLinks, "EMLINK"), - (InvalidFilename, "ENAMETOOLONG"), - (NetworkDown, "ENETDOWN"), - (NetworkUnreachable, "ENETUNREACH"), - (NotConnected, "ENOTCONN"), - (NotADirectory, "ENOTDIR"), - (DirectoryNotEmpty, "ENOTEMPTY"), - (BrokenPipe, "EPIPE"), - (ReadOnlyFilesystem, "EROFS"), - (NotSeekable, "ESPIPE"), - (StaleNetworkFileHandle, "ESTALE"), - (TimedOut, "ETIMEDOUT"), - (ExecutableFileBusy, "ETXTBSY"), - (CrossesDevices, "EXDEV"), - // The following have two valid options...we pick one. - (PermissionDenied, "EPERM"), - (WouldBlock, "EWOULDBLOCK"), + ("E2BIG", ArgumentListTooLong), + ("EADDRINUSE", AddrInUse), + ("EADDRNOTAVAIL", AddrNotAvailable), + ("EBUSY", ResourceBusy), + ("ECONNABORTED", ConnectionAborted), + ("ECONNREFUSED", ConnectionRefused), + ("ECONNRESET", ConnectionReset), + ("EDEADLK", Deadlock), + ("EDQUOT", FilesystemQuotaExceeded), + ("EEXIST", AlreadyExists), + ("EFBIG", FileTooLarge), + ("EHOSTUNREACH", HostUnreachable), + ("EINTR", Interrupted), + ("EINVAL", InvalidInput), + ("EISDIR", IsADirectory), + ("ELOOP", FilesystemLoop), + ("ENOENT", NotFound), + ("ENOMEM", OutOfMemory), + ("ENOSPC", StorageFull), + ("ENOSYS", Unsupported), + ("EMLINK", TooManyLinks), + ("ENAMETOOLONG", InvalidFilename), + ("ENETDOWN", NetworkDown), + ("ENETUNREACH", NetworkUnreachable), + ("ENOTCONN", NotConnected), + ("ENOTDIR", NotADirectory), + ("ENOTEMPTY", DirectoryNotEmpty), + ("EPIPE", BrokenPipe), + ("EROFS", ReadOnlyFilesystem), + ("ESPIPE", NotSeekable), + ("ESTALE", StaleNetworkFileHandle), + ("ETIMEDOUT", TimedOut), + ("ETXTBSY", ExecutableFileBusy), + ("EXDEV", CrossesDevices), + // The following have two valid options. We have both for the forwards mapping; only the + // first one will be used for the backwards mapping. + ("EPERM", PermissionDenied), + ("EACCES", PermissionDenied), + ("EWOULDBLOCK", WouldBlock), + ("EAGAIN", WouldBlock), ] }; @@ -577,7 +579,7 @@ fn io_error_to_errnum( let this = self.eval_context_ref(); let target = &this.tcx.sess.target; if target.families.iter().any(|f| f == "unix") { - for &(kind, name) in UNIX_IO_ERROR_TABLE { + for &(name, kind) in UNIX_IO_ERROR_TABLE { if err_kind == kind { return this.eval_libc(name); } @@ -615,7 +617,7 @@ fn errnum_to_io_error( let target = &this.tcx.sess.target; if target.families.iter().any(|f| f == "unix") { let errnum = errnum.to_i32()?; - for &(kind, name) in UNIX_IO_ERROR_TABLE { + for &(name, kind) in UNIX_IO_ERROR_TABLE { if errnum == this.eval_libc_i32(name)? { return Ok(kind); }