diff options
Diffstat (limited to 'lib/Support/Windows')
-rw-r--r-- | lib/Support/Windows/Path.inc | 159 | ||||
-rw-r--r-- | lib/Support/Windows/Process.inc | 31 | ||||
-rw-r--r-- | lib/Support/Windows/Program.inc | 20 | ||||
-rw-r--r-- | lib/Support/Windows/Signals.inc | 51 | ||||
-rw-r--r-- | lib/Support/Windows/ThreadLocal.inc | 2 | ||||
-rw-r--r-- | lib/Support/Windows/WindowsSupport.h | 13 | ||||
-rw-r--r-- | lib/Support/Windows/explicit_symbols.inc | 6 |
7 files changed, 91 insertions, 191 deletions
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index 365031c..d8b5702 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -44,6 +44,7 @@ using namespace llvm; using llvm::sys::windows::UTF8ToUTF16; using llvm::sys::windows::UTF16ToUTF8; +using llvm::sys::path::widenPath; static std::error_code windows_error(DWORD E) { return mapWindowsError(E); @@ -59,11 +60,15 @@ static bool is_separator(const wchar_t value) { } } +namespace llvm { +namespace sys { +namespace path { + // Convert a UTF-8 path to UTF-16. Also, if the absolute equivalent of the // path is longer than CreateDirectory can tolerate, make it absolute and // prefixed by '\\?\'. -static std::error_code widenPath(const Twine &Path8, - SmallVectorImpl<wchar_t> &Path16) { +std::error_code widenPath(const Twine &Path8, + SmallVectorImpl<wchar_t> &Path16) { const size_t MaxDirLen = MAX_PATH - 12; // Must leave room for 8.3 filename. // Several operations would convert Path8 to SmallString; more efficient to @@ -111,9 +116,8 @@ static std::error_code widenPath(const Twine &Path8, // Just use the caller's original path. return UTF8ToUTF16(Path8Str, Path16); } +} // end namespace path -namespace llvm { -namespace sys { namespace fs { std::string getMainExecutable(const char *argv0, void *MainExecAddr) { @@ -268,21 +272,12 @@ std::error_code rename(const Twine &from, const Twine &to) { return ec; } -std::error_code resize_file(const Twine &path, uint64_t size) { - SmallVector<wchar_t, 128> path_utf16; - - if (std::error_code ec = widenPath(path, path_utf16)) - return ec; - - int fd = ::_wopen(path_utf16.begin(), O_BINARY | _O_RDWR, S_IWRITE); - if (fd == -1) - return std::error_code(errno, std::generic_category()); +std::error_code resize_file(int FD, uint64_t Size) { #ifdef HAVE__CHSIZE_S - errno_t error = ::_chsize_s(fd, size); + errno_t error = ::_chsize_s(FD, Size); #else - errno_t error = ::_chsize(fd, size); + errno_t error = ::_chsize(FD, Size); #endif - ::close(fd); return std::error_code(error, std::generic_category()); } @@ -463,17 +458,15 @@ std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { return std::error_code(); } -std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { - FileDescriptor = FD; +std::error_code mapped_file_region::init(int FD, uint64_t Offset, + mapmode Mode) { // Make sure that the requested size fits within SIZE_T. - if (Size > std::numeric_limits<SIZE_T>::max()) { - if (FileDescriptor) { - if (CloseFD) - _close(FileDescriptor); - } else - ::CloseHandle(FileHandle); + if (Size > std::numeric_limits<SIZE_T>::max()) return make_error_code(errc::invalid_argument); - } + + HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); + if (FileHandle == INVALID_HANDLE_VALUE) + return make_error_code(errc::bad_file_descriptor); DWORD flprotect; switch (Mode) { @@ -482,18 +475,13 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) case priv: flprotect = PAGE_WRITECOPY; break; } - FileMappingHandle = + HANDLE FileMappingHandle = ::CreateFileMappingW(FileHandle, 0, flprotect, (Offset + Size) >> 32, (Offset + Size) & 0xffffffff, 0); if (FileMappingHandle == NULL) { std::error_code ec = windows_error(GetLastError()); - if (FileDescriptor) { - if (CloseFD) - _close(FileDescriptor); - } else - ::CloseHandle(FileHandle); return ec; } @@ -511,11 +499,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) if (Mapping == NULL) { std::error_code ec = windows_error(GetLastError()); ::CloseHandle(FileMappingHandle); - if (FileDescriptor) { - if (CloseFD) - _close(FileDescriptor); - } else - ::CloseHandle(FileHandle); return ec; } @@ -526,11 +509,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) std::error_code ec = windows_error(GetLastError()); ::UnmapViewOfFile(Mapping); ::CloseHandle(FileMappingHandle); - if (FileDescriptor) { - if (CloseFD) - _close(FileDescriptor); - } else - ::CloseHandle(FileHandle); return ec; } Size = mbi.RegionSize; @@ -539,84 +517,15 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) // Close all the handles except for the view. It will keep the other handles // alive. ::CloseHandle(FileMappingHandle); - if (FileDescriptor) { - if (CloseFD) - _close(FileDescriptor); // Also closes FileHandle. - } else - ::CloseHandle(FileHandle); return std::error_code(); } -mapped_file_region::mapped_file_region(const Twine &path, - mapmode mode, - uint64_t length, - uint64_t offset, - std::error_code &ec) - : Mode(mode) - , Size(length) - , Mapping() - , FileDescriptor() - , FileHandle(INVALID_HANDLE_VALUE) - , FileMappingHandle() { - SmallVector<wchar_t, 128> path_utf16; - - // Convert path to UTF-16. - if ((ec = widenPath(path, path_utf16))) - return; - - // Get file handle for creating a file mapping. - FileHandle = ::CreateFileW(c_str(path_utf16), - Mode == readonly ? GENERIC_READ - : GENERIC_READ | GENERIC_WRITE, - Mode == readonly ? FILE_SHARE_READ - : 0, - 0, - Mode == readonly ? OPEN_EXISTING - : OPEN_ALWAYS, - Mode == readonly ? FILE_ATTRIBUTE_READONLY - : FILE_ATTRIBUTE_NORMAL, - 0); - if (FileHandle == INVALID_HANDLE_VALUE) { - ec = windows_error(::GetLastError()); - return; - } - - FileDescriptor = 0; - ec = init(FileDescriptor, true, offset); - if (ec) { - Mapping = FileMappingHandle = 0; - FileHandle = INVALID_HANDLE_VALUE; - FileDescriptor = 0; - } -} - -mapped_file_region::mapped_file_region(int fd, - bool closefd, - mapmode mode, - uint64_t length, - uint64_t offset, - std::error_code &ec) - : Mode(mode) - , Size(length) - , Mapping() - , FileDescriptor(fd) - , FileHandle(INVALID_HANDLE_VALUE) - , FileMappingHandle() { - FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); - if (FileHandle == INVALID_HANDLE_VALUE) { - if (closefd) - _close(FileDescriptor); - FileDescriptor = 0; - ec = make_error_code(errc::bad_file_descriptor); - return; - } - - ec = init(FileDescriptor, closefd, offset); - if (ec) { - Mapping = FileMappingHandle = 0; - FileHandle = INVALID_HANDLE_VALUE; - FileDescriptor = 0; - } +mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length, + uint64_t offset, std::error_code &ec) + : Size(length), Mapping() { + ec = init(fd, offset, mode); + if (ec) + Mapping = 0; } mapped_file_region::~mapped_file_region() { @@ -624,30 +533,12 @@ mapped_file_region::~mapped_file_region() { ::UnmapViewOfFile(Mapping); } -mapped_file_region::mapped_file_region(mapped_file_region &&other) - : Mode(other.Mode) - , Size(other.Size) - , Mapping(other.Mapping) - , FileDescriptor(other.FileDescriptor) - , FileHandle(other.FileHandle) - , FileMappingHandle(other.FileMappingHandle) { - other.Mapping = other.FileMappingHandle = 0; - other.FileHandle = INVALID_HANDLE_VALUE; - other.FileDescriptor = 0; -} - -mapped_file_region::mapmode mapped_file_region::flags() const { - assert(Mapping && "Mapping failed but used anyway!"); - return Mode; -} - uint64_t mapped_file_region::size() const { assert(Mapping && "Mapping failed but used anyway!"); return Size; } char *mapped_file_region::data() const { - assert(Mode != readonly && "Cannot get non-const data for readonly mapping!"); assert(Mapping && "Mapping failed but used anyway!"); return reinterpret_cast<char*>(Mapping); } diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc index 3819e63..854eac7 100644 --- a/lib/Support/Windows/Process.inc +++ b/lib/Support/Windows/Process.inc @@ -49,10 +49,6 @@ using namespace llvm; using namespace sys; -process::id_type self_process::get_id() { - return GetCurrentProcessId(); -} - static TimeValue getTimeValueFromFILETIME(FILETIME Time) { ULARGE_INTEGER TimeInteger; TimeInteger.LowPart = Time.dwLowDateTime; @@ -65,28 +61,10 @@ static TimeValue getTimeValueFromFILETIME(FILETIME Time) { (TimeInteger.QuadPart % 10000000) * 100)); } -TimeValue self_process::get_user_time() const { - FILETIME ProcCreate, ProcExit, KernelTime, UserTime; - if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime, - &UserTime) == 0) - return TimeValue(); - - return getTimeValueFromFILETIME(UserTime); -} - -TimeValue self_process::get_system_time() const { - FILETIME ProcCreate, ProcExit, KernelTime, UserTime; - if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime, - &UserTime) == 0) - return TimeValue(); - - return getTimeValueFromFILETIME(KernelTime); -} - // This function retrieves the page size using GetNativeSystemInfo() and is // present solely so it can be called once to initialize the self_process member // below. -static unsigned getPageSize() { +static unsigned computePageSize() { // GetNativeSystemInfo() provides the physical page size which may differ // from GetSystemInfo() in 32-bit applications running under WOW64. SYSTEM_INFO info; @@ -96,12 +74,11 @@ static unsigned getPageSize() { return static_cast<unsigned>(info.dwPageSize); } -// This constructor guaranteed to be run exactly once on a single thread, and -// sets up various process invariants that can be queried cheaply from then on. -self_process::self_process() : PageSize(getPageSize()) { +unsigned Process::getPageSize() { + static unsigned Ret = computePageSize(); + return Ret; } - size_t Process::GetMallocUsage() { diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index 72c2a58..c370077 100644 --- a/lib/Support/Windows/Program.inc +++ b/lib/Support/Windows/Program.inc @@ -15,8 +15,8 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/WindowsError.h" +#include "llvm/Support/raw_ostream.h" #include <cstdio> #include <fcntl.h> #include <io.h> @@ -62,7 +62,8 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name, SmallVector<StringRef, 12> PathExts; PathExts.push_back(""); PathExts.push_back(".exe"); // FIXME: This must be in %PATHEXT%. - SplitString(std::getenv("PATHEXT"), PathExts, ";"); + if (const char *PathExtEnv = std::getenv("PATHEXT")) + SplitString(PathExtEnv, PathExts, ";"); SmallVector<wchar_t, MAX_PATH> U16Result; DWORD Len = MAX_PATH; @@ -117,14 +118,19 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) { sa.bInheritHandle = TRUE; SmallVector<wchar_t, 128> fnameUnicode; - if (windows::UTF8ToUTF16(fname, fnameUnicode)) - return INVALID_HANDLE_VALUE; - + if (path->empty()) { + // Don't play long-path tricks on "NUL". + if (windows::UTF8ToUTF16(fname, fnameUnicode)) + return INVALID_HANDLE_VALUE; + } else { + if (path::widenPath(fname, fnameUnicode)) + return INVALID_HANDLE_VALUE; + } h = CreateFileW(fnameUnicode.data(), fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { - MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " + + MakeErrMsg(ErrMsg, fname + ": Can't open file for " + (fd ? "input: " : "output: ")); } @@ -322,7 +328,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, fflush(stderr); SmallVector<wchar_t, MAX_PATH> ProgramUtf16; - if (std::error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) { + if (std::error_code ec = path::widenPath(Program, ProgramUtf16)) { SetLastError(ec.value()); MakeErrMsg(ErrMsg, std::string("Unable to convert application name to UTF-16")); diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index 35ba6f8..aa1aa72 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -13,6 +13,7 @@ #include "llvm/Support/FileSystem.h" #include <algorithm> +#include <signal.h> #include <stdio.h> #include <vector> @@ -165,7 +166,6 @@ static std::vector<std::string> *FilesToRemove = NULL; static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0; static bool RegisteredUnhandledExceptionFilter = false; static bool CleanupExecuted = false; -static bool ExitOnUnhandledExceptions = false; static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; // Windows creates a new thread to execute the console handler when an event @@ -184,7 +184,8 @@ namespace llvm { /// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry, /// ignore" CRT debug report dialog. "retry" raises an exception which /// ultimately triggers our stack dumper. -static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) { +static LLVM_ATTRIBUTE_UNUSED int +AvoidMessageBoxHook(int ReportType, char *Message, int *Return) { // Set *Return to the retry code for the return value of _CrtDbgReport: // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx // This may also trigger just-in-time debugging via DebugBreak(). @@ -196,6 +197,12 @@ static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) { #endif +extern "C" void HandleAbort(int Sig) { + if (Sig == SIGABRT) { + LLVM_BUILTIN_TRAP; + } +} + static void RegisterHandler() { #if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR) // On MinGW.org, we need to load up the symbols explicitly, because the @@ -226,17 +233,6 @@ static void RegisterHandler() { OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter); SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE); - // Environment variable to disable any kind of crash dialog. - if (getenv("LLVM_DISABLE_CRASH_REPORT")) { -#ifdef _MSC_VER - _CrtSetReportHook(AvoidMessageBoxHook); -#endif - SetErrorMode(SEM_FAILCRITICALERRORS | - SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); - ExitOnUnhandledExceptions = true; - } - // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or // else multi-threading problems will ensue. } @@ -276,9 +272,29 @@ void sys::DontRemoveFileOnSignal(StringRef Filename) { LeaveCriticalSection(&CriticalSection); } +void sys::DisableSystemDialogsOnCrash() { + // Crash to stack trace handler on abort. + signal(SIGABRT, HandleAbort); + + // The following functions are not reliably accessible on MinGW. +#ifdef _MSC_VER + // We're already handling writing a "something went wrong" message. + _set_abort_behavior(0, _WRITE_ABORT_MSG); + // Disable Dr. Watson. + _set_abort_behavior(0, _CALL_REPORTFAULT); + _CrtSetReportHook(AvoidMessageBoxHook); +#endif + + // Disable standard error dialog box. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | + SEM_NOOPENFILEERRORBOX); + _set_error_mode(_OUT_TO_STDERR); +} + /// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or /// SIGSEGV) is delivered to the process, print a stack trace and then exit. void sys::PrintStackTraceOnErrorSignal() { + DisableSystemDialogsOnCrash(); RegisterHandler(); LeaveCriticalSection(&CriticalSection); } @@ -437,14 +453,7 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { fputc('\n', stderr); } - if (ExitOnUnhandledExceptions) - _exit(ep->ExceptionRecord->ExceptionCode); - - // Allow dialog box to pop up allowing choice to start debugger. - if (OldFilter) - return (*OldFilter)(ep); - else - return EXCEPTION_CONTINUE_SEARCH; + _exit(ep->ExceptionRecord->ExceptionCode); } static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { diff --git a/lib/Support/Windows/ThreadLocal.inc b/lib/Support/Windows/ThreadLocal.inc index 14ce619..b9cb8ff 100644 --- a/lib/Support/Windows/ThreadLocal.inc +++ b/lib/Support/Windows/ThreadLocal.inc @@ -34,7 +34,7 @@ ThreadLocalImpl::~ThreadLocalImpl() { TlsFree(*tls); } -const void* ThreadLocalImpl::getInstance() { +void *ThreadLocalImpl::getInstance() { DWORD* tls = reinterpret_cast<DWORD*>(&data); return TlsGetValue(*tls); } diff --git a/lib/Support/Windows/WindowsSupport.h b/lib/Support/Windows/WindowsSupport.h index 6d9c5fb..5bb0b8d 100644 --- a/lib/Support/Windows/WindowsSupport.h +++ b/lib/Support/Windows/WindowsSupport.h @@ -19,6 +19,9 @@ //=== is guaranteed to work on *all* Win32 variants. //===----------------------------------------------------------------------===// +#ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H +#define LLVM_SUPPORT_WINDOWSSUPPORT_H + // mingw-w64 tends to define it as 0x0502 in its headers. #undef _WIN32_WINNT #undef _WIN32_IE @@ -30,6 +33,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" // Get build system configuration settings #include "llvm/Support/Compiler.h" #include <system_error> @@ -88,7 +92,7 @@ public: } // True if Handle is valid. - LLVM_EXPLICIT operator bool() const { + explicit operator bool() const { return HandleTraits::IsValid(Handle) ? true : false; } @@ -162,6 +166,11 @@ c_str(SmallVectorImpl<T> &str) { } namespace sys { +namespace path { +std::error_code widenPath(const Twine &Path8, + SmallVectorImpl<wchar_t> &Path16); +} // end namespace path + namespace windows { std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16); std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, @@ -172,3 +181,5 @@ std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, } // end namespace windows } // end namespace sys } // end namespace llvm. + +#endif diff --git a/lib/Support/Windows/explicit_symbols.inc b/lib/Support/Windows/explicit_symbols.inc index cd56b13..bbbf7ea 100644 --- a/lib/Support/Windows/explicit_symbols.inc +++ b/lib/Support/Windows/explicit_symbols.inc @@ -10,9 +10,15 @@ #ifdef HAVE___CHKSTK EXPLICIT_SYMBOL(__chkstk) #endif +#ifdef HAVE___CHKSTK_MS + EXPLICIT_SYMBOL(__chkstk_ms) +#endif #ifdef HAVE____CHKSTK EXPLICIT_SYMBOL(___chkstk) #endif +#ifdef HAVE____CHKSTK_MS + EXPLICIT_SYMBOL(___chkstk_ms) +#endif #ifdef HAVE___MAIN EXPLICIT_SYMBOL(__main) // FIXME: Don't call it. #endif |