summaryrefslogtreecommitdiffstats
path: root/src/VBox/Runtime/common/err
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/common/err')
-rw-r--r--src/VBox/Runtime/common/err/Makefile.kup0
-rw-r--r--src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp467
-rw-r--r--src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp465
-rw-r--r--src/VBox/Runtime/common/err/errinfo-alloc.cpp80
-rw-r--r--src/VBox/Runtime/common/err/errinfo.cpp137
-rw-r--r--src/VBox/Runtime/common/err/errinfolog.cpp215
-rw-r--r--src/VBox/Runtime/common/err/errmsg-sorter.cpp483
-rw-r--r--src/VBox/Runtime/common/err/errmsg.cpp338
-rw-r--r--src/VBox/Runtime/common/err/errmsg.sed98
-rw-r--r--src/VBox/Runtime/common/err/errmsgcom.sed76
-rw-r--r--src/VBox/Runtime/common/err/errmsgxpcom.cpp170
-rw-r--r--src/VBox/Runtime/common/err/nocrt-strerror.cpp464
12 files changed, 2993 insertions, 0 deletions
diff --git a/src/VBox/Runtime/common/err/Makefile.kup b/src/VBox/Runtime/common/err/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Runtime/common/err/Makefile.kup
diff --git a/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
new file mode 100644
index 00000000..c79b49be
--- /dev/null
+++ b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
@@ -0,0 +1,467 @@
+/* $Id: RTErrConvertFromErrno.cpp $ */
+/** @file
+ * IPRT - Convert errno to iprt status codes.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/log.h>
+#include <iprt/assert.h>
+#include <iprt/errno.h>
+
+
+RTDECL(int) RTErrConvertFromErrno(int iNativeCode)
+{
+ /* very fast check for no error. */
+ if (iNativeCode == 0)
+ return VINF_SUCCESS;
+
+ /*
+ * Process error codes.
+ *
+ * (Use a switch and not a table since the numbers vary among compilers
+ * and OSes. So we let the compiler switch optimizer handle speed issues.)
+ *
+ * This switch is arranged like the Linux i386 errno.h! This switch is mirrored
+ * by RTErrConvertToErrno.
+ */
+ switch (iNativeCode)
+ { /* Linux number */
+#ifdef EPERM
+ case EPERM: return VERR_ACCESS_DENIED; /* 1 */
+#endif
+#ifdef ENOENT
+ case ENOENT: return VERR_FILE_NOT_FOUND;
+#endif
+#ifdef ESRCH
+ case ESRCH: return VERR_PROCESS_NOT_FOUND;
+#endif
+#ifdef EINTR
+ case EINTR: return VERR_INTERRUPTED;
+#endif
+#ifdef EIO
+ case EIO: return VERR_DEV_IO_ERROR;
+#endif
+#ifdef ENXIO
+ case ENXIO: return VERR_DEV_IO_ERROR; /** @todo fix this duplicate error */
+#endif
+#ifdef E2BIG
+ case E2BIG: return VERR_TOO_MUCH_DATA;
+#endif
+#ifdef ENOEXEC
+ case ENOEXEC: return VERR_BAD_EXE_FORMAT;
+#endif
+#ifdef EBADF
+ case EBADF: return VERR_INVALID_HANDLE;
+#endif
+#ifdef ECHILD
+ case ECHILD: return VERR_PROCESS_NOT_FOUND; /* 10 */ /** @todo fix duplicate error */
+#endif
+#ifdef EAGAIN
+ case EAGAIN: return VERR_TRY_AGAIN;
+#endif
+#ifdef ENOMEM
+ case ENOMEM: return VERR_NO_MEMORY;
+#endif
+#ifdef EACCES
+ case EACCES: return VERR_ACCESS_DENIED; /** @todo fix duplicate error */
+#endif
+#ifdef EFAULT
+ case EFAULT: return VERR_INVALID_POINTER;
+#endif
+#ifdef ENOTBLK
+ //case ENOTBLK: return VERR_;
+#endif
+#ifdef EBUSY
+ case EBUSY: return VERR_RESOURCE_BUSY;
+#endif
+#ifdef EEXIST
+ case EEXIST: return VERR_ALREADY_EXISTS;
+#endif
+#ifdef EXDEV
+ case EXDEV: return VERR_NOT_SAME_DEVICE;
+#endif
+#ifdef ENODEV
+ case ENODEV: return VERR_NOT_SUPPORTED; /** @todo fix duplicate error */
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR: return VERR_PATH_NOT_FOUND; /* 20 */
+#endif
+#ifdef EISDIR
+ case EISDIR: return VERR_IS_A_DIRECTORY;
+#endif
+#ifdef EINVAL
+ case EINVAL: return VERR_INVALID_PARAMETER;
+#endif
+#ifdef ENFILE
+ case ENFILE: return VERR_TOO_MANY_OPEN_FILES; /** @todo fix duplicate error */
+#endif
+#ifdef EMFILE
+ case EMFILE: return VERR_TOO_MANY_OPEN_FILES;
+#endif
+#ifdef ENOTTY
+ case ENOTTY: return VERR_INVALID_FUNCTION;
+#endif
+#ifdef ETXTBSY
+ case ETXTBSY: return VERR_SHARING_VIOLATION;
+#endif
+#ifdef EFBIG
+ case EFBIG: return VERR_FILE_TOO_BIG;
+#endif
+#ifdef ENOSPC
+ case ENOSPC: return VERR_DISK_FULL;
+#endif
+#ifdef ESPIPE
+ case ESPIPE: return VERR_SEEK_ON_DEVICE;
+#endif
+#ifdef EROFS
+ case EROFS: return VERR_WRITE_PROTECT; /* 30 */
+#endif
+#ifdef EMLINK
+ //case EMLINK:
+#endif
+#ifdef EPIPE
+ case EPIPE: return VERR_BROKEN_PIPE;
+#endif
+#ifdef EDOM
+ case EDOM: return VERR_INVALID_PARAMETER; /** @todo fix duplicate error */
+#endif
+#ifdef ERANGE
+ case ERANGE: return VERR_OUT_OF_RANGE;
+#endif
+#ifdef EDEADLK
+ case EDEADLK: return VERR_DEADLOCK;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG: return VERR_FILENAME_TOO_LONG;
+#endif
+#ifdef ENOLCK
+ case ENOLCK: return VERR_FILE_LOCK_FAILED;
+#endif
+#ifdef ENOSYS /** @todo map this differently on solaris. */
+ case ENOSYS: return VERR_NOT_SUPPORTED;
+#endif
+#ifdef ENOTEMPTY
+ case ENOTEMPTY: return VERR_DIR_NOT_EMPTY;
+#endif
+#ifdef ELOOP
+ case ELOOP: return VERR_TOO_MANY_SYMLINKS; /* 40 */
+#endif
+ //41??
+#ifdef ENOMSG
+ //case ENOMSG 42 /* No message of desired type */
+#endif
+#ifdef EIDRM
+ //case EIDRM 43 /* Identifier removed */
+#endif
+#ifdef ECHRNG
+ //case ECHRNG 44 /* Channel number out of range */
+#endif
+#ifdef EL2NSYNC
+ //case EL2NSYNC 45 /* Level 2 not synchronized */
+#endif
+#ifdef EL3HLT
+ //case EL3HLT 46 /* Level 3 halted */
+#endif
+#ifdef EL3RST
+ //case EL3RST 47 /* Level 3 reset */
+#endif
+#ifdef ELNRNG
+ //case ELNRNG 48 /* Link number out of range */
+#endif
+#ifdef EUNATCH
+ //case EUNATCH 49 /* Protocol driver not attached */
+#endif
+#ifdef ENOCSI
+ //case ENOCSI 50 /* No CSI structure available */
+#endif
+#ifdef EL2HLT
+ //case EL2HLT 51 /* Level 2 halted */
+#endif
+#ifdef EBADE
+ //case EBADE 52 /* Invalid exchange */
+#endif
+#ifdef EBADR
+ //case EBADR 53 /* Invalid request descriptor */
+#endif
+#ifdef EXFULL
+ //case EXFULL 54 /* Exchange full */
+#endif
+#ifdef ENOANO
+ //case ENOANO 55 /* No anode */
+#endif
+#ifdef EBADRQC
+ //case EBADRQC 56 /* Invalid request code */
+#endif
+#ifdef EBADSLT
+ //case EBADSLT 57 /* Invalid slot */
+#endif
+ //case 58:
+#ifdef EBFONT
+ //case EBFONT 59 /* Bad font file format */
+#endif
+#ifdef ENOSTR
+ //case ENOSTR 60 /* Device not a stream */
+#endif
+#ifdef ENODATA
+ case ENODATA: return VERR_NO_DATA;
+#endif
+#ifdef ETIME
+ //case ETIME 62 /* Timer expired */
+#endif
+#ifdef ENOSR
+ //case ENOSR 63 /* Out of streams resources */
+#endif
+#ifdef ENONET
+ case ENONET: return VERR_NET_NO_NETWORK;
+#endif
+#ifdef ENOPKG
+ //case ENOPKG 65 /* Package not installed */
+#endif
+#ifdef EREMOTE
+ //case EREMOTE 66 /* Object is remote */
+#endif
+#ifdef ENOLINK
+ //case ENOLINK 67 /* Link has been severed */
+#endif
+#ifdef EADV
+ //case EADV 68 /* Advertise error */
+#endif
+#ifdef ESRMNT
+ //case ESRMNT 69 /* Srmount error */
+#endif
+#ifdef ECOMM
+ //case ECOMM 70 /* Communication error on send */
+#endif
+#ifdef EPROTO
+ case EPROTO: return VERR_NET_PROTOCOL_ERROR;
+#endif
+#ifdef EMULTIHOP
+ //case EMULTIHOP 72 /* Multihop attempted */
+#endif
+#ifdef EDOTDOT
+ //case EDOTDOT 73 /* RFS specific error */
+#endif
+#ifdef EBADMSG
+ //case EBADMSG 74 /* Not a data message */
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW: return VERR_TOO_MUCH_DATA; /** @todo fix duplicate error */
+#endif
+#ifdef ENOTUNIQ
+ case ENOTUNIQ: return VERR_NET_NOT_UNIQUE_NAME;
+#endif
+#ifdef EBADFD
+ case EBADFD: return VERR_INVALID_HANDLE; /** @todo fix duplicate error? */
+#endif
+#ifdef EREMCHG
+ //case EREMCHG 78 /* Remote address changed */
+#endif
+#ifdef ELIBACC
+ //case ELIBACC 79 /* Can not access a needed shared library */
+#endif
+#ifdef ELIBBAD
+ //case ELIBBAD 80 /* Accessing a corrupted shared library */
+#endif
+#ifdef ELIBSCN
+ //case ELIBSCN 81 /* .lib section in a.out corrupted */
+#endif
+#ifdef ELIBMAX
+ //case ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#endif
+#ifdef ELIBEXEC
+ //case ELIBEXEC 83 /* Cannot exec a shared library directly */
+#endif
+#ifdef EILSEQ
+ case EILSEQ: return VERR_NO_TRANSLATION;
+#endif
+#ifdef ERESTART
+ case ERESTART: return VERR_INTERRUPTED;/** @todo fix duplicate error?*/
+#endif
+#ifdef ESTRPIPE
+ //case ESTRPIPE 86 /* Streams pipe error */
+#endif
+#ifdef EUSERS
+ //case EUSERS 87 /* Too many users */
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK: return VERR_NET_NOT_SOCKET;
+#endif
+#ifdef EDESTADDRREQ
+ case EDESTADDRREQ: return VERR_NET_DEST_ADDRESS_REQUIRED;
+#endif
+#ifdef EMSGSIZE
+ case EMSGSIZE: return VERR_NET_MSG_SIZE;
+#endif
+#ifdef EPROTOTYPE
+ case EPROTOTYPE: return VERR_NET_PROTOCOL_TYPE;
+#endif
+#ifdef ENOPROTOOPT
+ case ENOPROTOOPT: return VERR_NET_PROTOCOL_NOT_AVAILABLE;
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT: return VERR_NET_PROTOCOL_NOT_SUPPORTED;
+#endif
+#ifdef ESOCKTNOSUPPORT
+ case ESOCKTNOSUPPORT: return VERR_NET_SOCKET_TYPE_NOT_SUPPORTED;
+#endif
+#ifdef EOPNOTSUPP /** @todo map this differently on solaris. */
+ case EOPNOTSUPP: return VERR_NET_OPERATION_NOT_SUPPORTED;
+#endif
+#ifdef EPFNOSUPPORT
+ case EPFNOSUPPORT: return VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT: return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE: return VERR_NET_ADDRESS_IN_USE;
+#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL: return VERR_NET_ADDRESS_NOT_AVAILABLE;
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN: return VERR_NET_DOWN;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH: return VERR_NET_UNREACHABLE;
+#endif
+#ifdef ENETRESET
+ case ENETRESET: return VERR_NET_CONNECTION_RESET;
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED: return VERR_NET_CONNECTION_ABORTED;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET: return VERR_NET_CONNECTION_RESET_BY_PEER;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS: return VERR_NET_NO_BUFFER_SPACE;
+#endif
+#ifdef EISCONN
+ case EISCONN: return VERR_NET_ALREADY_CONNECTED;
+#endif
+#ifdef ENOTCONN
+ case ENOTCONN: return VERR_NET_NOT_CONNECTED;
+#endif
+#ifdef ESHUTDOWN
+ case ESHUTDOWN: return VERR_NET_SHUTDOWN;
+#endif
+#ifdef ETOOMANYREFS
+ case ETOOMANYREFS: return VERR_NET_TOO_MANY_REFERENCES;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT: return VERR_TIMEOUT;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED: return VERR_NET_CONNECTION_REFUSED;
+#endif
+#ifdef EHOSTDOWN
+ case EHOSTDOWN: return VERR_NET_HOST_DOWN;
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH: return VERR_NET_HOST_UNREACHABLE;
+#endif
+#ifdef EALREADY
+# if !defined(ENOLCK) || (EALREADY != ENOLCK)
+ case EALREADY: return VERR_NET_ALREADY_IN_PROGRESS;
+# endif
+#endif
+#ifdef EINPROGRESS
+# if !defined(ENODEV) || (EINPROGRESS != ENODEV)
+ case EINPROGRESS: return VERR_NET_IN_PROGRESS;
+# endif
+#endif
+#ifdef ESTALE
+ case ESTALE: return VERR_STALE_FILE_HANDLE; /* 116: Stale NFS file handle */
+#endif
+#ifdef EUCLEAN
+ //case EUCLEAN 117 /* Structure needs cleaning */
+#endif
+#ifdef ENOTNAM
+ //case ENOTNAM 118 /* Not a XENIX named type file */
+#endif
+#ifdef ENAVAIL
+ //case ENAVAIL 119 /* No XENIX semaphores available */
+#endif
+#ifdef EISNAM
+ //case EISNAM 120 /* Is a named type file */
+#endif
+#ifdef EREMOTEIO
+ //case EREMOTEIO 121 /* Remote I/O error */
+#endif
+#ifdef EDQUOT
+ case EDQUOT: return VERR_DISK_FULL; /** @todo fix duplicate error */
+#endif
+#ifdef ENOMEDIUM
+ case ENOMEDIUM: return VERR_MEDIA_NOT_PRESENT;
+#endif
+#ifdef EMEDIUMTYPE
+ case EMEDIUMTYPE: return VERR_MEDIA_NOT_RECOGNIZED;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK: return VERR_TRY_AGAIN;
+#endif
+
+ /* Non-linux */
+
+#ifdef EPROCLIM
+ case EPROCLIM: return VERR_MAX_PROCS_REACHED;
+#endif
+#ifdef EDOOFUS
+# if EDOOFUS != EINVAL
+ case EDOOFUS: return VERR_INTERNAL_ERROR;
+# endif
+#endif
+#ifdef ENOTSUP
+# ifndef EOPNOTSUPP
+ case ENOTSUP: return VERR_NOT_SUPPORTED;
+# else
+# if ENOTSUP != EOPNOTSUPP
+ case ENOTSUP: return VERR_NOT_SUPPORTED;
+# endif
+# endif
+#endif
+ default:
+ AssertLogRelMsgFailed(("Unhandled error code %d\n", iNativeCode));
+ return VERR_UNRESOLVED_ERROR;
+ }
+}
+RT_EXPORT_SYMBOL(RTErrConvertFromErrno);
+
diff --git a/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp
new file mode 100644
index 00000000..d8e9fbb7
--- /dev/null
+++ b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp
@@ -0,0 +1,465 @@
+/* $Id: RTErrConvertToErrno.cpp $ */
+/** @file
+ * IPRT - Convert iprt status codes to errno.
+ */
+
+/*
+ * Copyright (C) 2007-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/errno.h>
+
+
+RTDECL(int) RTErrConvertToErrno(int iErr)
+{
+ /* very fast check for no error. */
+ if (RT_SUCCESS(iErr))
+ return 0;
+
+ /*
+ * Process error codes.
+ *
+ * (Use a switch and not a table since the numbers vary among compilers
+ * and OSes. So we let the compiler switch optimizer handle speed issues.)
+ *
+ * This switch is arranged like the Linux i386 errno.h! It also mirrors the
+ * conversions performed by RTErrConvertFromErrno with a few extra case since
+ * there are far more IPRT status codes than Unix ones.
+ */
+ switch (iErr)
+ {
+#ifdef EPERM
+ case VERR_ACCESS_DENIED: return EPERM;
+#endif
+#ifdef ENOENT
+ case VERR_FILE_NOT_FOUND: return ENOENT;
+#endif
+#ifdef ESRCH
+ case VERR_PROCESS_NOT_FOUND: return ESRCH;
+#endif
+#ifdef EINTR
+ case VERR_INTERRUPTED: return EINTR;
+#endif
+#ifdef EIO
+ case VERR_DEV_IO_ERROR: return EIO;
+#endif
+#ifdef ENXIO
+ //case VERR_DEV_IO_ERROR: return ENXIO;
+#endif
+#ifdef E2BIG
+ case VERR_TOO_MUCH_DATA: return E2BIG;
+#endif
+#ifdef ENOEXEC
+ case VERR_BAD_EXE_FORMAT: return ENOEXEC;
+#endif
+#ifdef EBADF
+ case VERR_INVALID_HANDLE: return EBADF;
+#endif
+#ifdef ECHILD
+ //case VERR_PROCESS_NOT_FOUND: return ECHILD;
+#endif
+#ifdef EAGAIN
+ case VERR_TRY_AGAIN: return EAGAIN;
+#endif
+#ifdef ENOMEM
+ case VERR_NO_MEMORY: return ENOMEM;
+#endif
+#ifdef EACCES
+ //case VERR_ACCESS_DENIED: return EACCES;
+#endif
+#ifdef EFAULT
+ case VERR_INVALID_POINTER: return EFAULT;
+#endif
+#ifdef ENOTBLK
+ //case ENOTBLK: return VERR_;
+#endif
+#ifdef EBUSY
+ case VERR_RESOURCE_BUSY: return EBUSY;
+#endif
+#ifdef EEXIST
+ case VERR_ALREADY_EXISTS: return EEXIST;
+#endif
+#ifdef EXDEV
+ case VERR_NOT_SAME_DEVICE: return EXDEV;
+#endif
+#ifdef ENODEV
+ //case VERR_NOT_SUPPORTED: return ENODEV;
+#endif
+#ifdef ENOTDIR
+ case VERR_NOT_A_DIRECTORY:
+ case VERR_PATH_NOT_FOUND: return ENOTDIR;
+#endif
+#ifdef EISDIR
+ case VERR_IS_A_DIRECTORY: return EISDIR;
+#endif
+#ifdef EINVAL
+ case VERR_INVALID_PARAMETER: return EINVAL;
+#endif
+#ifdef ENFILE
+ case VERR_TOO_MANY_OPEN_FILES: return ENFILE;
+#endif
+#ifdef EMFILE
+ //case VERR_TOO_MANY_OPEN_FILES: return EMFILE;
+#endif
+#ifdef ENOTTY
+ case VERR_INVALID_FUNCTION: return ENOTTY;
+#endif
+#ifdef ETXTBSY
+ case VERR_SHARING_VIOLATION: return ETXTBSY;
+#endif
+#ifdef EFBIG
+ case VERR_FILE_TOO_BIG: return EFBIG;
+#endif
+#ifdef ENOSPC
+ case VERR_DISK_FULL: return ENOSPC;
+#endif
+#ifdef ESPIPE
+ case VERR_SEEK_ON_DEVICE: return ESPIPE;
+#endif
+#ifdef EROFS
+ case VERR_WRITE_PROTECT: return EROFS;
+#endif
+#ifdef EMLINK
+ //case EMLINK:
+#endif
+#ifdef EPIPE
+ case VERR_BROKEN_PIPE: return EPIPE;
+#endif
+#ifdef EDOM
+ //case VERR_INVALID_PARAMETER: return EDOM;
+#endif
+#ifdef ERANGE
+ case VERR_OUT_OF_RANGE: return ERANGE;
+ case VERR_FLOAT_UNDERFLOW: return ERANGE;
+ case VWRN_FLOAT_UNDERFLOW: return ERANGE;
+ case VERR_FLOAT_OVERFLOW: return ERANGE;
+ case VWRN_FLOAT_OVERFLOW: return ERANGE;
+#endif
+#ifdef EDEADLK
+ case VERR_DEADLOCK: return EDEADLK;
+#endif
+#ifdef ENAMETOOLONG
+ case VERR_FILENAME_TOO_LONG: return ENAMETOOLONG;
+#endif
+#ifdef ENOLCK
+ case VERR_FILE_LOCK_FAILED: return ENOLCK;
+#endif
+#ifdef ENOSYS
+ case VERR_NOT_IMPLEMENTED:
+ case VERR_NOT_SUPPORTED: return ENOSYS;
+#endif
+#ifdef ENOTEMPTY
+ case VERR_DIR_NOT_EMPTY: return ENOTEMPTY;
+#endif
+#ifdef ELOOP
+ case VERR_TOO_MANY_SYMLINKS: return ELOOP;
+#endif
+ //41??
+#ifdef ENOMSG
+ //case ENOMSG 42 /* No message of desired type */
+#endif
+#ifdef EIDRM
+ //case EIDRM 43 /* Identifier removed */
+#endif
+#ifdef ECHRNG
+ //case ECHRNG 44 /* Channel number out of range */
+#endif
+#ifdef EL2NSYNC
+ //case EL2NSYNC 45 /* Level 2 not synchronized */
+#endif
+#ifdef EL3HLT
+ //case EL3HLT 46 /* Level 3 halted */
+#endif
+#ifdef EL3RST
+ //case EL3RST 47 /* Level 3 reset */
+#endif
+#ifdef ELNRNG
+ //case ELNRNG 48 /* Link number out of range */
+#endif
+#ifdef EUNATCH
+ //case EUNATCH 49 /* Protocol driver not attached */
+#endif
+#ifdef ENOCSI
+ //case ENOCSI 50 /* No CSI structure available */
+#endif
+#ifdef EL2HLT
+ //case EL2HLT 51 /* Level 2 halted */
+#endif
+#ifdef EBADE
+ //case EBADE 52 /* Invalid exchange */
+#endif
+#ifdef EBADR
+ //case EBADR 53 /* Invalid request descriptor */
+#endif
+#ifdef EXFULL
+ //case EXFULL 54 /* Exchange full */
+#endif
+#ifdef ENOANO
+ //case ENOANO 55 /* No anode */
+#endif
+#ifdef EBADRQC
+ //case EBADRQC 56 /* Invalid request code */
+#endif
+#ifdef EBADSLT
+ //case EBADSLT 57 /* Invalid slot */
+#endif
+ //case 58:
+#ifdef EBFONT
+ //case EBFONT 59 /* Bad font file format */
+#endif
+#ifdef ENOSTR
+ //case ENOSTR 60 /* Device not a stream */
+#endif
+#ifdef ENODATA
+ case VERR_NO_DATA: return ENODATA;
+#endif
+#ifdef ETIME
+ //case ETIME 62 /* Timer expired */
+#endif
+#ifdef ENOSR
+ //case ENOSR 63 /* Out of streams resources */
+#endif
+#ifdef ENONET
+ case VERR_NET_NO_NETWORK: return ENONET;
+#endif
+#ifdef ENOPKG
+ //case ENOPKG 65 /* Package not installed */
+#endif
+#ifdef EREMOTE
+ //case EREMOTE 66 /* Object is remote */
+#endif
+#ifdef ENOLINK
+ //case ENOLINK 67 /* Link has been severed */
+#endif
+#ifdef EADV
+ //case EADV 68 /* Advertise error */
+#endif
+#ifdef ESRMNT
+ //case ESRMNT 69 /* Srmount error */
+#endif
+#ifdef ECOMM
+ //case ECOMM 70 /* Communication error on send */
+#endif
+#ifdef EPROTO
+ //case EPROTO 71 /* Protocol error */
+#endif
+#ifdef EMULTIHOP
+ //case EMULTIHOP 72 /* Multihop attempted */
+#endif
+#ifdef EDOTDOT
+ //case EDOTDOT 73 /* RFS specific error */
+#endif
+#ifdef EBADMSG
+ //case EBADMSG 74 /* Not a data message */
+#endif
+#ifdef EOVERFLOW
+ //case VERR_TOO_MUCH_DATA: return EOVERFLOW;
+#endif
+#ifdef ENOTUNIQ
+ case VERR_NET_NOT_UNIQUE_NAME: return ENOTUNIQ;
+#endif
+#ifdef EBADFD
+ //case VERR_INVALID_HANDLE: return EBADFD;
+#endif
+#ifdef EREMCHG
+ //case EREMCHG 78 /* Remote address changed */
+#endif
+#ifdef ELIBACC
+ //case ELIBACC 79 /* Can not access a needed shared library */
+#endif
+#ifdef ELIBBAD
+ //case ELIBBAD 80 /* Accessing a corrupted shared library */
+#endif
+#ifdef ELIBSCN
+ //case ELIBSCN 81 /* .lib section in a.out corrupted */
+#endif
+#ifdef ELIBMAX
+ //case ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#endif
+#ifdef ELIBEXEC
+ //case ELIBEXEC 83 /* Cannot exec a shared library directly */
+#endif
+#ifdef EILSEQ
+ case VERR_NO_TRANSLATION: return EILSEQ;
+#endif
+#ifdef ERESTART
+ //case VERR_INTERRUPTED: return ERESTART;
+#endif
+#ifdef ESTRPIPE
+ //case ESTRPIPE 86 /* Streams pipe error */
+#endif
+#ifdef EUSERS
+ //case EUSERS 87 /* Too many users */
+#endif
+#ifdef ENOTSOCK
+ case VERR_NET_NOT_SOCKET: return ENOTSOCK;
+#endif
+#ifdef EDESTADDRREQ
+ case VERR_NET_DEST_ADDRESS_REQUIRED: return EDESTADDRREQ;
+#endif
+#ifdef EMSGSIZE
+ case VERR_NET_MSG_SIZE: return EMSGSIZE;
+#endif
+#ifdef EPROTOTYPE
+ case VERR_NET_PROTOCOL_TYPE: return EPROTOTYPE;
+#endif
+#ifdef ENOPROTOOPT
+ case VERR_NET_PROTOCOL_NOT_AVAILABLE: return ENOPROTOOPT;
+#endif
+#ifdef EPROTONOSUPPORT
+ case VERR_NET_PROTOCOL_NOT_SUPPORTED: return EPROTONOSUPPORT;
+#endif
+#ifdef ESOCKTNOSUPPORT
+ case VERR_NET_SOCKET_TYPE_NOT_SUPPORTED: return ESOCKTNOSUPPORT;
+#endif
+#ifdef EOPNOTSUPP
+ case VERR_NET_OPERATION_NOT_SUPPORTED: return EOPNOTSUPP;
+#endif
+#ifdef EPFNOSUPPORT
+ case VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED: return EPFNOSUPPORT;
+#endif
+#ifdef EAFNOSUPPORT
+ case VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED: return EAFNOSUPPORT;
+#endif
+#ifdef EADDRINUSE
+ case VERR_NET_ADDRESS_IN_USE: return EADDRINUSE;
+#endif
+#ifdef EADDRNOTAVAIL
+ case VERR_NET_ADDRESS_NOT_AVAILABLE: return EADDRNOTAVAIL;
+#endif
+#ifdef ENETDOWN
+ case VERR_NET_DOWN: return ENETDOWN;
+#endif
+#ifdef ENETUNREACH
+ case VERR_NET_UNREACHABLE: return ENETUNREACH;
+#endif
+#ifdef ENETRESET
+ case VERR_NET_CONNECTION_RESET: return ENETRESET;
+#endif
+#ifdef ECONNABORTED
+ case VERR_NET_CONNECTION_ABORTED: return ECONNABORTED;
+#endif
+#ifdef ECONNRESET
+ case VERR_NET_CONNECTION_RESET_BY_PEER: return ECONNRESET;
+#endif
+#ifdef ENOBUFS
+ case VERR_NET_NO_BUFFER_SPACE: return ENOBUFS;
+#endif
+#ifdef EISCONN
+ case VERR_NET_ALREADY_CONNECTED: return EISCONN;
+#endif
+#ifdef ENOTCONN
+ case VERR_NET_NOT_CONNECTED: return ENOTCONN;
+#endif
+#ifdef ESHUTDOWN
+ case VERR_NET_SHUTDOWN: return ESHUTDOWN;
+#endif
+#ifdef ETOOMANYREFS
+ case VERR_NET_TOO_MANY_REFERENCES: return ETOOMANYREFS;
+#endif
+#ifdef ETIMEDOUT
+ case VERR_TIMEOUT: return ETIMEDOUT;
+#endif
+#ifdef ECONNREFUSED
+ case VERR_NET_CONNECTION_REFUSED: return ECONNREFUSED;
+#endif
+#ifdef EHOSTDOWN
+ case VERR_NET_HOST_DOWN: return EHOSTDOWN;
+#endif
+#ifdef EHOSTUNREACH
+ case VERR_NET_HOST_UNREACHABLE: return EHOSTUNREACH;
+#endif
+#ifdef EALREADY
+ case VERR_NET_ALREADY_IN_PROGRESS: return EALREADY;
+#endif
+#ifdef EINPROGRESS
+ case VERR_NET_IN_PROGRESS: return EINPROGRESS;
+#endif
+#ifdef ESTALE
+ //case ESTALE 116 /* Stale NFS file handle */
+#endif
+#ifdef EUCLEAN
+ //case EUCLEAN 117 /* Structure needs cleaning */
+#endif
+#ifdef ENOTNAM
+ //case ENOTNAM 118 /* Not a XENIX named type file */
+#endif
+#ifdef ENAVAIL
+ //case ENAVAIL 119 /* No XENIX semaphores available */
+#endif
+#ifdef EISNAM
+ //case EISNAM 120 /* Is a named type file */
+#endif
+#ifdef EREMOTEIO
+ //case EREMOTEIO 121 /* Remote I/O error */
+#endif
+#ifdef EDQUOT
+ //case VERR_DISK_FULL: return EDQUOT;
+#endif
+#ifdef ENOMEDIUM
+ case VERR_MEDIA_NOT_PRESENT: return ENOMEDIUM;
+#endif
+#ifdef EMEDIUMTYPE
+ case VERR_MEDIA_NOT_RECOGNIZED: return EMEDIUMTYPE;
+#endif
+
+ /* Non-linux */
+
+#ifdef EPROCLIM
+ case VERR_MAX_PROCS_REACHED: return EPROCLIM;
+#endif
+#ifdef EDOOFUS
+ case VERR_INTERNAL_ERROR:
+ case VERR_INTERNAL_ERROR_2:
+ case VERR_INTERNAL_ERROR_3: return EDOOFUS;
+#endif
+
+ default:
+ /* The idea here is that if you hit this, you will have to
+ translate the status code yourself. */
+ AssertMsgFailed(("Unhandled error code %Rrc\n", iErr));
+#ifdef EPROTO
+ return EPROTO;
+#else
+ return EINVAL;
+#endif
+ }
+}
+RT_EXPORT_SYMBOL(RTErrConvertToErrno);
+
diff --git a/src/VBox/Runtime/common/err/errinfo-alloc.cpp b/src/VBox/Runtime/common/err/errinfo-alloc.cpp
new file mode 100644
index 00000000..9c4f6ed0
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errinfo-alloc.cpp
@@ -0,0 +1,80 @@
+/* $Id: errinfo-alloc.cpp $ */
+/** @file
+ * IPRT - Error Info, Allocators.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/err.h>
+
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+
+
+
+RTDECL(PRTERRINFO) RTErrInfoAlloc(size_t cbMsg)
+{
+ PRTERRINFO pErrInfo;
+ RTErrInfoAllocEx(cbMsg, &pErrInfo);
+ return pErrInfo;
+}
+
+
+RTDECL(int) RTErrInfoAllocEx(size_t cbMsg, PRTERRINFO *ppErrInfo)
+{
+ if (cbMsg == 0)
+ cbMsg = _4K;
+ else
+ cbMsg = RT_ALIGN_Z(cbMsg, 256);
+
+ PRTERRINFO pErrInfo;
+ *ppErrInfo = pErrInfo = (PRTERRINFO)RTMemTmpAlloc(sizeof(*pErrInfo) + cbMsg);
+ if (RT_UNLIKELY(!pErrInfo))
+ return VERR_NO_TMP_MEMORY;
+
+ RTErrInfoInit(pErrInfo, (char *)(pErrInfo + 1), cbMsg);
+ pErrInfo->fFlags = RTERRINFO_FLAGS_T_ALLOC | RTERRINFO_FLAGS_MAGIC;
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(void) RTErrInfoFree(PRTERRINFO pErrInfo)
+{
+ RTMemTmpFree(pErrInfo);
+}
+
diff --git a/src/VBox/Runtime/common/err/errinfo.cpp b/src/VBox/Runtime/common/err/errinfo.cpp
new file mode 100644
index 00000000..1af02c8f
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errinfo.cpp
@@ -0,0 +1,137 @@
+/* $Id: errinfo.cpp $ */
+/** @file
+ * IPRT - Error Info, Setters.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/errcore.h>
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+
+RTDECL(int) RTErrInfoSet(PRTERRINFO pErrInfo, int rc, const char *pszMsg)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+
+ RTStrCopy(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg);
+ pErrInfo->rc = rc;
+ pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
+ }
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoSetF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTErrInfoSetV(pErrInfo, rc, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoSetV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+
+ RTStrPrintfV(pErrInfo->pszMsg, pErrInfo->cbMsg, pszFormat, va);
+ pErrInfo->rc = rc;
+ pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
+ }
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoAdd(PRTERRINFO pErrInfo, int rc, const char *pszMsg)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET)
+ RTStrCat(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg);
+ else
+ {
+ while (*pszMsg == ' ')
+ pszMsg++;
+ return RTErrInfoSet(pErrInfo, rc, pszMsg);
+ }
+ }
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoAddF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTErrInfoAddV(pErrInfo, rc, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoAddV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+ if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET)
+ {
+ char *pszOut = (char *)memchr(pErrInfo->pszMsg, '\0', pErrInfo->cbMsg - 2);
+ if (pszOut)
+ RTStrPrintfV(pszOut, &pErrInfo->pszMsg[pErrInfo->cbMsg] - pszOut, pszFormat, va);
+ }
+ else
+ {
+ while (*pszFormat == ' ')
+ pszFormat++;
+ return RTErrInfoSetV(pErrInfo, rc, pszFormat, va);
+ }
+ }
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/common/err/errinfolog.cpp b/src/VBox/Runtime/common/err/errinfolog.cpp
new file mode 100644
index 00000000..0ed53b75
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errinfolog.cpp
@@ -0,0 +1,215 @@
+/* $Id: errinfolog.cpp $ */
+/** @file
+ * IPRT - Error Info, Setters with logging.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/errcore.h>
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/log.h>
+
+
+RTDECL(int) RTErrInfoLogAndSet(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszMsg)
+{
+ /* The logging: */
+ if (fFlags & RTERRINFO_LOG_F_RELEASE)
+ {
+ PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %s\n", rc, pszMsg);
+ }
+
+ PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %s\n", rc, pszMsg);
+
+ /* The setting: */
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+
+ RTStrCopy(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg);
+ pErrInfo->rc = rc;
+ pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
+ }
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoLogAndSetF(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTErrInfoLogAndSetV(pErrInfo, rc, iLogGroup, fFlags, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoLogAndSetV(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, va_list va)
+{
+ /* The logging: */
+ if (fFlags & RTERRINFO_LOG_F_RELEASE)
+ {
+ PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ {
+ va_list va2;
+ va_copy(va2, va);
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %N\n", rc, pszFormat, &va2);
+ va_end(va2);
+ }
+ }
+
+ PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ {
+ va_list va2;
+ va_copy(va2, va);
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %N\n", rc, pszFormat, &va2);
+ va_end(va2);
+ }
+
+ /* The setting: */
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+
+ RTStrPrintfV(pErrInfo->pszMsg, pErrInfo->cbMsg, pszFormat, va);
+ pErrInfo->rc = rc;
+ pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
+ }
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoLogAndAdd(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszMsg)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET)
+ RTStrCat(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg);
+ else
+ {
+ while (*pszMsg == ' ')
+ pszMsg++;
+ return RTErrInfoSet(pErrInfo, rc, pszMsg);
+ }
+ }
+
+ /* The logging: */
+ if (fFlags & RTERRINFO_LOG_F_RELEASE)
+ {
+ PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %s\n", rc, pszMsg);
+ }
+
+ PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %s\n", rc, pszMsg);
+
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoLogAndAddF(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTErrInfoLogAndAddV(pErrInfo, rc, iLogGroup, fFlags, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+
+RTDECL(int) RTErrInfoLogAndAddV(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, va_list va)
+{
+ if (pErrInfo)
+ {
+ AssertPtr(pErrInfo);
+ Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC);
+ if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET)
+ {
+ char *pszOut = (char *)memchr(pErrInfo->pszMsg, '\0', pErrInfo->cbMsg - 2);
+ if (pszOut)
+ {
+ va_list va2;
+ va_copy(va2, va);
+ RTStrPrintfV(pszOut, &pErrInfo->pszMsg[pErrInfo->cbMsg] - pszOut, pszFormat, va2);
+ va_end(va2);
+ }
+ }
+ else
+ {
+ while (*pszFormat == ' ')
+ pszFormat++;
+ return RTErrInfoSetV(pErrInfo, rc, pszFormat, va);
+ }
+ }
+
+ /* The logging: */
+ if (fFlags & RTERRINFO_LOG_F_RELEASE)
+ {
+ PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ {
+ va_list va2;
+ va_copy(va2, va);
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %N\n", rc, pszFormat, &va2);
+ va_end(va2);
+ }
+ }
+
+ PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup));
+ if (pLogger)
+ {
+ va_list va2;
+ va_copy(va2, va);
+ RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %N\n", rc, pszFormat, &va2);
+ va_end(va2);
+ }
+
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/common/err/errmsg-sorter.cpp b/src/VBox/Runtime/common/err/errmsg-sorter.cpp
new file mode 100644
index 00000000..a4c68865
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errmsg-sorter.cpp
@@ -0,0 +1,483 @@
+/* $Id: errmsg-sorter.cpp $ */
+/** @file
+ * IPRT - Status code messages, sorter build program.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/string.h>
+#include <VBox/err.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ * Include the string table code.
+ */
+#define BLDPROG_STRTAB_MAX_STRLEN 512
+#define BLDPROG_STRTAB_WITH_COMPRESSION
+#define BLDPROG_STRTAB_PURE_ASCII
+#define BLDPROG_STRTAB_WITH_CAMEL_WORDS
+#include <iprt/bldprog-strtab-template.cpp.h>
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+/** Used for raw-input and sorting. */
+typedef struct RTSTATUSMSGINT1
+{
+ /** Pointer to the short message string. */
+ const char *pszMsgShort;
+ /** Pointer to the full message string. */
+ const char *pszMsgFull;
+ /** Pointer to the define string. */
+ const char *pszDefine;
+ /** Status code number. */
+ int iCode;
+ /** Set if duplicate. */
+ bool fDuplicate;
+} RTSTATUSMSGINT1;
+typedef RTSTATUSMSGINT1 *PRTSTATUSMSGINT1;
+
+
+/** This is used when building the string table and printing it. */
+typedef struct RTSTATUSMSGINT2
+{
+ /** The short message string. */
+ BLDPROGSTRING MsgShort;
+ /** The full message string. */
+ BLDPROGSTRING MsgFull;
+ /** The define string. */
+ BLDPROGSTRING Define;
+ /** Pointer to the define string. */
+ const char *pszDefine;
+ /** Status code number. */
+ int iCode;
+ /** Index into the primary table (for multiple passes). */
+ unsigned idx1;
+} RTSTATUSMSGINT2;
+typedef RTSTATUSMSGINT2 *PRTSTATUSMSGINT2;
+
+
+/** This used to determin minimum field sizes. */
+typedef struct RTSTATUSMSGSTATS
+{
+ unsigned offMax;
+ unsigned cchMax;
+ unsigned cBitsOffset;
+ unsigned cBitsLength;
+} RTSTATUSMSGSTATS;
+typedef RTSTATUSMSGSTATS *PRTSTATUSMSGSTATS;
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+static const char *g_pszProgName = "errmsg-sorter";
+static RTSTATUSMSGINT1 g_aStatusMsgs[] =
+{
+#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
+# include "errmsgdata.h"
+#else
+ { "Success.", "Success.", "VINF_SUCCESS", 0, false },
+#endif
+};
+
+
+static RTEXITCODE error(const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ fprintf(stderr, "%s: error: ", g_pszProgName);
+ vfprintf(stderr, pszFormat, va);
+ va_end(va);
+ return RTEXITCODE_FAILURE;
+}
+
+
+/** qsort callback. */
+static int CompareErrMsg(const void *pv1, const void *pv2) RT_NOTHROW_DEF
+{
+ PRTSTATUSMSGINT1 p1 = (PRTSTATUSMSGINT1)pv1;
+ PRTSTATUSMSGINT1 p2 = (PRTSTATUSMSGINT1)pv2;
+ int iDiff;
+ if (p1->iCode < p2->iCode)
+ iDiff = -1;
+ else if (p1->iCode > p2->iCode)
+ iDiff = 1;
+ else
+ iDiff = 0;
+ return iDiff;
+}
+
+
+/**
+ * Checks whether @a pszDefine is a deliberate duplicate define that should be
+ * omitted.
+ */
+static bool IgnoreDuplicateDefine(const char *pszDefine)
+{
+ size_t const cchDefine = strlen(pszDefine);
+
+ static const RTSTRTUPLE s_aTails[] =
+ {
+ { RT_STR_TUPLE("_FIRST") },
+ { RT_STR_TUPLE("_LAST") },
+ { RT_STR_TUPLE("_HIGEST") },
+ { RT_STR_TUPLE("_LOWEST") },
+ };
+ for (size_t i = 0; i < RT_ELEMENTS(s_aTails); i++)
+ if ( cchDefine > s_aTails[i].cch
+ && memcmp(&pszDefine[cchDefine - s_aTails[i].cch], s_aTails[i].psz, s_aTails[i].cch) == 0)
+ return true;
+
+ static const RTSTRTUPLE s_aDeliberateOrSilly[] =
+ {
+ { RT_STR_TUPLE("VERR_VRDP_TIMEOUT") },
+ { RT_STR_TUPLE("VINF_VRDP_SUCCESS") },
+ { RT_STR_TUPLE("VWRN_CONTINUE_RECOMPILE") },
+ { RT_STR_TUPLE("VWRN_PATM_CONTINUE_SEARCH") },
+ };
+ for (size_t i = 0; i < RT_ELEMENTS(s_aDeliberateOrSilly); i++)
+ if ( cchDefine == s_aDeliberateOrSilly[i].cch
+ && memcmp(pszDefine, s_aDeliberateOrSilly[i].psz, cchDefine) == 0)
+ return true;
+
+ return false;
+}
+
+
+DECLINLINE(void) GatherStringStats(PRTSTATUSMSGSTATS pStats, PBLDPROGSTRING pString)
+{
+ if (pStats->offMax < pString->offStrTab)
+ pStats->offMax = pString->offStrTab;
+ if (pStats->cchMax < pString->cchString)
+ pStats->cchMax = (unsigned)pString->cchString;
+}
+
+
+DECLINLINE(unsigned) CalcBitsForValue(size_t uValue)
+{
+ unsigned cBits = 1;
+ while (RT_BIT_64(cBits) < uValue && cBits < 64)
+ cBits++;
+ return cBits;
+}
+
+
+static void CalcBitsForStringStats(PRTSTATUSMSGSTATS pStats)
+{
+ pStats->cBitsOffset = CalcBitsForValue(pStats->offMax);
+ pStats->cBitsLength = CalcBitsForValue(pStats->cchMax);
+}
+
+
+int main(int argc, char **argv)
+{
+ /*
+ * Parse arguments.
+ */
+ enum { kMode_All, kMode_NoFullMsg, kMode_OnlyDefines } enmMode;
+ if (argc == 3 && strcmp(argv[1], "--all") == 0)
+ enmMode = kMode_All;
+ else if (argc == 3 && strcmp(argv[1], "--no-full-msg") == 0)
+ enmMode = kMode_NoFullMsg;
+ else if (argc == 3 && strcmp(argv[1], "--only-defines") == 0)
+ enmMode = kMode_OnlyDefines;
+ else
+ {
+ fprintf(stderr,
+ "syntax error!\n"
+ "Usage: %s <--all|--no-full-msg|--only-defines> <outfile>\n", argv[0]);
+ return RTEXITCODE_SYNTAX;
+ }
+ const char * const pszOutFile = argv[2];
+
+ /*
+ * Sort the table and mark duplicates.
+ */
+ qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareErrMsg);
+
+ int rcExit = RTEXITCODE_SUCCESS;
+ int iPrev = INT32_MAX;
+ for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
+ {
+ /* Deal with duplicates, trying to eliminate unnecessary *_FIRST, *_LAST,
+ *_LOWEST, and *_HIGHEST entries as well as some deliberate duplicate entries.
+ This means we need to look forward and backwards here. */
+ PRTSTATUSMSGINT1 pMsg = &g_aStatusMsgs[i];
+ if (pMsg->iCode == iPrev && i != 0)
+ {
+ if (IgnoreDuplicateDefine(pMsg->pszDefine))
+ {
+ pMsg->fDuplicate = true;
+ continue;
+ }
+ PRTSTATUSMSGINT1 pPrev = &g_aStatusMsgs[i - 1];
+ rcExit = error("Duplicate value %d - %s and %s\n", iPrev, pMsg->pszDefine, pPrev->pszDefine);
+ }
+ else if (i + 1 < RT_ELEMENTS(g_aStatusMsgs))
+ {
+ PRTSTATUSMSGINT1 pNext = &g_aStatusMsgs[i];
+ if ( pMsg->iCode == pNext->iCode
+ && IgnoreDuplicateDefine(pMsg->pszDefine))
+ {
+ pMsg->fDuplicate = true;
+ continue;
+ }
+ }
+ iPrev = pMsg->iCode;
+ pMsg->fDuplicate = false;
+ }
+
+ /*
+ * Create a string table for it all.
+ */
+ BLDPROGSTRTAB StrTab;
+ if (!BldProgStrTab_Init(&StrTab, RT_ELEMENTS(g_aStatusMsgs) * 3))
+ return error("Out of memory!\n");
+
+ static RTSTATUSMSGINT2 s_aStatusMsgs2[RT_ELEMENTS(g_aStatusMsgs)];
+ unsigned cStatusMsgs = 0;
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
+ if (!g_aStatusMsgs[i].fDuplicate)
+ {
+ s_aStatusMsgs2[cStatusMsgs].idx1 = i;
+ s_aStatusMsgs2[cStatusMsgs].iCode = g_aStatusMsgs[i].iCode;
+ s_aStatusMsgs2[cStatusMsgs].pszDefine = g_aStatusMsgs[i].pszDefine;
+ BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].Define, g_aStatusMsgs[i].pszDefine);
+ cStatusMsgs++;
+ }
+
+ if (enmMode != kMode_OnlyDefines)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgShort, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgShort);
+
+ if (enmMode == kMode_All)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgFull, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgFull);
+
+ if (!BldProgStrTab_CompileIt(&StrTab, true))
+ return error("BldProgStrTab_CompileIt failed!\n");
+
+ /*
+ * Prepare output file.
+ */
+ FILE *pOut = fopen(pszOutFile, "wt");
+ if (pOut)
+ {
+ /*
+ * .
+ */
+ RTSTATUSMSGSTATS Defines = {0, 0, 0, 0};
+ RTSTATUSMSGSTATS MsgShort = {0, 0, 0, 0};
+ RTSTATUSMSGSTATS MsgFull = {0, 0, 0, 0};
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ {
+ GatherStringStats(&Defines, &s_aStatusMsgs2[i].Define);
+ GatherStringStats(&MsgShort, &s_aStatusMsgs2[i].MsgShort);
+ GatherStringStats(&MsgFull, &s_aStatusMsgs2[i].MsgFull);
+ }
+ CalcBitsForStringStats(&Defines);
+ CalcBitsForStringStats(&MsgShort);
+ CalcBitsForStringStats(&MsgFull);
+ printf(" Defines: max offset %#x -> %u bits, max length %#x -> bits %u\n",
+ Defines.offMax, Defines.cBitsOffset, (unsigned)Defines.cchMax, Defines.cBitsLength);
+ if (enmMode != kMode_OnlyDefines)
+ printf("MsgShort: max offset %#x -> %u bits, max length %#x -> bits %u\n",
+ MsgShort.offMax, MsgShort.cBitsOffset, (unsigned)MsgShort.cchMax, MsgShort.cBitsLength);
+ if (enmMode == kMode_All)
+ printf(" MsgFull: max offset %#x -> %u bits, max length %#x -> bits %u\n",
+ MsgFull.offMax, MsgFull.cBitsOffset, (unsigned)MsgFull.cchMax, MsgFull.cBitsLength);
+
+ unsigned cBitsCodePos = CalcBitsForValue((size_t)s_aStatusMsgs2[cStatusMsgs - 1].iCode);
+ unsigned cBitsCodeNeg = CalcBitsForValue((size_t)-s_aStatusMsgs2[0].iCode);
+ unsigned cBitsCode = RT_MAX(cBitsCodePos, cBitsCodeNeg) + 1;
+ printf("Statuses: min %d, max %d -> %u bits\n",
+ s_aStatusMsgs2[0].iCode, s_aStatusMsgs2[cStatusMsgs - 1].iCode, cBitsCode);
+
+ /*
+ * Print the table.
+ */
+ fprintf(pOut,
+ "\n"
+ "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n"
+ "# pragma pack(1)\n"
+ "#endif\n"
+ "typedef struct RTMSGENTRYINT\n"
+ "{\n");
+ /* 16 + 16 + 8 */
+ bool fOptimalLayout = true;
+ if ( enmMode == kMode_OnlyDefines
+ && cBitsCode <= 16
+ && Defines.cBitsOffset <= 16
+ && Defines.cBitsLength <= 8)
+ fprintf(pOut,
+ " uint16_t offDefine; /* need %2u bits, max %#x */\n"
+ " uint8_t cchDefine; /* need %2u bits, max %#x */\n"
+ " int16_t iCode; /* need %2u bits */\n",
+ Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax, cBitsCode);
+ else if ( enmMode == kMode_NoFullMsg
+ && cBitsCode + Defines.cBitsOffset + Defines.cBitsLength + MsgShort.cBitsOffset + MsgShort.cBitsLength <= 64)
+ fprintf(pOut,
+ " uint64_t offDefine : %2u; /* max %#x */\n"
+ " uint64_t cchDefine : %2u; /* max %#x */\n"
+ " uint64_t offMsgShort : %2u; /* max %#x */\n"
+ " uint64_t cchMsgShort : %2u; /* max %#x */\n"
+ " int64_t iCode : %2u;\n",
+ Defines.cBitsOffset, Defines.offMax,
+ Defines.cBitsLength, Defines.cchMax,
+ MsgShort.cBitsOffset, MsgShort.offMax,
+ MsgShort.cBitsLength, MsgShort.cchMax,
+ cBitsCode);
+ else if ( enmMode == kMode_All
+ && Defines.cBitsOffset + Defines.cBitsLength
+ + MsgShort.cBitsOffset + MsgShort.cBitsLength
+ + MsgFull.cBitsOffset + MsgFull.cBitsLength
+ + cBitsCode <= 96
+ && cBitsCode + Defines.cBitsLength + MsgShort.cBitsLength <= 32)
+ fprintf(pOut,
+ " uint64_t offDefine : %2u; /* max %#x */\n"
+ " uint64_t offMsgShort : %2u; /* max %#x */\n"
+ " uint64_t offMsgFull : %2u; /* max %#x */\n"
+ " uint64_t cchMsgFull : %2u; /* max %#x */\n"
+ " int32_t iCode : %2u;\n"
+ " uint32_t cchDefine : %2u; /* max %#x */\n"
+ " uint32_t cchMsgShort : %2u; /* max %#x */\n",
+ Defines.cBitsOffset, Defines.offMax,
+ MsgShort.cBitsOffset, MsgShort.offMax,
+ MsgFull.cBitsOffset, MsgFull.offMax,
+ MsgFull.cBitsLength, MsgFull.cchMax,
+ cBitsCode,
+ Defines.cBitsLength, Defines.cchMax,
+ MsgShort.cBitsLength, MsgShort.cchMax);
+ else
+ {
+ fprintf(stderr, "%s: warning: Optimized structure layouts needs readjusting...\n", g_pszProgName);
+ fOptimalLayout = false;
+ fprintf(pOut,
+ " uint32_t offDefine : 23; /* need %u bits, max %#x */\n"
+ " uint32_t cchDefine : 9; /* need %u bits, max %#x */\n",
+ Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax);
+ if (enmMode != kMode_OnlyDefines)
+ fprintf(pOut,
+ " uint32_t offMsgShort : 23; /* need %u bits, max %#x */\n"
+ " uint32_t cchMsgShort : 9; /* need %u bits, max %#x */\n",
+ MsgShort.cBitsOffset, MsgShort.offMax, MsgShort.cBitsLength, MsgShort.offMax);
+ if (enmMode == kMode_All)
+ fprintf(pOut,
+ " uint32_t offMsgFull : 23; /* need %u bits, max %#x */\n"
+ " uint32_t cchMsgFull : 9; /* need %u bits, max %#x */\n",
+ MsgFull.cBitsOffset, MsgFull.offMax, MsgFull.cBitsLength, MsgFull.cchMax);
+ fprintf(pOut,
+ " int32_t iCode; /* need %u bits */\n", cBitsCode);
+ }
+ fprintf(pOut,
+ "} RTMSGENTRYINT;\n"
+ "typedef RTMSGENTRYINT *PCRTMSGENTRYINT;\n"
+ "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n"
+ "# pragma pack()\n"
+ "#endif\n"
+ "\n"
+ "static const RTMSGENTRYINT g_aStatusMsgs[ /*%lu*/ ] =\n"
+ "{\n"
+ ,
+ (unsigned long)cStatusMsgs);
+
+ if (enmMode == kMode_All && fOptimalLayout)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ fprintf(pOut, " { %#08x, %#08x, %#08x, %3u, %6d, %3u, %3u }, /* %s */\n",
+ s_aStatusMsgs2[i].Define.offStrTab,
+ s_aStatusMsgs2[i].MsgShort.offStrTab,
+ s_aStatusMsgs2[i].MsgFull.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
+ s_aStatusMsgs2[i].iCode,
+ (unsigned)s_aStatusMsgs2[i].Define.cchString,
+ (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
+ s_aStatusMsgs2[i].pszDefine);
+ else if (enmMode == kMode_All)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ fprintf(pOut, " { %#08x, %3u, %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n",
+ s_aStatusMsgs2[i].Define.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].Define.cchString,
+ s_aStatusMsgs2[i].MsgShort.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
+ s_aStatusMsgs2[i].MsgFull.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
+ s_aStatusMsgs2[i].iCode,
+ s_aStatusMsgs2[i].pszDefine);
+ else if (enmMode == kMode_NoFullMsg)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ fprintf(pOut, " { %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n",
+ s_aStatusMsgs2[i].Define.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].Define.cchString,
+ s_aStatusMsgs2[i].MsgShort.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
+ s_aStatusMsgs2[i].iCode,
+ s_aStatusMsgs2[i].pszDefine);
+ else if (enmMode == kMode_OnlyDefines)
+ for (size_t i = 0; i < cStatusMsgs; i++)
+ fprintf(pOut, " { %#08x, %3u, %8d }, /* %s */\n",
+ s_aStatusMsgs2[i].Define.offStrTab,
+ (unsigned)s_aStatusMsgs2[i].Define.cchString,
+ s_aStatusMsgs2[i].iCode,
+ s_aStatusMsgs2[i].pszDefine);
+ else
+ return error("Unsupported message selection (%d)!\n", enmMode);
+ fprintf(pOut,
+ "};\n"
+ "\n");
+
+ BldProgStrTab_WriteStringTable(&StrTab, pOut, "static ", "g_", "StatusMsgStrTab");
+
+ /*
+ * Close the output file and we're done.
+ */
+ fflush(pOut);
+ if (ferror(pOut))
+ rcExit = error("Error writing '%s'!\n", pszOutFile);
+ if (fclose(pOut) != 0)
+ rcExit = error("Failed to close '%s' after writing it!\n", pszOutFile);
+ }
+ else
+ rcExit = error("Failed to open '%s' for writing!\n", pszOutFile);
+ return rcExit;
+}
+
diff --git a/src/VBox/Runtime/common/err/errmsg.cpp b/src/VBox/Runtime/common/err/errmsg.cpp
new file mode 100644
index 00000000..5e37cba7
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errmsg.cpp
@@ -0,0 +1,338 @@
+/* $Id: errmsg.cpp $ */
+/** @file
+ * IPRT - Status code messages.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/string.h>
+#include <VBox/err.h>
+
+#include <iprt/bldprog-strtab.h>
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#if (defined(IN_RT_STATIC) || defined(IPRT_ERRMSG_DEFINES_ONLY)) && !defined(IPRT_ERRMSG_NO_FULL_MSG)
+/** Skip the full message in static builds to save space.
+ * This is defined when IPRT_ERRMSG_DEFINES_ONLY is defined. */
+# define IPRT_ERRMSG_NO_FULL_MSG
+#endif
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+#ifdef IPRT_NO_ERROR_DATA
+/* Cook data just for VINF_SUCCESS so that code below compiles fine. */
+static const char g_achStrTabData[] = { "VINF_SUCCESS" };
+static const RTBLDPROGSTRTAB g_StatusMsgStrTab = { g_achStrTabData, sizeof(g_achStrTabData) - 1, 0, NULL };
+static const struct
+{
+ int16_t iCode;
+ uint8_t offDefine;
+ uint8_t cchDefine;
+ uint8_t offMsgShort;
+ uint8_t cchMsgShort;
+ uint8_t offMsgFull;
+ uint8_t cchMsgFull;
+} g_aStatusMsgs[] =
+{
+ { VINF_SUCCESS, 0, 12, 0, 12, 0, 12, },
+};
+#elif defined(IPRT_ERRMSG_DEFINES_ONLY)
+# include "errmsgdata-only-defines.h"
+#elif defined(IPRT_ERRMSG_NO_FULL_MSG)
+# include "errmsgdata-no-full-msg.h"
+#else
+# include "errmsgdata-all.h"
+#endif
+
+
+/**
+ * Looks up the message table entry for @a rc.
+ *
+ * @returns index into g_aStatusMsgs on success, ~(size_t)0 if not found.
+ * @param rc The status code to locate the entry for.
+ */
+static size_t rtErrLookup(int rc)
+{
+ /*
+ * Perform binary search (duplicate code in rtErrWinLookup).
+ */
+ size_t iStart = 0;
+ size_t iEnd = RT_ELEMENTS(g_aStatusMsgs);
+ for (;;)
+ {
+ size_t i = iStart + (iEnd - iStart) / 2;
+ int const iCode = g_aStatusMsgs[i].iCode;
+ if (rc < iCode)
+ {
+ if (iStart < i)
+ iEnd = i;
+ else
+ break;
+ }
+ else if (rc > iCode)
+ {
+ i++;
+ if (i < iEnd)
+ iStart = i;
+ else
+ break;
+ }
+ else
+ return i;
+ }
+
+#ifdef RT_STRICT
+ for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
+ Assert(g_aStatusMsgs[i].iCode != rc);
+#endif
+
+ return ~(size_t)0;
+}
+
+
+RTDECL(bool) RTErrIsKnown(int rc)
+{
+ return rtErrLookup(rc) != ~(size_t)0;
+}
+RT_EXPORT_SYMBOL(RTErrIsKnown);
+
+
+RTDECL(ssize_t) RTErrQueryDefine(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
+{
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+ return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
+ pszBuf, cbBuf);
+ if (fFailIfUnknown)
+ return VERR_NOT_FOUND;
+ return RTStrFormatU32(pszBuf, cbBuf, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
+}
+RT_EXPORT_SYMBOL(RTErrQueryDefine);
+
+
+/**
+ * Helper for rtErrQueryMsgNotFound.
+ */
+DECLINLINE(ssize_t) rtErrQueryCopyHelper(char **ppszBuf, size_t *pcbBuf, const char *pszSrc, size_t cchSrc, ssize_t cchRet)
+{
+ char *pszDst = *ppszBuf;
+ size_t cbDst = *pcbBuf;
+ if (cbDst > cchSrc)
+ {
+ memcpy(pszDst, pszSrc, cchSrc);
+ cbDst -= cchSrc;
+ pszDst += cchSrc;
+ cchRet += cchSrc;
+ *pszDst = '\0';
+ }
+ else
+ {
+ while (cbDst > 1 && cchSrc > 0)
+ {
+ *pszDst++ = *pszSrc++;
+ cchSrc--;
+ cbDst--;
+ }
+ if (cbDst > 0)
+ *pszDst = '\0';
+ cchRet = VERR_BUFFER_OVERFLOW;
+ }
+ *ppszBuf = pszDst;
+ *pcbBuf = cbDst;
+ return cchRet;
+}
+
+
+/**
+ * RTErrQueryMsgShort & RTErrQueryMsgFull helper.
+ */
+DECL_NO_INLINE(static, ssize_t) rtErrQueryMsgNotFound(int rc, char *pszBuf, size_t cbBuf)
+{
+ /* Unknown Status %d (%#x) */
+ ssize_t cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE("Unknown Status "), 0);
+ char szValue[64];
+ size_t cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 10, 0, 0, RTSTR_F_VALSIGNED);
+ cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet);
+ cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(" ("), cchRet);
+ cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 16, 0, 0, RTSTR_F_SPECIAL);
+ cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet);
+ cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(")"), cchRet);
+ return cchRet;
+}
+
+
+RTDECL(ssize_t) RTErrQueryMsgShort(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
+{
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+#ifdef IPRT_ERRMSG_DEFINES_ONLY
+ return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
+ pszBuf, cbBuf);
+#else
+ return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
+ pszBuf, cbBuf);
+#endif
+ if (fFailIfUnknown)
+ return VERR_NOT_FOUND;
+ return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf);
+}
+RT_EXPORT_SYMBOL(RTErrQueryMsgShort);
+
+
+RTDECL(ssize_t) RTErrQueryMsgFull(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
+{
+#if defined(IPRT_ERRMSG_DEFINES_ONLY) || defined(IPRT_ERRMSG_NO_FULL_MSG)
+ return RTErrQueryMsgShort(rc, pszBuf, cbBuf, fFailIfUnknown);
+#else
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+ return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
+ pszBuf, cbBuf);
+ if (fFailIfUnknown)
+ return VERR_NOT_FOUND;
+ return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf);
+#endif
+}
+RT_EXPORT_SYMBOL(RTErrQueryMsgShort);
+
+
+RTDECL(size_t) RTErrFormatDefine(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
+{
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+ return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
+ pfnOutput, pvArgOutput);
+ size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
+ return pfnOutput(pvArgOutput, pszTmp, cchValue);
+}
+RT_EXPORT_SYMBOL(RTErrFormatDefine);
+
+
+/**
+ * RTErrFormatMsgShort & RTErrFormatMsgFull helper.
+ */
+static size_t rtErrFormatMsgNotFound(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
+{
+ size_t cchRet = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status "));
+ size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
+ cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
+ cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
+ cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(")"));
+ return cchRet;
+}
+
+
+RTDECL(size_t) RTErrFormatMsgShort(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
+{
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+#ifndef IPRT_ERRMSG_DEFINES_ONLY
+ return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
+ pfnOutput, pvArgOutput);
+#else
+ return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
+ pfnOutput, pvArgOutput);
+#endif
+ return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
+}
+RT_EXPORT_SYMBOL(RTErrFormatMsgShort);
+
+
+RTDECL(size_t) RTErrFormatMsgFull(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
+{
+#ifdef IPRT_ERRMSG_NO_FULL_MSG
+ return RTErrFormatMsgShort(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
+#else
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+ return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
+ pfnOutput, pvArgOutput);
+ return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
+#endif
+}
+RT_EXPORT_SYMBOL(RTErrFormatMsgFull);
+
+
+RTDECL(size_t) RTErrFormatMsgAll(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
+{
+ size_t idx = rtErrLookup(rc);
+ if (idx != ~(size_t)0)
+ {
+ size_t cchValue;
+ size_t cchRet = RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
+ pfnOutput, pvArgOutput);
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
+ cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
+ cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
+#ifdef IPRT_ERRMSG_DEFINES_ONLY
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(")"));
+#elif defined(IPRT_ERRMSG_NO_FULL_MSG)
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - "));
+ cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
+ pfnOutput, pvArgOutput);
+#else
+ cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - "));
+ cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
+ g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
+ pfnOutput, pvArgOutput);
+#endif
+ return cchRet;
+ }
+ return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
+}
+RT_EXPORT_SYMBOL(RTErrFormatMsgAll);
+
diff --git a/src/VBox/Runtime/common/err/errmsg.sed b/src/VBox/Runtime/common/err/errmsg.sed
new file mode 100644
index 00000000..97febba9
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errmsg.sed
@@ -0,0 +1,98 @@
+# $Id: errmsg.sed $
+## @file
+# IPRT - SED script for converting */err.h.
+#
+
+#
+# Copyright (C) 2006-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+# Handle text inside the markers.
+/SED-START/,/SED-END/{
+
+# if (#define) goto defines
+/^[[:space:]]*#[[:space:]]*define/b defines
+
+# if (/**) goto description
+/\/\*\*/b description
+
+}
+
+# Everything else is deleted!
+d
+b end
+
+
+##
+# Convert the defines
+:defines
+s/^[[:space:]]*#[[:space:]]*define[[:space:]]*\([[:alnum:]_]*\)[[:space:]]*\(.*\)[[:space:]]*$/ "\1",\n \1, false }, /
+b end
+
+##
+# Convert descriptive comments. /** desc */
+:description
+
+# Read all the lines belonging to the comment into the buffer.
+:look-for-end-of-comment
+/\*\//bend-of-comment
+N
+blook-for-end-of-comment
+:end-of-comment
+
+# anything with @{ and @} is skipped
+/@[\{\}]/d
+
+# Fix double spaces
+s/[[:space:]][[:space:]]/ /g
+
+# Fix \# sequences (doxygen needs them, we don't).
+s/\\#/#/g
+
+# insert punctuation.
+s/\([^.[:space:]]\)[[:space:]]*\*\//\1. \*\//
+
+# convert /** short. more
+s/[[:space:]]*\/\*\*[[:space:]]*/ { NULL, \"/
+s/ { NULL, \"\([^.!?"]*[.!?][.!?]*\)/ { \"\1\",\n \"\1/
+
+# terminate the string
+s/[[:space:]]*\*\//\"\,/
+
+# translate empty lines into new-lines (only one, please).
+s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*\*[[:space:]][[:space:]]*/\\n/g
+
+# remove asterics.
+s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*/ /g
+b end
+
+
+# next expression
+:end
diff --git a/src/VBox/Runtime/common/err/errmsgcom.sed b/src/VBox/Runtime/common/err/errmsgcom.sed
new file mode 100644
index 00000000..01d7f7fe
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errmsgcom.sed
@@ -0,0 +1,76 @@
+# $Id: errmsgcom.sed $
+## @file
+# IPRT - SED script for converting COM errors
+#
+
+#
+# Copyright (C) 2006-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+# we only care about message definitions
+/No symbolic name defined/b skip_it
+\/\/ MessageId: /b messageid
+d
+b end
+
+
+# Everything else is deleted!
+:skip_it
+d
+b end
+
+
+#
+# A message ID we care about
+#
+:messageid
+# concatenate the next four lines to the string
+N
+N
+N
+N
+{
+ # remove DOS <CR>.
+ s/\r//g
+ # remove the message ID
+ s/\/\/ MessageId: //g
+ # remove the stuff in between
+ s/\/\/\n\/\/ MessageText:\n\/\/\n\/\/ *//g
+ # backslashes have to be escaped
+ s/\\/\\\\/g
+ # double quotes have to be escaped, too
+ s/"/\\"/g
+ # output C array entry
+ s/\([[:alnum:]_]*\)[\t ]*\n\(.*\)[\t ]*$/{ "\2", "\1", \1 }, /
+}
+b end
+
+# next expression
+:end
diff --git a/src/VBox/Runtime/common/err/errmsgxpcom.cpp b/src/VBox/Runtime/common/err/errmsgxpcom.cpp
new file mode 100644
index 00000000..170f7dea
--- /dev/null
+++ b/src/VBox/Runtime/common/err/errmsgxpcom.cpp
@@ -0,0 +1,170 @@
+/* $Id: errmsgxpcom.cpp $ */
+/** @file
+ * IPRT - Status code messages for XPCOM.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/errcore.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/string.h>
+#include <iprt/errcore.h>
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+typedef uint32_t VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/** Array of messages.
+ * The data is generated by a sed script.
+ */
+static const RTCOMERRMSG g_aStatusMsgs[] =
+{
+#define MY_ERR(_def, _desc, _val) { _desc, _def, _val }
+
+ MY_ERR("NS_OK", "Success", UINT32_C(0x00000000)),
+ MY_ERR("NS_ERROR_NOT_IMPLEMENTED", "Not implemented", UINT32_C(0x80004001)),
+ MY_ERR("NS_ERROR_NO_INTERFACE", "Interface not supported", UINT32_C(0x80004002)),
+ MY_ERR("NS_ERROR_INVALID_POINTER", "Invalid pointer value", UINT32_C(0x80004003)),
+ MY_ERR("NS_ERROR_ABORT", "Operation aborted", UINT32_C(0x80004004)),
+ MY_ERR("NS_ERROR_FAILURE", "Operation failed", UINT32_C(0x80004005)),
+ MY_ERR("NS_ERROR_CALL_FAILED", "Call to remote object failed", UINT32_C(0x800706be)),
+ MY_ERR("NS_ERROR_UNEXPECTED", "Unexpected error", UINT32_C(0x8000ffff)),
+
+ MY_ERR("NS_ERROR_CANNOT_CONVERT_DATA", "Cannot convert data", UINT32_C(0x80010001)),
+ MY_ERR("NS_ERROR_OBJECT_IS_IMMUTABLE", "Object is immutable", UINT32_C(0x80010002)),
+ MY_ERR("NS_ERROR_LOSS_OF_SIGNIFICANT_DATA", "Loss of significant data", UINT32_C(0x80010003)),
+ MY_ERR("NS_ERROR_PROXY_INVALID_IN_PARAMETER", "Cannot proxy an IN parameter", UINT32_C(0x80010010)),
+ MY_ERR("NS_ERROR_PROXY_INVALID_OUT_PARAMETER", "Cannot proxy an OUT parameter", UINT32_C(0x80010011)),
+ MY_ERR("NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA", "Loss of insignificant data", UINT32_C(0x00010001)),
+
+ MY_ERR("E_ACCESSDENIED", "Access denied", UINT32_C(0x80070005)), /* VirtualBox addition */
+ MY_ERR("NS_ERROR_OUT_OF_MEMORY", "Memory allocation failed", UINT32_C(0x8007000e)),
+ MY_ERR("NS_ERROR_INVALID_ARG", "Invalid argument value", UINT32_C(0x80070057)),
+
+ MY_ERR("NS_ERROR_NO_AGGREGATION", "Class does not allow aggregation", UINT32_C(0x80040110)),
+ MY_ERR("NS_ERROR_NOT_AVAILABLE", "Resource not available", UINT32_C(0x80040111)),
+ MY_ERR("NS_ERROR_FACTORY_NOT_REGISTERED", "Class not registered", UINT32_C(0x80040154)),
+ MY_ERR("NS_ERROR_FACTORY_REGISTER_AGAIN", "Cannot be registered, try again later", UINT32_C(0x80040155)),
+ MY_ERR("NS_ERROR_FACTORY_NOT_LOADED", "Dynamically loaded factory cannot be found", UINT32_C(0x800401f8)),
+ MY_ERR("NS_ERROR_FACTORY_EXISTS", "Factory already exists", UINT32_C(0xc1f30100)),
+ MY_ERR("NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT", "Factory does not support signatures", UINT32_C(0xc1f30101)),
+ MY_ERR("NS_ERROR_NOT_INITIALIZED", "Instance not initialized", UINT32_C(0xc1f30001)),
+ MY_ERR("NS_ERROR_ALREADY_INITIALIZED", "Instance already initialized", UINT32_C(0xc1f30002)),
+
+ MY_ERR("NS_BASE_STREAM_CLOSED", "Stream closed", UINT32_C(0x80470002)),
+ MY_ERR("NS_BASE_STREAM_OSERROR", "Operative system stream error", UINT32_C(0x80470003)),
+ MY_ERR("NS_BASE_STREAM_ILLEGAL_ARGS", "Illegal argument to stream method", UINT32_C(0x80470004)),
+ MY_ERR("NS_BASE_STREAM_NO_CONVERTER", "No stream converter", UINT32_C(0x80470005)),
+ MY_ERR("NS_BASE_STREAM_BAD_CONVERSION", "Badstream conversion", UINT32_C(0x80470006)),
+ MY_ERR("NS_BASE_STREAM_WOULD_BLOCK", "Stream operation would block", UINT32_C(0x80470007)),
+
+ MY_ERR("NS_ERROR_FILE_UNRECOGNIZED_PATH", "Unrecognized path", UINT32_C(0x80520001)),
+ MY_ERR("NS_ERROR_FILE_UNRESOLVABLE_SYMLINK", "NS_ERROR_FILE_UNRESOLVABLE_SYMLINK", UINT32_C(0x80520002)),
+ MY_ERR("NS_ERROR_FILE_EXECUTION_FAILED", "NS_ERROR_FILE_EXECUTION_FAILED", UINT32_C(0x80520003)),
+ MY_ERR("NS_ERROR_FILE_UNKNOWN_TYPE", "NS_ERROR_FILE_UNKNOWN_TYPE", UINT32_C(0x80520004)),
+ MY_ERR("NS_ERROR_FILE_DESTINATION_NOT_DIR", "NS_ERROR_FILE_DESTINATION_NOT_DIR", UINT32_C(0x80520005)),
+ MY_ERR("NS_ERROR_FILE_TARGET_DOES_NOT_EXIST", "NS_ERROR_FILE_TARGET_DOES_NOT_EXIST", UINT32_C(0x80520006)),
+ MY_ERR("NS_ERROR_FILE_COPY_OR_MOVE_FAILED", "NS_ERROR_FILE_COPY_OR_MOVE_FAILED", UINT32_C(0x80520007)),
+ MY_ERR("NS_ERROR_FILE_ALREADY_EXISTS", "NS_ERROR_FILE_ALREADY_EXISTS", UINT32_C(0x80520008)),
+ MY_ERR("NS_ERROR_FILE_INVALID_PATH", "NS_ERROR_FILE_INVALID_PATH", UINT32_C(0x80520009)),
+ MY_ERR("NS_ERROR_FILE_DISK_FULL", "NS_ERROR_FILE_DISK_FULL", UINT32_C(0x8052000a)),
+ MY_ERR("NS_ERROR_FILE_CORRUPTED", "NS_ERROR_FILE_CORRUPTED", UINT32_C(0x8052000b)),
+ MY_ERR("NS_ERROR_FILE_NOT_DIRECTORY", "NS_ERROR_FILE_NOT_DIRECTORY", UINT32_C(0x8052000c)),
+ MY_ERR("NS_ERROR_FILE_IS_DIRECTORY", "NS_ERROR_FILE_IS_DIRECTORY", UINT32_C(0x8052000d)),
+ MY_ERR("NS_ERROR_FILE_IS_LOCKED", "NS_ERROR_FILE_IS_LOCKED", UINT32_C(0x8052000e)),
+ MY_ERR("NS_ERROR_FILE_TOO_BIG", "NS_ERROR_FILE_TOO_BIG", UINT32_C(0x8052000f)),
+ MY_ERR("NS_ERROR_FILE_NO_DEVICE_SPACE", "NS_ERROR_FILE_NO_DEVICE_SPACE", UINT32_C(0x80520010)),
+ MY_ERR("NS_ERROR_FILE_NAME_TOO_LONG", "NS_ERROR_FILE_NAME_TOO_LONG", UINT32_C(0x80520011)),
+ MY_ERR("NS_ERROR_FILE_NOT_FOUND", "NS_ERROR_FILE_NOT_FOUND", UINT32_C(0x80520012)),
+ MY_ERR("NS_ERROR_FILE_READ_ONLY", "NS_ERROR_FILE_READ_ONLY", UINT32_C(0x80520013)),
+ MY_ERR("NS_ERROR_FILE_DIR_NOT_EMPTY", "NS_ERROR_FILE_DIR_NOT_EMPTY", UINT32_C(0x80520014)),
+ MY_ERR("NS_ERROR_FILE_ACCESS_DENIED", "NS_ERROR_FILE_ACCESS_DENIED", UINT32_C(0x80520015)),
+ MY_ERR("NS_SUCCESS_FILE_DIRECTORY_EMPTY", "NS_SUCCESS_FILE_DIRECTORY_EMPTY", UINT32_C(0x00520001)),
+ MY_ERR("NS_ERROR_SOCKET_FAIL", "IPC daemon socket error", UINT32_C(0xc1f30200)), /* new XPCOM error code */
+
+#if defined(VBOX) && !defined(IN_GUEST) && !defined(DOXYGEN_RUNNING)
+# include "errmsgvboxcomdata.h"
+#endif
+
+ { NULL, NULL, 0 }
+#undef MY_ERR
+};
+
+
+/** Temporary buffers to format unknown messages in.
+ * @{
+ */
+static char g_aszUnknownStr[8][64];
+static RTCOMERRMSG g_aUnknownMsgs[8] =
+{
+ { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
+ { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
+ { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
+ { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 },
+ { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 },
+ { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 },
+ { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 },
+ { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 }
+};
+/** Last used index in g_aUnknownMsgs. */
+static volatile uint32_t g_iUnknownMsgs;
+/** @} */
+
+
+RTDECL(PCRTCOMERRMSG) RTErrCOMGet(uint32_t rc)
+{
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1; i++)
+ if (g_aStatusMsgs[i].iCode == rc)
+ return &g_aStatusMsgs[i];
+
+ /*
+ * Need to use the temporary stuff.
+ */
+ int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs);
+ RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "Unknown Status 0x%X", rc);
+ return &g_aUnknownMsgs[iMsg];
+}
+RT_EXPORT_SYMBOL(RTErrCOMGet);
+
diff --git a/src/VBox/Runtime/common/err/nocrt-strerror.cpp b/src/VBox/Runtime/common/err/nocrt-strerror.cpp
new file mode 100644
index 00000000..e26136ea
--- /dev/null
+++ b/src/VBox/Runtime/common/err/nocrt-strerror.cpp
@@ -0,0 +1,464 @@
+/* $Id: nocrt-strerror.cpp $ */
+/** @file
+ * IPRT - No-CRT - Convert errno value to string.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#define IPRT_NO_CRT_FOR_3RD_PARTY
+#include "internal/nocrt.h"
+#include <iprt/nocrt/string.h>
+#include <iprt/nocrt/errno.h>
+#include <iprt/assert.h>
+#include <iprt/log.h>
+
+
+#undef strerror
+const char *RT_NOCRT(strerror)(int iErrNo)
+{
+ /*
+ * Process error codes.
+ *
+ * (Use a switch and not a table since the numbers vary among compilers
+ * and OSes. So we let the compiler switch optimizer handle speed issues.)
+ *
+ * This switch is arranged like the Linux i386 errno.h! This switch is mirrored
+ * by RTErrConvertToErrno and RTErrConvertFromErrno.
+ */
+ switch (iErrNo)
+ { /* Linux number */
+ case 0: return "no error";
+#ifdef EPERM
+ RT_CASE_RET_STR(EPERM); /* 1 */
+#endif
+#ifdef ENOENT
+ RT_CASE_RET_STR(ENOENT);
+#endif
+#ifdef ESRCH
+ RT_CASE_RET_STR(ESRCH);
+#endif
+#ifdef EINTR
+ RT_CASE_RET_STR(EINTR);
+#endif
+#ifdef EIO
+ RT_CASE_RET_STR(EIO);
+#endif
+#ifdef ENXIO
+ RT_CASE_RET_STR(ENXIO); /** @todo fix this duplicate error */
+#endif
+#ifdef E2BIG
+ RT_CASE_RET_STR(E2BIG);
+#endif
+#ifdef ENOEXEC
+ RT_CASE_RET_STR(ENOEXEC);
+#endif
+#ifdef EBADF
+ RT_CASE_RET_STR(EBADF);
+#endif
+#ifdef ECHILD
+ RT_CASE_RET_STR(ECHILD); /* 10 */ /** @todo fix duplicate error */
+#endif
+#ifdef EAGAIN
+ RT_CASE_RET_STR(EAGAIN);
+#endif
+#ifdef ENOMEM
+ RT_CASE_RET_STR(ENOMEM);
+#endif
+#ifdef EACCES
+ RT_CASE_RET_STR(EACCES); /** @todo fix duplicate error */
+#endif
+#ifdef EFAULT
+ RT_CASE_RET_STR(EFAULT);
+#endif
+#ifdef ENOTBLK
+ RT_CASE_RET_STR(ENOTBLK);
+#endif
+#ifdef EBUSY
+ RT_CASE_RET_STR(EBUSY);
+#endif
+#ifdef EEXIST
+ RT_CASE_RET_STR(EEXIST);
+#endif
+#ifdef EXDEV
+ RT_CASE_RET_STR(EXDEV);
+#endif
+#ifdef ENODEV
+ RT_CASE_RET_STR(ENODEV); /** @todo fix duplicate error */
+#endif
+#ifdef ENOTDIR
+ RT_CASE_RET_STR(ENOTDIR); /* 20 */
+#endif
+#ifdef EISDIR
+ RT_CASE_RET_STR(EISDIR);
+#endif
+#ifdef EINVAL
+ RT_CASE_RET_STR(EINVAL);
+#endif
+#ifdef ENFILE
+ RT_CASE_RET_STR(ENFILE); /** @todo fix duplicate error */
+#endif
+#ifdef EMFILE
+ RT_CASE_RET_STR(EMFILE);
+#endif
+#ifdef ENOTTY
+ RT_CASE_RET_STR(ENOTTY);
+#endif
+#ifdef ETXTBSY
+ RT_CASE_RET_STR(ETXTBSY);
+#endif
+#ifdef EFBIG
+ RT_CASE_RET_STR(EFBIG);
+#endif
+#ifdef ENOSPC
+ RT_CASE_RET_STR(ENOSPC);
+#endif
+#ifdef ESPIPE
+ RT_CASE_RET_STR(ESPIPE);
+#endif
+#ifdef EROFS
+ RT_CASE_RET_STR(EROFS); /* 30 */
+#endif
+#ifdef EMLINK
+ RT_CASE_RET_STR(EMLINK);
+#endif
+#ifdef EPIPE
+ RT_CASE_RET_STR(EPIPE);
+#endif
+#ifdef EDOM
+ RT_CASE_RET_STR(EDOM); /** @todo fix duplicate error */
+#endif
+#ifdef ERANGE
+ RT_CASE_RET_STR(ERANGE); /** @todo fix duplicate error */
+#endif
+#ifdef EDEADLK
+ RT_CASE_RET_STR(EDEADLK);
+#endif
+#ifdef ENAMETOOLONG
+ RT_CASE_RET_STR(ENAMETOOLONG);
+#endif
+#ifdef ENOLCK
+ RT_CASE_RET_STR(ENOLCK);
+#endif
+#ifdef ENOSYS /** @todo map this differently on solaris. */
+ RT_CASE_RET_STR(ENOSYS);
+#endif
+#ifdef ENOTEMPTY
+ RT_CASE_RET_STR(ENOTEMPTY);
+#endif
+#ifdef ELOOP
+ RT_CASE_RET_STR(ELOOP); /* 40 */
+#endif
+ //41??
+#ifdef ENOMSG
+ RT_CASE_RET_STR(ENOMSG);
+#endif
+#ifdef EIDRM
+ RT_CASE_RET_STR(EIDRM);
+#endif
+#ifdef ECHRNG
+ RT_CASE_RET_STR(ECHRNG);
+#endif
+#ifdef EL2NSYNC
+ RT_CASE_RET_STR(EL2NSYNC);
+#endif
+#ifdef EL3HLT
+ RT_CASE_RET_STR(EL3HLT);
+#endif
+#ifdef EL3RST
+ RT_CASE_RET_STR(EL3RST);
+#endif
+#ifdef ELNRNG
+ RT_CASE_RET_STR(ELNRNG);
+#endif
+#ifdef EUNATCH
+ RT_CASE_RET_STR(EUNATCH);
+#endif
+#ifdef ENOCSI
+ RT_CASE_RET_STR(ENOCSI);
+#endif
+#ifdef EL2HLT
+ RT_CASE_RET_STR(EL2HLT);
+#endif
+#ifdef EBADE
+ RT_CASE_RET_STR(EBADE);
+#endif
+#ifdef EBADR
+ RT_CASE_RET_STR(EBADR);
+#endif
+#ifdef EXFULL
+ RT_CASE_RET_STR(EXFULL);
+#endif
+#ifdef ENOANO
+ RT_CASE_RET_STR(ENOANO);
+#endif
+#ifdef EBADRQC
+ RT_CASE_RET_STR(EBADRQC);
+#endif
+#ifdef EBADSLT
+ RT_CASE_RET_STR(EBADSLT);
+#endif
+ //case 58:
+#ifdef EBFONT
+ RT_CASE_RET_STR(EBFONT);
+#endif
+#ifdef ENOSTR
+ RT_CASE_RET_STR(ENOSTR);
+#endif
+#ifdef ENODATA
+ RT_CASE_RET_STR(ENODATA);
+#endif
+#ifdef ETIME
+ RT_CASE_RET_STR(ETIME);
+#endif
+#ifdef ENOSR
+ RT_CASE_RET_STR(ENOSR);
+#endif
+#ifdef ENONET
+ RT_CASE_RET_STR(ENONET);
+#endif
+#ifdef ENOPKG
+ RT_CASE_RET_STR(ENOPKG);
+#endif
+#ifdef EREMOTE
+ RT_CASE_RET_STR(EREMOTE);
+#endif
+#ifdef ENOLINK
+ RT_CASE_RET_STR(ENOLINK);
+#endif
+#ifdef EADV
+ RT_CASE_RET_STR(EADV);
+#endif
+#ifdef ESRMNT
+ RT_CASE_RET_STR(ESRMNT);
+#endif
+#ifdef ECOMM
+ RT_CASE_RET_STR(ECOMM);
+#endif
+#ifdef EPROTO
+ RT_CASE_RET_STR(EPROTO);
+#endif
+#ifdef EMULTIHOP
+ RT_CASE_RET_STR(EMULTIHOP);
+#endif
+#ifdef EDOTDOT
+ RT_CASE_RET_STR(EDOTDOT);
+#endif
+#ifdef EBADMSG
+ RT_CASE_RET_STR(EBADMSG);
+#endif
+#ifdef EOVERFLOW
+ RT_CASE_RET_STR(EOVERFLOW); /** @todo fix duplicate error? */
+#endif
+#ifdef ENOTUNIQ
+ RT_CASE_RET_STR(ENOTUNIQ);
+#endif
+#ifdef EBADFD
+ RT_CASE_RET_STR(EBADFD); /** @todo fix duplicate error? */
+#endif
+#ifdef EREMCHG
+ RT_CASE_RET_STR(EREMCHG);
+#endif
+#ifdef ELIBACC
+ RT_CASE_RET_STR(ELIBACC);
+#endif
+#ifdef ELIBBAD
+ RT_CASE_RET_STR(ELIBBAD);
+#endif
+#ifdef ELIBSCN
+ RT_CASE_RET_STR(ELIBSCN);
+#endif
+#ifdef ELIBMAX
+ RT_CASE_RET_STR(ELIBMAX);
+#endif
+#ifdef ELIBEXEC
+ RT_CASE_RET_STR(ELIBEXEC);
+#endif
+#ifdef EILSEQ
+ RT_CASE_RET_STR(EILSEQ);
+#endif
+#ifdef ERESTART
+ RT_CASE_RET_STR(ERESTART);/** @todo fix duplicate error?*/
+#endif
+#ifdef ESTRPIPE
+ RT_CASE_RET_STR(ESTRPIPE);
+#endif
+#ifdef EUSERS
+ RT_CASE_RET_STR(EUSERS);
+#endif
+#ifdef ENOTSOCK
+ RT_CASE_RET_STR(ENOTSOCK);
+#endif
+#ifdef EDESTADDRREQ
+ RT_CASE_RET_STR(EDESTADDRREQ);
+#endif
+#ifdef EMSGSIZE
+ RT_CASE_RET_STR(EMSGSIZE);
+#endif
+#ifdef EPROTOTYPE
+ RT_CASE_RET_STR(EPROTOTYPE);
+#endif
+#ifdef ENOPROTOOPT
+ RT_CASE_RET_STR(ENOPROTOOPT);
+#endif
+#ifdef EPROTONOSUPPORT
+ RT_CASE_RET_STR(EPROTONOSUPPORT);
+#endif
+#ifdef ESOCKTNOSUPPORT
+ RT_CASE_RET_STR(ESOCKTNOSUPPORT);
+#endif
+#ifdef EOPNOTSUPP /** @todo map this differently on solaris. */
+ RT_CASE_RET_STR(EOPNOTSUPP);
+#endif
+#ifdef EPFNOSUPPORT
+ RT_CASE_RET_STR(EPFNOSUPPORT);
+#endif
+#ifdef EAFNOSUPPORT
+ RT_CASE_RET_STR(EAFNOSUPPORT);
+#endif
+#ifdef EADDRINUSE
+ RT_CASE_RET_STR(EADDRINUSE);
+#endif
+#ifdef EADDRNOTAVAIL
+ RT_CASE_RET_STR(EADDRNOTAVAIL);
+#endif
+#ifdef ENETDOWN
+ RT_CASE_RET_STR(ENETDOWN);
+#endif
+#ifdef ENETUNREACH
+ RT_CASE_RET_STR(ENETUNREACH);
+#endif
+#ifdef ENETRESET
+ RT_CASE_RET_STR(ENETRESET);
+#endif
+#ifdef ECONNABORTED
+ RT_CASE_RET_STR(ECONNABORTED);
+#endif
+#ifdef ECONNRESET
+ RT_CASE_RET_STR(ECONNRESET);
+#endif
+#ifdef ENOBUFS
+ RT_CASE_RET_STR(ENOBUFS);
+#endif
+#ifdef EISCONN
+ RT_CASE_RET_STR(EISCONN);
+#endif
+#ifdef ENOTCONN
+ RT_CASE_RET_STR(ENOTCONN);
+#endif
+#ifdef ESHUTDOWN
+ RT_CASE_RET_STR(ESHUTDOWN);
+#endif
+#ifdef ETOOMANYREFS
+ RT_CASE_RET_STR(ETOOMANYREFS);
+#endif
+#ifdef ETIMEDOUT
+ RT_CASE_RET_STR(ETIMEDOUT);
+#endif
+#ifdef ECONNREFUSED
+ RT_CASE_RET_STR(ECONNREFUSED);
+#endif
+#ifdef EHOSTDOWN
+ RT_CASE_RET_STR(EHOSTDOWN);
+#endif
+#ifdef EHOSTUNREACH
+ RT_CASE_RET_STR(EHOSTUNREACH);
+#endif
+#ifdef EALREADY
+# if !defined(ENOLCK) || (EALREADY != ENOLCK)
+ RT_CASE_RET_STR(EALREADY);
+# endif
+#endif
+#ifdef EINPROGRESS
+# if !defined(ENODEV) || (EINPROGRESS != ENODEV)
+ RT_CASE_RET_STR(EINPROGRESS);
+# endif
+#endif
+#ifdef ESTALE
+ RT_CASE_RET_STR(ESTALE); /* 116: Stale NFS file handle */
+#endif
+#ifdef EUCLEAN
+ RT_CASE_RET_STR(EUCLEAN);
+#endif
+#ifdef ENOTNAM
+ RT_CASE_RET_STR(ENOTNAM);
+#endif
+#ifdef ENAVAIL
+ RT_CASE_RET_STR(ENAVAIL);
+#endif
+#ifdef EISNAM
+ RT_CASE_RET_STR(EISNAM);
+#endif
+#ifdef EREMOTEIO
+ RT_CASE_RET_STR(EREMOTEIO);
+#endif
+#ifdef EDQUOT
+ RT_CASE_RET_STR(EDQUOT); /** @todo fix duplicate error */
+#endif
+#ifdef ENOMEDIUM
+ RT_CASE_RET_STR(ENOMEDIUM);
+#endif
+#ifdef EMEDIUMTYPE
+ RT_CASE_RET_STR(EMEDIUMTYPE);
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ RT_CASE_RET_STR(EWOULDBLOCK);
+#endif
+
+ /* Non-linux */
+
+#ifdef EPROCLIM
+ RT_CASE_RET_STR(EPROCLIM);
+#endif
+#ifdef EDOOFUS
+# if EDOOFUS != EINVAL
+ RT_CASE_RET_STR(EDOOFUS);
+# endif
+#endif
+#ifdef ENOTSUP
+# ifndef EOPNOTSUPP
+ RT_CASE_RET_STR(ENOTSUP);
+# else
+# if ENOTSUP != EOPNOTSUPP
+ RT_CASE_RET_STR(ENOTSUP);
+# endif
+# endif
+#endif
+ default:
+ AssertLogRelMsgFailedReturn(("Unhandled error code %d\n", iErrNo), "unknown-errno-value");
+ }
+}
+RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(strerror);
+