You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.246
Former-commit-id: 0c7ce5b1a7851e13f22acfd379b7f9fb304e4833
This commit is contained in:
parent
a7724cd563
commit
279aa8f685
202
external/llvm/lib/Support/Windows/DynamicLibrary.inc
vendored
Normal file
202
external/llvm/lib/Support/Windows/DynamicLibrary.inc
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
//===- 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;
|
||||
}
|
Reference in New Issue
Block a user