void
mono_error_set_first_argument (MonoError *oerror, const char *first_argument);
+#if HOST_WIN32
+#if HOST_X86 || HOST_AMD64
+
+#include <windows.h>
+
+// Single instruction inlinable form of GetLastError.
+//
+// Naming violation so can search disassembly for GetLastError.
+//
+#define GetLastError mono_GetLastError
+
+static inline
+unsigned long
+__stdcall
+GetLastError (void)
+{
+#if HOST_X86
+ return __readfsdword (0x34);
+#elif HOST_AMD64
+ return __readgsdword (0x68);
+#else
+#error Unreachable, see above.
+#endif
+}
+
+// Single instruction inlinable valid subset of SetLastError.
+//
+// Naming violation so can search disassembly for SetLastError.
+//
+// This is useful, for example, if you want to set a breakpoint
+// on SetLastError, but do not want to break on merely "restoring" it,
+// only "originating" it.
+//
+// A generic name is used in case there are other use-cases.
+//
+static inline
+void
+__stdcall
+mono_SetLastError (unsigned long err)
+{
+#if HOST_X86
+ __writefsdword (0x34, err);
+#elif HOST_AMD64
+ __writegsdword (0x68, err);
+#else
+#error Unreachable, see above.
+#endif
+}
+
+#else // arm, arm64, etc.
+
+#define mono_SetLastError SetLastError
+
+#endif // processor
+#endif // win32
+
#endif
#include <mono/utils/mono-coop-semaphore.h>
#include <mono/utils/os-event.h>
#include <mono/utils/refcount.h>
+#include <mono/utils/mono-error-internals.h>
#include <glib.h>
#include <config.h>
mono_win32_abort_blocking_io_call (THREAD_INFO_TYPE *info);
#define W32_DEFINE_LAST_ERROR_RESTORE_POINT \
- DWORD _last_error_restore_point = GetLastError ();
+ const DWORD _last_error_restore_point = GetLastError ();
#define W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT \
/* Only restore if changed to prevent unecessary writes. */ \
if (GetLastError () != _last_error_restore_point) \
- SetLastError (_last_error_restore_point);
+ mono_SetLastError (_last_error_restore_point);
#else