mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
263 lines
9.3 KiB
Diff
263 lines
9.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: PJ Reiniger <pj.reiniger@gmail.com>
|
|
Date: Tue, 3 May 2022 20:22:38 -0400
|
|
Subject: [PATCH 15/34] Windows support
|
|
|
|
---
|
|
.../llvm/Support/Windows/WindowsSupport.h | 56 +++++------
|
|
llvm/lib/Support/ConvertUTF.cpp | 95 +++++++++++++++++++
|
|
llvm/lib/Support/ErrorHandling.cpp | 14 +--
|
|
llvm/lib/Support/raw_ostream.cpp | 1 -
|
|
4 files changed, 129 insertions(+), 37 deletions(-)
|
|
|
|
diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
index 30644ef7f62cb81a33f2b62068f77f4e7f3f5019..994a145668d8f7b6c4569099fdb3b1c9096a6b30 100644
|
|
--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
+++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
@@ -33,8 +33,6 @@
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
-#include "llvm/Config/llvm-config.h" // Get build system configuration settings
|
|
-#include "llvm/Support/Allocator.h"
|
|
#include "llvm/Support/Chrono.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
@@ -42,18 +40,46 @@
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <system_error>
|
|
+#define WIN32_NO_STATUS
|
|
#include <windows.h>
|
|
+#undef WIN32_NO_STATUS
|
|
+#include <winternl.h>
|
|
+#include <ntstatus.h>
|
|
|
|
// Must be included after windows.h
|
|
#include <wincrypt.h>
|
|
|
|
namespace llvm {
|
|
|
|
+/// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
|
|
+/// RtlGetVersion or GetVersionEx under the hood depending on what is available.
|
|
+/// GetVersionEx is deprecated, but this API exposes the build number which can
|
|
+/// be useful for working around certain kernel bugs.
|
|
+inline llvm::VersionTuple GetWindowsOSVersion() {
|
|
+ typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
|
+ HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
|
|
+ if (hMod) {
|
|
+ auto getVer = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
|
|
+ if (getVer) {
|
|
+ RTL_OSVERSIONINFOEXW info{};
|
|
+ info.dwOSVersionInfoSize = sizeof(info);
|
|
+ if (getVer((PRTL_OSVERSIONINFOW)&info) == ((NTSTATUS)0x00000000L)) {
|
|
+ return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion, 0,
|
|
+ info.dwBuildNumber);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return llvm::VersionTuple(0, 0, 0, 0);
|
|
+}
|
|
+
|
|
/// Determines if the program is running on Windows 8 or newer. This
|
|
/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
|
|
/// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
|
|
/// yet have VersionHelpers.h, so we have our own helper.
|
|
-LLVM_ABI bool RunningWindows8OrGreater();
|
|
+inline bool RunningWindows8OrGreater() {
|
|
+ // Windows 8 is version 6.2, service pack 0.
|
|
+ return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0);
|
|
+}
|
|
|
|
/// Determines if the program is running on Windows 11 or Windows Server 2022.
|
|
LLVM_ABI bool RunningWindows11OrGreater();
|
|
@@ -229,30 +255,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) {
|
|
return Time;
|
|
}
|
|
|
|
-namespace windows {
|
|
-// Returns command line arguments. Unlike arguments given to main(),
|
|
-// this function guarantees that the returned arguments are encoded in
|
|
-// UTF-8 regardless of the current code page setting.
|
|
-LLVM_ABI std::error_code
|
|
-GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
|
|
- BumpPtrAllocator &Alloc);
|
|
-
|
|
-/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
|
|
-/// File API.
|
|
-LLVM_ABI std::error_code widenPath(const Twine &Path8,
|
|
- SmallVectorImpl<wchar_t> &Path16,
|
|
- size_t MaxPathLen = MAX_PATH);
|
|
-
|
|
-/// Retrieves the handle to a in-memory system module such as ntdll.dll, while
|
|
-/// ensuring we're not retrieving a malicious injected module but a module
|
|
-/// loaded from the system path.
|
|
-LLVM_ABI HMODULE loadSystemModuleSecure(LPCWSTR lpModuleName);
|
|
-
|
|
-/// Convert a UTF-8 path to a long form UTF-8 path expanding any short 8.3 form
|
|
-/// components.
|
|
-LLVM_ABI std::error_code makeLongFormPath(const Twine &Path8,
|
|
- llvm::SmallVectorImpl<char> &Result8);
|
|
-} // end namespace windows
|
|
} // end namespace sys
|
|
} // end namespace llvm.
|
|
|
|
diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp
|
|
index 63f92631d5b473cf9a69a06eddf4271304e8c730..f8551c7136ed44b8ed8c2f0bc4498145af504dd0 100644
|
|
--- a/llvm/lib/Support/ConvertUTF.cpp
|
|
+++ b/llvm/lib/Support/ConvertUTF.cpp
|
|
@@ -67,6 +67,11 @@
|
|
#endif
|
|
#include <assert.h>
|
|
|
|
+#ifdef _WIN32
|
|
+#include "wpi/util/WindowsError.hpp"
|
|
+#include "Windows/WindowsSupport.hpp"
|
|
+#endif
|
|
+
|
|
/*
|
|
* This code extensively uses fall-through switches.
|
|
* Keep the compiler from warning about that.
|
|
@@ -759,6 +764,96 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
|
|
|
|
--------------------------------------------------------------------- */
|
|
|
|
+#ifdef _WIN32
|
|
+
|
|
+namespace sys {
|
|
+namespace windows {
|
|
+std::error_code CodePageToUTF16(unsigned codepage,
|
|
+ std::string_view original,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ if (!original.empty()) {
|
|
+ int len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
|
|
+ original.size(), utf16.begin(), 0);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+
|
|
+ utf16.reserve(len + 1);
|
|
+ utf16.resize_for_overwrite(len);
|
|
+
|
|
+ len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
|
|
+ original.size(), utf16.begin(), utf16.size());
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Make utf16 null terminated.
|
|
+ utf16.push_back(0);
|
|
+ utf16.pop_back();
|
|
+
|
|
+ return std::error_code();
|
|
+}
|
|
+
|
|
+std::error_code UTF8ToUTF16(std::string_view utf8,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ return CodePageToUTF16(CP_UTF8, utf8, utf16);
|
|
+}
|
|
+
|
|
+std::error_code CurCPToUTF16(std::string_view curcp,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ return CodePageToUTF16(CP_ACP, curcp, utf16);
|
|
+}
|
|
+
|
|
+static
|
|
+std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
|
|
+ size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &converted) {
|
|
+ if (utf16_len) {
|
|
+ // Get length.
|
|
+ int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.begin(),
|
|
+ 0, NULL, NULL);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+
|
|
+ converted.reserve(len);
|
|
+ converted.resize_for_overwrite(len);
|
|
+
|
|
+ // Now do the actual conversion.
|
|
+ len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.data(),
|
|
+ converted.size(), NULL, NULL);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Make the new string null terminated.
|
|
+ converted.push_back(0);
|
|
+ converted.pop_back();
|
|
+
|
|
+ return std::error_code();
|
|
+}
|
|
+
|
|
+std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &utf8) {
|
|
+ return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
|
|
+}
|
|
+
|
|
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &curcp) {
|
|
+ return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
|
|
+}
|
|
+
|
|
+} // end namespace windows
|
|
+} // end namespace sys
|
|
+
|
|
+#endif // _WIN32
|
|
+
|
|
} // namespace llvm
|
|
|
|
ConvertUTF_RESTORE_WARNINGS
|
|
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
|
|
index c4366de2aec2f1730954aecfc627dd0e164481ab..cc0e4665da20b619f0cf52a25b0c71bdf78e62f6 100644
|
|
--- a/llvm/lib/Support/ErrorHandling.cpp
|
|
+++ b/llvm/lib/Support/ErrorHandling.cpp
|
|
@@ -60,7 +60,11 @@ static std::mutex BadAllocErrorHandlerMutex;
|
|
|
|
static bool write_retry(int fd, const char *buf, size_t count) {
|
|
while (count > 0) {
|
|
+#ifdef _WIN32
|
|
+ int written = sys::RetryAfterSignal(-1, ::_write, fd, buf, count);
|
|
+#else
|
|
ssize_t written = sys::RetryAfterSignal(-1, ::write, fd, buf, count);
|
|
+#endif
|
|
if (written <= 0)
|
|
return false;
|
|
buf += written;
|
|
@@ -115,15 +119,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
|
|
write_retry(2, MessageStr.data(), MessageStr.size());
|
|
}
|
|
|
|
- // If we reached here, we are failing ungracefully. Run the interrupt handlers
|
|
- // to make sure any special cleanups get done, in particular that we remove
|
|
- // files registered with RemoveFileOnSignal.
|
|
- sys::RunInterruptHandlers();
|
|
-
|
|
- if (GenCrashDiag)
|
|
- abort();
|
|
- else
|
|
- exit(1);
|
|
+ exit(1);
|
|
}
|
|
|
|
void llvm::reportFatalInternalError(const char *reason) {
|
|
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
|
|
index 459189b0f0a006d465a857f26a78968c4f234a8d..7a834a0562af1f7da4315e735fe444278a9eef0e 100644
|
|
--- a/llvm/lib/Support/raw_ostream.cpp
|
|
+++ b/llvm/lib/Support/raw_ostream.cpp
|
|
@@ -519,7 +519,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
|
|
DWORD WinLastError = GetLastError();
|
|
if (WinLastError == ERROR_BROKEN_PIPE ||
|
|
(WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
|
|
- llvm::sys::CallOneShotPipeSignalHandler();
|
|
errno = EPIPE;
|
|
}
|
|
#endif
|