diff options
Diffstat (limited to 'contrib/llvm/lib/Support/Windows/DynamicLibrary.inc')
| -rw-r--r-- | contrib/llvm/lib/Support/Windows/DynamicLibrary.inc | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc deleted file mode 100644 index 71b206c4cf9e..000000000000 --- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc +++ /dev/null @@ -1,202 +0,0 @@ -//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of DynamicLibrary. -// -//===----------------------------------------------------------------------===// - -#include "WindowsSupport.h" -#include "llvm/Support/ConvertUTF.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; -} |
