You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
37
external/llvm/lib/Support/Windows/COM.inc
vendored
37
external/llvm/lib/Support/Windows/COM.inc
vendored
@ -1,37 +0,0 @@
|
||||
//==- llvm/Support/Windows/COM.inc - Windows COM Implementation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Windows portion of COM support.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only Windows code.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
InitializeCOMRAII::InitializeCOMRAII(COMThreadingMode Threading,
|
||||
bool SpeedOverMemory) {
|
||||
DWORD Coinit = 0;
|
||||
if (Threading == COMThreadingMode::SingleThreaded)
|
||||
Coinit |= COINIT_APARTMENTTHREADED;
|
||||
else
|
||||
Coinit |= COINIT_MULTITHREADED;
|
||||
if (SpeedOverMemory)
|
||||
Coinit |= COINIT_SPEED_OVER_MEMORY;
|
||||
::CoInitializeEx(nullptr, Coinit);
|
||||
}
|
||||
|
||||
InitializeCOMRAII::~InitializeCOMRAII() { ::CoUninitialize(); }
|
||||
}
|
||||
}
|
202
external/llvm/lib/Support/Windows/DynamicLibrary.inc
vendored
202
external/llvm/lib/Support/Windows/DynamicLibrary.inc
vendored
@ -1,202 +0,0 @@
|
||||
//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the Win32 specific implementation of DynamicLibrary.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <psapi.h>
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only Win32 specific code
|
||||
//=== and must not be UNIX code.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
DynamicLibrary::HandleSet::~HandleSet() {
|
||||
for (void *Handle : llvm::reverse(Handles))
|
||||
FreeLibrary(HMODULE(Handle));
|
||||
|
||||
// 'Process' should not be released on Windows.
|
||||
assert((!Process || Process==this) && "Bad Handle");
|
||||
// llvm_shutdown called, Return to default
|
||||
DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
|
||||
}
|
||||
|
||||
void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
|
||||
// Create the instance and return it to be the *Process* handle
|
||||
// simillar to dlopen(NULL, RTLD_LAZY|RTLD_GLOBAL)
|
||||
if (!File)
|
||||
return &(*OpenedHandles);
|
||||
|
||||
SmallVector<wchar_t, MAX_PATH> FileUnicode;
|
||||
if (std::error_code ec = windows::UTF8ToUTF16(File, FileUnicode)) {
|
||||
SetLastError(ec.value());
|
||||
MakeErrMsg(Err, std::string(File) + ": Can't convert to UTF-16");
|
||||
return &DynamicLibrary::Invalid;
|
||||
}
|
||||
|
||||
HMODULE Handle = LoadLibraryW(FileUnicode.data());
|
||||
if (Handle == NULL) {
|
||||
MakeErrMsg(Err, std::string(File) + ": Can't open");
|
||||
return &DynamicLibrary::Invalid;
|
||||
}
|
||||
|
||||
return reinterpret_cast<void*>(Handle);
|
||||
}
|
||||
|
||||
static DynamicLibrary::HandleSet *IsOpenedHandlesInstance(void *Handle) {
|
||||
if (!OpenedHandles.isConstructed())
|
||||
return nullptr;
|
||||
DynamicLibrary::HandleSet &Inst = *OpenedHandles;
|
||||
return Handle == &Inst ? &Inst : nullptr;
|
||||
}
|
||||
|
||||
void DynamicLibrary::HandleSet::DLClose(void *Handle) {
|
||||
if (HandleSet* HS = IsOpenedHandlesInstance(Handle))
|
||||
HS->Process = nullptr; // Just drop the *Process* handle.
|
||||
else
|
||||
FreeLibrary((HMODULE)Handle);
|
||||
}
|
||||
|
||||
static bool GetProcessModules(HANDLE H, DWORD &Bytes, HMODULE *Data = nullptr) {
|
||||
// EnumProcessModules will fail on Windows 64 while some versions of
|
||||
// MingW-32 don't have EnumProcessModulesEx.
|
||||
if (
|
||||
#ifdef _WIN64
|
||||
!EnumProcessModulesEx(H, Data, Bytes, &Bytes, LIST_MODULES_64BIT)
|
||||
#else
|
||||
!EnumProcessModules(H, Data, Bytes, &Bytes)
|
||||
#endif
|
||||
) {
|
||||
std::string Err;
|
||||
if (MakeErrMsg(&Err, "EnumProcessModules failure"))
|
||||
llvm::errs() << Err << "\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
|
||||
HandleSet* HS = IsOpenedHandlesInstance(Handle);
|
||||
if (!HS)
|
||||
return (void *)uintptr_t(GetProcAddress((HMODULE)Handle, Symbol));
|
||||
|
||||
// Could have done a dlclose on the *Process* handle
|
||||
if (!HS->Process)
|
||||
return nullptr;
|
||||
|
||||
// Trials indicate EnumProcessModulesEx is consistantly faster than using
|
||||
// EnumerateLoadedModules64 or CreateToolhelp32Snapshot.
|
||||
//
|
||||
// | Handles | DbgHelp.dll | CreateSnapshot | EnumProcessModulesEx
|
||||
// |=========|=============|========================================
|
||||
// | 37 | 0.0000585 * | 0.0003031 | 0.0000152
|
||||
// | 1020 | 0.0026310 * | 0.0121598 | 0.0002683
|
||||
// | 2084 | 0.0149418 * | 0.0369936 | 0.0005610
|
||||
//
|
||||
// * Not including the load time of Dbghelp.dll (~.005 sec)
|
||||
//
|
||||
// There's still a case to somehow cache the result of EnumProcessModulesEx
|
||||
// across invocations, but the complication of doing that properly...
|
||||
// Possibly using LdrRegisterDllNotification to invalidate the cache?
|
||||
|
||||
DWORD Bytes = 0;
|
||||
HMODULE Self = HMODULE(GetCurrentProcess());
|
||||
if (!GetProcessModules(Self, Bytes))
|
||||
return nullptr;
|
||||
|
||||
// Get the most recent list in case any modules added/removed between calls
|
||||
// to EnumProcessModulesEx that gets the amount of, then copies the HMODULES.
|
||||
// MSDN is pretty clear that if the module list changes during the call to
|
||||
// EnumProcessModulesEx the results should not be used.
|
||||
std::vector<HMODULE> Handles;
|
||||
do {
|
||||
assert(Bytes && ((Bytes % sizeof(HMODULE)) == 0) &&
|
||||
"Should have at least one module and be aligned");
|
||||
Handles.resize(Bytes / sizeof(HMODULE));
|
||||
if (!GetProcessModules(Self, Bytes, Handles.data()))
|
||||
return nullptr;
|
||||
} while (Bytes != (Handles.size() * sizeof(HMODULE)));
|
||||
|
||||
// Try EXE first, mirroring what dlsym(dlopen(NULL)) does.
|
||||
if (FARPROC Ptr = GetProcAddress(HMODULE(Handles.front()), Symbol))
|
||||
return (void *) uintptr_t(Ptr);
|
||||
|
||||
if (Handles.size() > 1) {
|
||||
// This is different behaviour than what Posix dlsym(dlopen(NULL)) does.
|
||||
// Doing that here is causing real problems for the JIT where msvc.dll
|
||||
// and ucrt.dll can define the same symbols. The runtime linker will choose
|
||||
// symbols from ucrt.dll first, but iterating NOT in reverse here would
|
||||
// mean that the msvc.dll versions would be returned.
|
||||
|
||||
for (auto I = Handles.rbegin(), E = Handles.rend()-1; I != E; ++I) {
|
||||
if (FARPROC Ptr = GetProcAddress(HMODULE(*I), Symbol))
|
||||
return (void *) uintptr_t(Ptr);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Stack probing routines are in the support library (e.g. libgcc), but we don't
|
||||
// have dynamic linking on windows. Provide a hook.
|
||||
#define EXPLICIT_SYMBOL(SYM) \
|
||||
extern "C" { extern void *SYM; }
|
||||
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
|
||||
|
||||
#ifdef _M_IX86
|
||||
// Win32 on x86 implements certain single-precision math functions as macros.
|
||||
// These functions are not exported by the DLL, but will still be needed
|
||||
// for symbol-resolution by the JIT loader. Therefore, this Support libray
|
||||
// provides helper functions with the same implementation.
|
||||
|
||||
#define INLINE_DEF_SYMBOL1(TYP, SYM) \
|
||||
extern "C" TYP inline_##SYM(TYP _X) { return SYM(_X); }
|
||||
#define INLINE_DEF_SYMBOL2(TYP, SYM) \
|
||||
extern "C" TYP inline_##SYM(TYP _X, TYP _Y) { return SYM(_X, _Y); }
|
||||
#endif
|
||||
|
||||
#include "explicit_symbols.inc"
|
||||
|
||||
#undef EXPLICIT_SYMBOL
|
||||
#undef EXPLICIT_SYMBOL2
|
||||
#undef INLINE_DEF_SYMBOL1
|
||||
#undef INLINE_DEF_SYMBOL2
|
||||
|
||||
static void *DoSearch(const char *SymbolName) {
|
||||
|
||||
#define EXPLICIT_SYMBOL(SYM) \
|
||||
if (!strcmp(SymbolName, #SYM)) \
|
||||
return (void *)&SYM;
|
||||
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
|
||||
if (!strcmp(SymbolName, #SYMFROM)) \
|
||||
return (void *)&SYMTO;
|
||||
|
||||
#ifdef _M_IX86
|
||||
#define INLINE_DEF_SYMBOL1(TYP, SYM) \
|
||||
if (!strcmp(SymbolName, #SYM)) \
|
||||
return (void *)&inline_##SYM;
|
||||
#define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
|
||||
#endif
|
||||
|
||||
{
|
||||
#include "explicit_symbols.inc"
|
||||
}
|
||||
|
||||
#undef EXPLICIT_SYMBOL
|
||||
#undef EXPLICIT_SYMBOL2
|
||||
#undef INLINE_DEF_SYMBOL1
|
||||
#undef INLINE_DEF_SYMBOL2
|
||||
|
||||
return nullptr;
|
||||
}
|
34
external/llvm/lib/Support/Windows/Host.inc
vendored
34
external/llvm/lib/Support/Windows/Host.inc
vendored
@ -1,34 +0,0 @@
|
||||
//===- llvm/Support/Win32/Host.inc ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Win32 Host support.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static std::string updateTripleOSVersion(std::string Triple) {
|
||||
return Triple;
|
||||
}
|
||||
|
||||
std::string sys::getDefaultTargetTriple() {
|
||||
const char *Triple = LLVM_DEFAULT_TARGET_TRIPLE;
|
||||
|
||||
// Override the default target with an environment variable named by LLVM_TARGET_TRIPLE_ENV.
|
||||
#if defined(LLVM_TARGET_TRIPLE_ENV)
|
||||
if (const char *EnvTriple = std::getenv(LLVM_TARGET_TRIPLE_ENV))
|
||||
Triple = EnvTriple;
|
||||
#endif
|
||||
|
||||
return Triple::normalize(Triple);
|
||||
}
|
164
external/llvm/lib/Support/Windows/Memory.inc
vendored
164
external/llvm/lib/Support/Windows/Memory.inc
vendored
@ -1,164 +0,0 @@
|
||||
//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the Win32 specific implementation of various Memory
|
||||
// management utilities
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/WindowsError.h"
|
||||
|
||||
// The Windows.h header must be the last one included.
|
||||
#include "WindowsSupport.h"
|
||||
|
||||
namespace {
|
||||
|
||||
DWORD getWindowsProtectionFlags(unsigned Flags) {
|
||||
switch (Flags) {
|
||||
// Contrary to what you might expect, the Windows page protection flags
|
||||
// are not a bitwise combination of RWX values
|
||||
case llvm::sys::Memory::MF_READ:
|
||||
return PAGE_READONLY;
|
||||
case llvm::sys::Memory::MF_WRITE:
|
||||
// Note: PAGE_WRITE is not supported by VirtualProtect
|
||||
return PAGE_READWRITE;
|
||||
case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
|
||||
return PAGE_READWRITE;
|
||||
case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
|
||||
return PAGE_EXECUTE_READ;
|
||||
case llvm::sys::Memory::MF_READ |
|
||||
llvm::sys::Memory::MF_WRITE |
|
||||
llvm::sys::Memory::MF_EXEC:
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
case llvm::sys::Memory::MF_EXEC:
|
||||
return PAGE_EXECUTE;
|
||||
default:
|
||||
llvm_unreachable("Illegal memory protection flag specified!");
|
||||
}
|
||||
// Provide a default return value as required by some compilers.
|
||||
return PAGE_NOACCESS;
|
||||
}
|
||||
|
||||
size_t getAllocationGranularity() {
|
||||
SYSTEM_INFO Info;
|
||||
::GetSystemInfo(&Info);
|
||||
if (Info.dwPageSize > Info.dwAllocationGranularity)
|
||||
return Info.dwPageSize;
|
||||
else
|
||||
return Info.dwAllocationGranularity;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only Win32 specific code
|
||||
//=== and must not be UNIX code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
|
||||
const MemoryBlock *const NearBlock,
|
||||
unsigned Flags,
|
||||
std::error_code &EC) {
|
||||
EC = std::error_code();
|
||||
if (NumBytes == 0)
|
||||
return MemoryBlock();
|
||||
|
||||
// While we'd be happy to allocate single pages, the Windows allocation
|
||||
// granularity may be larger than a single page (in practice, it is 64K)
|
||||
// so mapping less than that will create an unreachable fragment of memory.
|
||||
// Avoid using one-time initialization of static locals here, since they
|
||||
// aren't thread safe with MSVC.
|
||||
static volatile size_t GranularityCached;
|
||||
size_t Granularity = GranularityCached;
|
||||
if (Granularity == 0) {
|
||||
Granularity = getAllocationGranularity();
|
||||
GranularityCached = Granularity;
|
||||
}
|
||||
|
||||
const size_t NumBlocks = (NumBytes+Granularity-1)/Granularity;
|
||||
|
||||
uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
|
||||
NearBlock->size()
|
||||
: 0;
|
||||
|
||||
// If the requested address is not aligned to the allocation granularity,
|
||||
// round up to get beyond NearBlock. VirtualAlloc would have rounded down.
|
||||
if (Start && Start % Granularity != 0)
|
||||
Start += Granularity - Start % Granularity;
|
||||
|
||||
DWORD Protect = getWindowsProtectionFlags(Flags);
|
||||
|
||||
void *PA = ::VirtualAlloc(reinterpret_cast<void*>(Start),
|
||||
NumBlocks*Granularity,
|
||||
MEM_RESERVE | MEM_COMMIT, Protect);
|
||||
if (PA == NULL) {
|
||||
if (NearBlock) {
|
||||
// Try again without the NearBlock hint
|
||||
return allocateMappedMemory(NumBytes, NULL, Flags, EC);
|
||||
}
|
||||
EC = mapWindowsError(::GetLastError());
|
||||
return MemoryBlock();
|
||||
}
|
||||
|
||||
MemoryBlock Result;
|
||||
Result.Address = PA;
|
||||
Result.Size = NumBlocks*Granularity;
|
||||
|
||||
if (Flags & MF_EXEC)
|
||||
Memory::InvalidateInstructionCache(Result.Address, Result.Size);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::error_code Memory::releaseMappedMemory(MemoryBlock &M) {
|
||||
if (M.Address == 0 || M.Size == 0)
|
||||
return std::error_code();
|
||||
|
||||
if (!VirtualFree(M.Address, 0, MEM_RELEASE))
|
||||
return mapWindowsError(::GetLastError());
|
||||
|
||||
M.Address = 0;
|
||||
M.Size = 0;
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
|
||||
unsigned Flags) {
|
||||
if (M.Address == 0 || M.Size == 0)
|
||||
return std::error_code();
|
||||
|
||||
DWORD Protect = getWindowsProtectionFlags(Flags);
|
||||
|
||||
DWORD OldFlags;
|
||||
if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags))
|
||||
return mapWindowsError(::GetLastError());
|
||||
|
||||
if (Flags & MF_EXEC)
|
||||
Memory::InvalidateInstructionCache(M.Address, M.Size);
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
/// InvalidateInstructionCache - Before the JIT can run a block of code
|
||||
/// that has been emitted it must invalidate the instruction cache on some
|
||||
/// platforms.
|
||||
void Memory::InvalidateInstructionCache(
|
||||
const void *Addr, size_t Len) {
|
||||
FlushInstructionCache(GetCurrentProcess(), Addr, Len);
|
||||
}
|
||||
|
||||
} // namespace sys
|
||||
} // namespace llvm
|
57
external/llvm/lib/Support/Windows/Mutex.inc
vendored
57
external/llvm/lib/Support/Windows/Mutex.inc
vendored
@ -1,57 +0,0 @@
|
||||
//===- llvm/Support/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Win32 specific (non-pthread) Mutex class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only generic Win32 code that
|
||||
//=== is guaranteed to work on *all* Win32 variants.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
sys::MutexImpl::MutexImpl(bool /*recursive*/)
|
||||
{
|
||||
data_ = new CRITICAL_SECTION;
|
||||
InitializeCriticalSection((LPCRITICAL_SECTION)data_);
|
||||
}
|
||||
|
||||
sys::MutexImpl::~MutexImpl()
|
||||
{
|
||||
DeleteCriticalSection((LPCRITICAL_SECTION)data_);
|
||||
delete (LPCRITICAL_SECTION)data_;
|
||||
data_ = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
sys::MutexImpl::acquire()
|
||||
{
|
||||
EnterCriticalSection((LPCRITICAL_SECTION)data_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
sys::MutexImpl::release()
|
||||
{
|
||||
LeaveCriticalSection((LPCRITICAL_SECTION)data_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
sys::MutexImpl::tryacquire()
|
||||
{
|
||||
return TryEnterCriticalSection((LPCRITICAL_SECTION)data_);
|
||||
}
|
||||
|
||||
}
|
1350
external/llvm/lib/Support/Windows/Path.inc
vendored
1350
external/llvm/lib/Support/Windows/Path.inc
vendored
File diff suppressed because it is too large
Load Diff
461
external/llvm/lib/Support/Windows/Process.inc
vendored
461
external/llvm/lib/Support/Windows/Process.inc
vendored
@ -1,461 +0,0 @@
|
||||
//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the Win32 specific implementation of the Process class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/WindowsError.h"
|
||||
#include <malloc.h>
|
||||
|
||||
// The Windows.h header must be after LLVM and standard headers.
|
||||
#include "WindowsSupport.h"
|
||||
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <psapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#if (HAVE_LIBPSAPI != 1)
|
||||
#error "libpsapi.a should be present"
|
||||
#endif
|
||||
#if (HAVE_LIBSHELL32 != 1)
|
||||
#error "libshell32.a should be present"
|
||||
#endif
|
||||
#else
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
#pragma comment(lib, "shell32.lib")
|
||||
#endif
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only Win32 specific code
|
||||
//=== and must not be UNIX code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef __MINGW32__
|
||||
// This ban should be lifted when MinGW 1.0+ has defined this value.
|
||||
# define _HEAPOK (-2)
|
||||
#endif
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// 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 computePageSize() {
|
||||
// GetNativeSystemInfo() provides the physical page size which may differ
|
||||
// from GetSystemInfo() in 32-bit applications running under WOW64.
|
||||
SYSTEM_INFO info;
|
||||
GetNativeSystemInfo(&info);
|
||||
// FIXME: FileOffset in MapViewOfFile() should be aligned to not dwPageSize,
|
||||
// but dwAllocationGranularity.
|
||||
return static_cast<unsigned>(info.dwPageSize);
|
||||
}
|
||||
|
||||
unsigned Process::getPageSize() {
|
||||
static unsigned Ret = computePageSize();
|
||||
return Ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
Process::GetMallocUsage()
|
||||
{
|
||||
_HEAPINFO hinfo;
|
||||
hinfo._pentry = NULL;
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
while (_heapwalk(&hinfo) == _HEAPOK)
|
||||
size += hinfo._size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
|
||||
std::chrono::nanoseconds &sys_time) {
|
||||
elapsed = std::chrono::system_clock::now();;
|
||||
|
||||
FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
|
||||
if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
|
||||
&UserTime) == 0)
|
||||
return;
|
||||
|
||||
user_time = toDuration(UserTime);
|
||||
sys_time = toDuration(KernelTime);
|
||||
}
|
||||
|
||||
// Some LLVM programs such as bugpoint produce core files as a normal part of
|
||||
// their operation. To prevent the disk from filling up, this configuration
|
||||
// item does what's necessary to prevent their generation.
|
||||
void Process::PreventCoreFiles() {
|
||||
// Windows does have the concept of core files, called minidumps. However,
|
||||
// disabling minidumps for a particular application extends past the lifetime
|
||||
// of that application, which is the incorrect behavior for this API.
|
||||
// Additionally, the APIs require elevated privileges to disable and re-
|
||||
// enable minidumps, which makes this untenable. For more information, see
|
||||
// WerAddExcludedApplication and WerRemoveExcludedApplication (Vista and
|
||||
// later).
|
||||
//
|
||||
// Windows also has modal pop-up message boxes. As this method is used by
|
||||
// bugpoint, preventing these pop-ups is additionally important.
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS |
|
||||
SEM_NOGPFAULTERRORBOX |
|
||||
SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
coreFilesPrevented = true;
|
||||
}
|
||||
|
||||
/// Returns the environment variable \arg Name's value as a string encoded in
|
||||
/// UTF-8. \arg Name is assumed to be in UTF-8 encoding.
|
||||
Optional<std::string> Process::GetEnv(StringRef Name) {
|
||||
// Convert the argument to UTF-16 to pass it to _wgetenv().
|
||||
SmallVector<wchar_t, 128> NameUTF16;
|
||||
if (windows::UTF8ToUTF16(Name, NameUTF16))
|
||||
return None;
|
||||
|
||||
// Environment variable can be encoded in non-UTF8 encoding, and there's no
|
||||
// way to know what the encoding is. The only reliable way to look up
|
||||
// multibyte environment variable is to use GetEnvironmentVariableW().
|
||||
SmallVector<wchar_t, MAX_PATH> Buf;
|
||||
size_t Size = MAX_PATH;
|
||||
do {
|
||||
Buf.reserve(Size);
|
||||
SetLastError(NO_ERROR);
|
||||
Size =
|
||||
GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
|
||||
if (Size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
return None;
|
||||
|
||||
// Try again with larger buffer.
|
||||
} while (Size > Buf.capacity());
|
||||
Buf.set_size(Size);
|
||||
|
||||
// Convert the result from UTF-16 to UTF-8.
|
||||
SmallVector<char, MAX_PATH> Res;
|
||||
if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
|
||||
return None;
|
||||
return std::string(Res.data());
|
||||
}
|
||||
|
||||
static void AllocateAndPush(const SmallVectorImpl<char> &S,
|
||||
SmallVectorImpl<const char *> &Vector,
|
||||
SpecificBumpPtrAllocator<char> &Allocator) {
|
||||
char *Buffer = Allocator.Allocate(S.size() + 1);
|
||||
::memcpy(Buffer, S.data(), S.size());
|
||||
Buffer[S.size()] = '\0';
|
||||
Vector.push_back(Buffer);
|
||||
}
|
||||
|
||||
/// Convert Arg from UTF-16 to UTF-8 and push it onto Args.
|
||||
static std::error_code
|
||||
ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
||||
SpecificBumpPtrAllocator<char> &Allocator) {
|
||||
SmallVector<char, MAX_PATH> ArgString;
|
||||
if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString))
|
||||
return ec;
|
||||
AllocateAndPush(ArgString, Args, Allocator);
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
/// \brief Perform wildcard expansion of Arg, or just push it into Args if it
|
||||
/// doesn't have wildcards or doesn't match any files.
|
||||
static std::error_code
|
||||
WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
||||
SpecificBumpPtrAllocator<char> &Allocator) {
|
||||
if (!wcspbrk(Arg, L"*?")) {
|
||||
// Arg does not contain any wildcard characters. This is the common case.
|
||||
return ConvertAndPushArg(Arg, Args, Allocator);
|
||||
}
|
||||
|
||||
if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) {
|
||||
// Don't wildcard expand /?. Always treat it as an option.
|
||||
return ConvertAndPushArg(Arg, Args, Allocator);
|
||||
}
|
||||
|
||||
// Extract any directory part of the argument.
|
||||
SmallVector<char, MAX_PATH> Dir;
|
||||
if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), Dir))
|
||||
return ec;
|
||||
sys::path::remove_filename(Dir);
|
||||
const int DirSize = Dir.size();
|
||||
|
||||
// Search for matching files.
|
||||
// FIXME: This assumes the wildcard is only in the file name and not in the
|
||||
// directory portion of the file path. For example, it doesn't handle
|
||||
// "*\foo.c" nor "s?c\bar.cpp".
|
||||
WIN32_FIND_DATAW FileData;
|
||||
HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
|
||||
if (FindHandle == INVALID_HANDLE_VALUE) {
|
||||
return ConvertAndPushArg(Arg, Args, Allocator);
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
do {
|
||||
SmallVector<char, MAX_PATH> FileName;
|
||||
ec = windows::UTF16ToUTF8(FileData.cFileName, wcslen(FileData.cFileName),
|
||||
FileName);
|
||||
if (ec)
|
||||
break;
|
||||
|
||||
// Append FileName to Dir, and remove it afterwards.
|
||||
llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
|
||||
AllocateAndPush(Dir, Args, Allocator);
|
||||
Dir.resize(DirSize);
|
||||
} while (FindNextFileW(FindHandle, &FileData));
|
||||
|
||||
FindClose(FindHandle);
|
||||
return ec;
|
||||
}
|
||||
|
||||
static std::error_code
|
||||
ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
||||
SpecificBumpPtrAllocator<char> &Allocator) {
|
||||
SmallVector<wchar_t, MAX_PATH> LongPath;
|
||||
DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
|
||||
if (Length == 0)
|
||||
return mapWindowsError(GetLastError());
|
||||
if (Length > LongPath.capacity()) {
|
||||
// We're not going to try to deal with paths longer than MAX_PATH, so we'll
|
||||
// treat this as an error. GetLastError() returns ERROR_SUCCESS, which
|
||||
// isn't useful, so we'll hardcode an appropriate error value.
|
||||
return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
LongPath.set_size(Length);
|
||||
return ConvertAndPushArg(LongPath.data(), Args, Allocator);
|
||||
}
|
||||
|
||||
std::error_code
|
||||
Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
|
||||
ArrayRef<const char *>,
|
||||
SpecificBumpPtrAllocator<char> &ArgAllocator) {
|
||||
int ArgCount;
|
||||
wchar_t **UnicodeCommandLine =
|
||||
CommandLineToArgvW(GetCommandLineW(), &ArgCount);
|
||||
if (!UnicodeCommandLine)
|
||||
return mapWindowsError(::GetLastError());
|
||||
|
||||
Args.reserve(ArgCount);
|
||||
std::error_code ec;
|
||||
|
||||
// The first argument may contain just the name of the executable (e.g.,
|
||||
// "clang") rather than the full path, so swap it with the full path.
|
||||
wchar_t ModuleName[MAX_PATH];
|
||||
int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
|
||||
if (0 < Length && Length < MAX_PATH)
|
||||
UnicodeCommandLine[0] = ModuleName;
|
||||
|
||||
// If the first argument is a shortened (8.3) name (which is possible even
|
||||
// if we got the module name), the driver will have trouble distinguishing it
|
||||
// (e.g., clang.exe v. clang++.exe), so expand it now.
|
||||
ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator);
|
||||
|
||||
for (int i = 1; i < ArgCount && !ec; ++i) {
|
||||
ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
|
||||
if (ec)
|
||||
break;
|
||||
}
|
||||
|
||||
LocalFree(UnicodeCommandLine);
|
||||
return ec;
|
||||
}
|
||||
|
||||
std::error_code Process::FixupStandardFileDescriptors() {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code Process::SafelyCloseFileDescriptor(int FD) {
|
||||
if (::close(FD) < 0)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
bool Process::StandardInIsUserInput() {
|
||||
return FileDescriptorIsDisplayed(0);
|
||||
}
|
||||
|
||||
bool Process::StandardOutIsDisplayed() {
|
||||
return FileDescriptorIsDisplayed(1);
|
||||
}
|
||||
|
||||
bool Process::StandardErrIsDisplayed() {
|
||||
return FileDescriptorIsDisplayed(2);
|
||||
}
|
||||
|
||||
bool Process::FileDescriptorIsDisplayed(int fd) {
|
||||
DWORD Mode; // Unused
|
||||
return (GetConsoleMode((HANDLE)_get_osfhandle(fd), &Mode) != 0);
|
||||
}
|
||||
|
||||
unsigned Process::StandardOutColumns() {
|
||||
unsigned Columns = 0;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
|
||||
Columns = csbi.dwSize.X;
|
||||
return Columns;
|
||||
}
|
||||
|
||||
unsigned Process::StandardErrColumns() {
|
||||
unsigned Columns = 0;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi))
|
||||
Columns = csbi.dwSize.X;
|
||||
return Columns;
|
||||
}
|
||||
|
||||
// The terminal always has colors.
|
||||
bool Process::FileDescriptorHasColors(int fd) {
|
||||
return FileDescriptorIsDisplayed(fd);
|
||||
}
|
||||
|
||||
bool Process::StandardOutHasColors() {
|
||||
return FileDescriptorHasColors(1);
|
||||
}
|
||||
|
||||
bool Process::StandardErrHasColors() {
|
||||
return FileDescriptorHasColors(2);
|
||||
}
|
||||
|
||||
static bool UseANSI = false;
|
||||
void Process::UseANSIEscapeCodes(bool enable) {
|
||||
UseANSI = enable;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DefaultColors
|
||||
{
|
||||
private:
|
||||
WORD defaultColor;
|
||||
public:
|
||||
DefaultColors()
|
||||
:defaultColor(GetCurrentColor()) {}
|
||||
static unsigned GetCurrentColor() {
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
|
||||
return csbi.wAttributes;
|
||||
return 0;
|
||||
}
|
||||
WORD operator()() const { return defaultColor; }
|
||||
};
|
||||
|
||||
DefaultColors defaultColors;
|
||||
|
||||
WORD fg_color(WORD color) {
|
||||
return color & (FOREGROUND_BLUE | FOREGROUND_GREEN |
|
||||
FOREGROUND_INTENSITY | FOREGROUND_RED);
|
||||
}
|
||||
|
||||
WORD bg_color(WORD color) {
|
||||
return color & (BACKGROUND_BLUE | BACKGROUND_GREEN |
|
||||
BACKGROUND_INTENSITY | BACKGROUND_RED);
|
||||
}
|
||||
}
|
||||
|
||||
bool Process::ColorNeedsFlush() {
|
||||
return !UseANSI;
|
||||
}
|
||||
|
||||
const char *Process::OutputBold(bool bg) {
|
||||
if (UseANSI) return "\033[1m";
|
||||
|
||||
WORD colors = DefaultColors::GetCurrentColor();
|
||||
if (bg)
|
||||
colors |= BACKGROUND_INTENSITY;
|
||||
else
|
||||
colors |= FOREGROUND_INTENSITY;
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *Process::OutputColor(char code, bool bold, bool bg) {
|
||||
if (UseANSI) return colorcodes[bg?1:0][bold?1:0][code&7];
|
||||
|
||||
WORD current = DefaultColors::GetCurrentColor();
|
||||
WORD colors;
|
||||
if (bg) {
|
||||
colors = ((code&1) ? BACKGROUND_RED : 0) |
|
||||
((code&2) ? BACKGROUND_GREEN : 0 ) |
|
||||
((code&4) ? BACKGROUND_BLUE : 0);
|
||||
if (bold)
|
||||
colors |= BACKGROUND_INTENSITY;
|
||||
colors |= fg_color(current);
|
||||
} else {
|
||||
colors = ((code&1) ? FOREGROUND_RED : 0) |
|
||||
((code&2) ? FOREGROUND_GREEN : 0 ) |
|
||||
((code&4) ? FOREGROUND_BLUE : 0);
|
||||
if (bold)
|
||||
colors |= FOREGROUND_INTENSITY;
|
||||
colors |= bg_color(current);
|
||||
}
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WORD GetConsoleTextAttribute(HANDLE hConsoleOutput) {
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
|
||||
return info.wAttributes;
|
||||
}
|
||||
|
||||
const char *Process::OutputReverse() {
|
||||
if (UseANSI) return "\033[7m";
|
||||
|
||||
const WORD attributes
|
||||
= GetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
|
||||
const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
|
||||
FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
|
||||
BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||
const WORD color_mask = foreground_mask | background_mask;
|
||||
|
||||
WORD new_attributes =
|
||||
((attributes & FOREGROUND_BLUE )?BACKGROUND_BLUE :0) |
|
||||
((attributes & FOREGROUND_GREEN )?BACKGROUND_GREEN :0) |
|
||||
((attributes & FOREGROUND_RED )?BACKGROUND_RED :0) |
|
||||
((attributes & FOREGROUND_INTENSITY)?BACKGROUND_INTENSITY:0) |
|
||||
((attributes & BACKGROUND_BLUE )?FOREGROUND_BLUE :0) |
|
||||
((attributes & BACKGROUND_GREEN )?FOREGROUND_GREEN :0) |
|
||||
((attributes & BACKGROUND_RED )?FOREGROUND_RED :0) |
|
||||
((attributes & BACKGROUND_INTENSITY)?FOREGROUND_INTENSITY:0) |
|
||||
0;
|
||||
new_attributes = (attributes & ~color_mask) | (new_attributes & color_mask);
|
||||
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), new_attributes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *Process::ResetColor() {
|
||||
if (UseANSI) return "\033[0m";
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Include GetLastError() in a fatal error message.
|
||||
static void ReportLastErrorFatal(const char *Msg) {
|
||||
std::string ErrMsg;
|
||||
MakeErrMsg(&ErrMsg, Msg);
|
||||
report_fatal_error(ErrMsg);
|
||||
}
|
||||
|
||||
unsigned Process::GetRandomNumber() {
|
||||
HCRYPTPROV HCPC;
|
||||
if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
ReportLastErrorFatal("Could not acquire a cryptographic context");
|
||||
|
||||
ScopedCryptContext CryptoProvider(HCPC);
|
||||
unsigned Ret;
|
||||
if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
|
||||
reinterpret_cast<BYTE *>(&Ret)))
|
||||
ReportLastErrorFatal("Could not generate a random number");
|
||||
return Ret;
|
||||
}
|
554
external/llvm/lib/Support/Windows/Program.inc
vendored
554
external/llvm/lib/Support/Windows/Program.inc
vendored
File diff suppressed because it is too large
Load Diff
129
external/llvm/lib/Support/Windows/RWMutex.inc
vendored
129
external/llvm/lib/Support/Windows/RWMutex.inc
vendored
@ -1,129 +0,0 @@
|
||||
//= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Win32 specific (non-pthread) RWMutex class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only generic Win32 code that
|
||||
//=== is guaranteed to work on *all* Win32 variants.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Windows has slim read-writer lock support on Vista and higher, so we
|
||||
// will attempt to load the APIs. If they exist, we will use them, and
|
||||
// if not, we will fall back on critical sections. When we drop support
|
||||
// for XP, we can stop lazy-loading these APIs and just use them directly.
|
||||
#if defined(__MINGW32__)
|
||||
// Taken from WinNT.h
|
||||
typedef struct _RTL_SRWLOCK {
|
||||
PVOID Ptr;
|
||||
} RTL_SRWLOCK, *PRTL_SRWLOCK;
|
||||
|
||||
// Taken from WinBase.h
|
||||
typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
|
||||
#endif
|
||||
|
||||
static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
|
||||
static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
|
||||
static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
|
||||
static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
|
||||
static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
|
||||
|
||||
static bool sHasSRW = false;
|
||||
|
||||
static bool loadSRW() {
|
||||
static bool sChecked = false;
|
||||
if (!sChecked) {
|
||||
sChecked = true;
|
||||
|
||||
if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
|
||||
fpInitializeSRWLock =
|
||||
(VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
|
||||
"InitializeSRWLock");
|
||||
fpAcquireSRWLockExclusive =
|
||||
(VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
|
||||
"AcquireSRWLockExclusive");
|
||||
fpAcquireSRWLockShared =
|
||||
(VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
|
||||
"AcquireSRWLockShared");
|
||||
fpReleaseSRWLockExclusive =
|
||||
(VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
|
||||
"ReleaseSRWLockExclusive");
|
||||
fpReleaseSRWLockShared =
|
||||
(VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
|
||||
"ReleaseSRWLockShared");
|
||||
|
||||
if (fpInitializeSRWLock != NULL) {
|
||||
sHasSRW = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sHasSRW;
|
||||
}
|
||||
|
||||
sys::RWMutexImpl::RWMutexImpl() {
|
||||
if (loadSRW()) {
|
||||
data_ = calloc(1, sizeof(SRWLOCK));
|
||||
fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
|
||||
} else {
|
||||
data_ = calloc(1, sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
}
|
||||
}
|
||||
|
||||
sys::RWMutexImpl::~RWMutexImpl() {
|
||||
if (!sHasSRW)
|
||||
DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
// Nothing to do in the case of slim reader/writers except free the memory.
|
||||
free(data_);
|
||||
}
|
||||
|
||||
bool sys::RWMutexImpl::reader_acquire() {
|
||||
if (sHasSRW) {
|
||||
fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
|
||||
} else {
|
||||
EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sys::RWMutexImpl::reader_release() {
|
||||
if (sHasSRW) {
|
||||
fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
|
||||
} else {
|
||||
LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sys::RWMutexImpl::writer_acquire() {
|
||||
if (sHasSRW) {
|
||||
fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
|
||||
} else {
|
||||
EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sys::RWMutexImpl::writer_release() {
|
||||
if (sHasSRW) {
|
||||
fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
|
||||
} else {
|
||||
LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
864
external/llvm/lib/Support/Windows/Signals.inc
vendored
864
external/llvm/lib/Support/Windows/Signals.inc
vendored
File diff suppressed because it is too large
Load Diff
@ -1,52 +0,0 @@
|
||||
//= llvm/Support/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Win32 specific (non-pthread) ThreadLocal class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only generic Win32 code that
|
||||
//=== is guaranteed to work on *all* Win32 variants.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
#include "llvm/Support/ThreadLocal.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
sys::ThreadLocalImpl::ThreadLocalImpl() : data() {
|
||||
static_assert(sizeof(DWORD) <= sizeof(data), "size too big");
|
||||
DWORD* tls = reinterpret_cast<DWORD*>(&data);
|
||||
*tls = TlsAlloc();
|
||||
assert(*tls != TLS_OUT_OF_INDEXES);
|
||||
}
|
||||
|
||||
sys::ThreadLocalImpl::~ThreadLocalImpl() {
|
||||
DWORD* tls = reinterpret_cast<DWORD*>(&data);
|
||||
TlsFree(*tls);
|
||||
}
|
||||
|
||||
void *sys::ThreadLocalImpl::getInstance() {
|
||||
DWORD* tls = reinterpret_cast<DWORD*>(&data);
|
||||
return TlsGetValue(*tls);
|
||||
}
|
||||
|
||||
void sys::ThreadLocalImpl::setInstance(const void* d){
|
||||
DWORD* tls = reinterpret_cast<DWORD*>(&data);
|
||||
int errorcode = TlsSetValue(*tls, const_cast<void*>(d));
|
||||
assert(errorcode != 0);
|
||||
(void)errorcode;
|
||||
}
|
||||
|
||||
void sys::ThreadLocalImpl::removeInstance() {
|
||||
setInstance(0);
|
||||
}
|
||||
|
||||
}
|
109
external/llvm/lib/Support/Windows/Threading.inc
vendored
109
external/llvm/lib/Support/Windows/Threading.inc
vendored
@ -1,109 +0,0 @@
|
||||
//===- Windows/Threading.inc - Win32 Threading Implementation - -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the Win32 specific implementation of Threading functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
|
||||
#include "Windows/WindowsSupport.h"
|
||||
#include <process.h>
|
||||
|
||||
// Windows will at times define MemoryFence.
|
||||
#ifdef MemoryFence
|
||||
#undef MemoryFence
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
struct ThreadInfo {
|
||||
void(*func)(void*);
|
||||
void *param;
|
||||
};
|
||||
}
|
||||
|
||||
static unsigned __stdcall ThreadCallback(void *param) {
|
||||
struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
|
||||
info->func(info->param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData,
|
||||
unsigned RequestedStackSize) {
|
||||
struct ThreadInfo param = { Fn, UserData };
|
||||
|
||||
HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
|
||||
RequestedStackSize, ThreadCallback,
|
||||
¶m, 0, NULL);
|
||||
|
||||
if (hThread) {
|
||||
// We actually don't care whether the wait succeeds or fails, in
|
||||
// the same way we don't care whether the pthread_join call succeeds
|
||||
// or fails. There's not much we could do if this were to fail. But
|
||||
// on success, this call will wait until the thread finishes executing
|
||||
// before returning.
|
||||
(void)::WaitForSingleObject(hThread, INFINITE);
|
||||
::CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t llvm::get_threadid() {
|
||||
return uint64_t(::GetCurrentThreadId());
|
||||
}
|
||||
|
||||
uint32_t llvm::get_max_thread_name_length() { return 0; }
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
static void SetThreadName(DWORD Id, LPCSTR Name) {
|
||||
constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
|
||||
#pragma pack(push, 8)
|
||||
struct THREADNAME_INFO {
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to thread name
|
||||
DWORD dwThreadId; // Thread ID (-1 == current thread)
|
||||
DWORD dwFlags; // Reserved. Do not use.
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = Name;
|
||||
info.dwThreadId = Id;
|
||||
info.dwFlags = 0;
|
||||
|
||||
__try {
|
||||
::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
|
||||
(ULONG_PTR *)&info);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void llvm::set_thread_name(const Twine &Name) {
|
||||
#if defined(_MSC_VER)
|
||||
// Make sure the input is null terminated.
|
||||
SmallString<64> Storage;
|
||||
StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
|
||||
SetThreadName(::GetCurrentThreadId(), NameStr.data());
|
||||
#endif
|
||||
}
|
||||
|
||||
void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
|
||||
// "Name" is not an inherent property of a thread on Windows. In fact, when
|
||||
// you "set" the name, you are only firing a one-time message to a debugger
|
||||
// which it interprets as a program setting its threads' name. We may be
|
||||
// able to get fancy by creating a TLS entry when someone calls
|
||||
// set_thread_name so that subsequent calls to get_thread_name return this
|
||||
// value.
|
||||
Name.clear();
|
||||
}
|
24
external/llvm/lib/Support/Windows/Watchdog.inc
vendored
24
external/llvm/lib/Support/Windows/Watchdog.inc
vendored
@ -1,24 +0,0 @@
|
||||
//===--- Windows/Watchdog.inc - Windows Watchdog Implementation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the generic Windows implementation of the Watchdog class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// TODO: implement.
|
||||
// Currently this is only used by PrettyStackTrace which is also unimplemented
|
||||
// on Windows. Roughly, a Windows implementation would use CreateWaitableTimer
|
||||
// and a second thread to run the TimerAPCProc.
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
Watchdog::Watchdog(unsigned int seconds) {}
|
||||
Watchdog::~Watchdog() {}
|
||||
}
|
||||
}
|
266
external/llvm/lib/Support/Windows/WindowsSupport.h
vendored
266
external/llvm/lib/Support/Windows/WindowsSupport.h
vendored
@ -1,266 +0,0 @@
|
||||
//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines things specific to Windows implementations. In addition to
|
||||
// providing some helpers for working with win32 APIs, this header wraps
|
||||
// <windows.h> with some portability macros. Always include WindowsSupport.h
|
||||
// instead of including <windows.h> directly.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== WARNING: Implementation here must contain only generic Win32 code that
|
||||
//=== 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
|
||||
|
||||
// Require at least Windows 7 API.
|
||||
#define _WIN32_WINNT 0x0601
|
||||
#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Config/config.h" // Get build system configuration settings
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <windows.h>
|
||||
|
||||
// Must be included after windows.h
|
||||
#include <wincrypt.h>
|
||||
|
||||
/// 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.
|
||||
inline bool RunningWindows8OrGreater() {
|
||||
// Windows 8 is version 6.2, service pack 0.
|
||||
OSVERSIONINFOEXW osvi = {};
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
osvi.dwMajorVersion = 6;
|
||||
osvi.dwMinorVersion = 2;
|
||||
osvi.wServicePackMajor = 0;
|
||||
|
||||
DWORDLONG Mask = 0;
|
||||
Mask = VerSetConditionMask(Mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
Mask = VerSetConditionMask(Mask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
Mask = VerSetConditionMask(Mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR,
|
||||
Mask) != FALSE;
|
||||
}
|
||||
|
||||
inline bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix) {
|
||||
if (!ErrMsg)
|
||||
return true;
|
||||
char *buffer = NULL;
|
||||
DWORD LastError = GetLastError();
|
||||
DWORD R = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, LastError, 0, (LPSTR)&buffer, 1, NULL);
|
||||
if (R)
|
||||
*ErrMsg = prefix + ": " + buffer;
|
||||
else
|
||||
*ErrMsg = prefix + ": Unknown error";
|
||||
*ErrMsg += " (0x" + llvm::utohexstr(LastError) + ")";
|
||||
|
||||
LocalFree(buffer);
|
||||
return R != 0;
|
||||
}
|
||||
|
||||
template <typename HandleTraits>
|
||||
class ScopedHandle {
|
||||
typedef typename HandleTraits::handle_type handle_type;
|
||||
handle_type Handle;
|
||||
|
||||
ScopedHandle(const ScopedHandle &other); // = delete;
|
||||
void operator=(const ScopedHandle &other); // = delete;
|
||||
public:
|
||||
ScopedHandle()
|
||||
: Handle(HandleTraits::GetInvalid()) {}
|
||||
|
||||
explicit ScopedHandle(handle_type h)
|
||||
: Handle(h) {}
|
||||
|
||||
~ScopedHandle() {
|
||||
if (HandleTraits::IsValid(Handle))
|
||||
HandleTraits::Close(Handle);
|
||||
}
|
||||
|
||||
handle_type take() {
|
||||
handle_type t = Handle;
|
||||
Handle = HandleTraits::GetInvalid();
|
||||
return t;
|
||||
}
|
||||
|
||||
ScopedHandle &operator=(handle_type h) {
|
||||
if (HandleTraits::IsValid(Handle))
|
||||
HandleTraits::Close(Handle);
|
||||
Handle = h;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// True if Handle is valid.
|
||||
explicit operator bool() const {
|
||||
return HandleTraits::IsValid(Handle) ? true : false;
|
||||
}
|
||||
|
||||
operator handle_type() const {
|
||||
return Handle;
|
||||
}
|
||||
};
|
||||
|
||||
struct CommonHandleTraits {
|
||||
typedef HANDLE handle_type;
|
||||
|
||||
static handle_type GetInvalid() {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static void Close(handle_type h) {
|
||||
::CloseHandle(h);
|
||||
}
|
||||
|
||||
static bool IsValid(handle_type h) {
|
||||
return h != GetInvalid();
|
||||
}
|
||||
};
|
||||
|
||||
struct JobHandleTraits : CommonHandleTraits {
|
||||
static handle_type GetInvalid() {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct CryptContextTraits : CommonHandleTraits {
|
||||
typedef HCRYPTPROV handle_type;
|
||||
|
||||
static handle_type GetInvalid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Close(handle_type h) {
|
||||
::CryptReleaseContext(h, 0);
|
||||
}
|
||||
|
||||
static bool IsValid(handle_type h) {
|
||||
return h != GetInvalid();
|
||||
}
|
||||
};
|
||||
|
||||
struct RegTraits : CommonHandleTraits {
|
||||
typedef HKEY handle_type;
|
||||
|
||||
static handle_type GetInvalid() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Close(handle_type h) {
|
||||
::RegCloseKey(h);
|
||||
}
|
||||
|
||||
static bool IsValid(handle_type h) {
|
||||
return h != GetInvalid();
|
||||
}
|
||||
};
|
||||
|
||||
struct FindHandleTraits : CommonHandleTraits {
|
||||
static void Close(handle_type h) {
|
||||
::FindClose(h);
|
||||
}
|
||||
};
|
||||
|
||||
struct FileHandleTraits : CommonHandleTraits {};
|
||||
|
||||
typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
|
||||
typedef ScopedHandle<FileHandleTraits> ScopedFileHandle;
|
||||
typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
|
||||
typedef ScopedHandle<RegTraits> ScopedRegHandle;
|
||||
typedef ScopedHandle<FindHandleTraits> ScopedFindHandle;
|
||||
typedef ScopedHandle<JobHandleTraits> ScopedJobHandle;
|
||||
|
||||
namespace llvm {
|
||||
template <class T>
|
||||
class SmallVectorImpl;
|
||||
|
||||
template <class T>
|
||||
typename SmallVectorImpl<T>::const_pointer
|
||||
c_str(SmallVectorImpl<T> &str) {
|
||||
str.push_back(0);
|
||||
str.pop_back();
|
||||
return str.data();
|
||||
}
|
||||
|
||||
namespace sys {
|
||||
|
||||
inline std::chrono::nanoseconds toDuration(FILETIME Time) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.LowPart = Time.dwLowDateTime;
|
||||
TimeInteger.HighPart = Time.dwHighDateTime;
|
||||
|
||||
// FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
|
||||
return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
|
||||
}
|
||||
|
||||
inline TimePoint<> toTimePoint(FILETIME Time) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.LowPart = Time.dwLowDateTime;
|
||||
TimeInteger.HighPart = Time.dwHighDateTime;
|
||||
|
||||
// Adjust for different epoch
|
||||
TimeInteger.QuadPart -= 11644473600ll * 10000000;
|
||||
|
||||
// FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
|
||||
return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
|
||||
}
|
||||
|
||||
inline FILETIME toFILETIME(TimePoint<> TP) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
|
||||
TimeInteger.QuadPart += 11644473600ll * 10000000;
|
||||
|
||||
FILETIME Time;
|
||||
Time.dwLowDateTime = TimeInteger.LowPart;
|
||||
Time.dwHighDateTime = TimeInteger.HighPart;
|
||||
return Time;
|
||||
}
|
||||
|
||||
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,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
/// Convert from UTF16 to the current code page used in the system
|
||||
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
} // end namespace windows
|
||||
} // end namespace sys
|
||||
} // end namespace llvm.
|
||||
|
||||
#endif
|
@ -1,102 +0,0 @@
|
||||
/* in libgcc.a */
|
||||
|
||||
#ifdef HAVE__ALLOCA
|
||||
EXPLICIT_SYMBOL(_alloca)
|
||||
EXPLICIT_SYMBOL2(alloca, _alloca)
|
||||
#endif
|
||||
#ifdef HAVE___ALLOCA
|
||||
EXPLICIT_SYMBOL(__alloca)
|
||||
#endif
|
||||
#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
|
||||
|
||||
#ifdef HAVE___ASHLDI3
|
||||
EXPLICIT_SYMBOL(__ashldi3)
|
||||
#endif
|
||||
#ifdef HAVE___ASHRDI3
|
||||
EXPLICIT_SYMBOL(__ashrdi3)
|
||||
#endif
|
||||
#ifdef HAVE___CMPDI2 // FIXME: unused
|
||||
EXPLICIT_SYMBOL(__cmpdi2)
|
||||
#endif
|
||||
#ifdef HAVE___DIVDI3
|
||||
EXPLICIT_SYMBOL(__divdi3)
|
||||
#endif
|
||||
#ifdef HAVE___FIXDFDI
|
||||
EXPLICIT_SYMBOL(__fixdfdi)
|
||||
#endif
|
||||
#ifdef HAVE___FIXSFDI
|
||||
EXPLICIT_SYMBOL(__fixsfdi)
|
||||
#endif
|
||||
#ifdef HAVE___FIXUNSDFDI
|
||||
EXPLICIT_SYMBOL(__fixunsdfdi)
|
||||
#endif
|
||||
#ifdef HAVE___FIXUNSSFDI
|
||||
EXPLICIT_SYMBOL(__fixunssfdi)
|
||||
#endif
|
||||
#ifdef HAVE___FLOATDIDF
|
||||
EXPLICIT_SYMBOL(__floatdidf)
|
||||
#endif
|
||||
#ifdef HAVE___FLOATDISF
|
||||
EXPLICIT_SYMBOL(__floatdisf)
|
||||
#endif
|
||||
#ifdef HAVE___LSHRDI3
|
||||
EXPLICIT_SYMBOL(__lshrdi3)
|
||||
#endif
|
||||
#ifdef HAVE___MODDI3
|
||||
EXPLICIT_SYMBOL(__moddi3)
|
||||
#endif
|
||||
#ifdef HAVE___UDIVDI3
|
||||
EXPLICIT_SYMBOL(__udivdi3)
|
||||
#endif
|
||||
#ifdef HAVE___UMODDI3
|
||||
EXPLICIT_SYMBOL(__umoddi3)
|
||||
#endif
|
||||
|
||||
/* msvcrt */
|
||||
#if defined(_MSC_VER)
|
||||
EXPLICIT_SYMBOL2(alloca, _alloca_probe)
|
||||
|
||||
#ifdef _M_IX86
|
||||
#define INLINE_DEF_FLOAT_SYMBOL(SYM, ARGC) INLINE_DEF_SYMBOL##ARGC(float, SYM)
|
||||
INLINE_DEF_FLOAT_SYMBOL(acosf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(asinf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(atanf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(atan2f, 2)
|
||||
INLINE_DEF_FLOAT_SYMBOL(ceilf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(cosf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(coshf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(expf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(floorf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(fmodf, 2)
|
||||
INLINE_DEF_FLOAT_SYMBOL(logf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(powf, 2)
|
||||
INLINE_DEF_FLOAT_SYMBOL(sinf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(sinhf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(sqrtf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(tanf, 1)
|
||||
INLINE_DEF_FLOAT_SYMBOL(tanhf, 1)
|
||||
|
||||
// These were added in VS 2013.
|
||||
#if (1800 <= _MSC_VER && _MSC_VER < 1900)
|
||||
INLINE_DEF_FLOAT_SYMBOL(copysignf, 2)
|
||||
INLINE_DEF_FLOAT_SYMBOL(fminf, 2)
|
||||
INLINE_DEF_FLOAT_SYMBOL(fmaxf, 2)
|
||||
#endif
|
||||
#undef INLINE_DEF_FLOAT_SYMBOL
|
||||
#endif
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user