aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support/Windows
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support/Windows')
-rw-r--r--lib/Support/Windows/Path.inc159
-rw-r--r--lib/Support/Windows/Process.inc31
-rw-r--r--lib/Support/Windows/Program.inc20
-rw-r--r--lib/Support/Windows/Signals.inc51
-rw-r--r--lib/Support/Windows/ThreadLocal.inc2
-rw-r--r--lib/Support/Windows/WindowsSupport.h13
-rw-r--r--lib/Support/Windows/explicit_symbols.inc6
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