Lookup Windows functions in process.
Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
parent
b2ab0a55e0
commit
0cf6aec6a7
@ -96,6 +96,12 @@ inline namespace windows {
|
||||
///
|
||||
bool IsDLL(const std::string& Path);
|
||||
|
||||
///\brief Look for given symbol in all modules loaded by the current process
|
||||
///
|
||||
/// \returns The adress of the symbol or null if not found
|
||||
///
|
||||
const void* LookupSymbol(const std::string& Name);
|
||||
|
||||
/// \brief Read registry string.
|
||||
/// This also supports a means to look for high-versioned keys by use
|
||||
/// of a $VERSION placeholder in the key path.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "IncrementalJIT.h"
|
||||
|
||||
#include "IncrementalExecutor.h"
|
||||
#include "cling/Utils/Platform.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
@ -217,13 +218,20 @@ IncrementalJIT::getSymbolAddressWithoutMangling(llvm::StringRef Name,
|
||||
if (auto Sym = getInjectedSymbols(Name))
|
||||
return Sym;
|
||||
|
||||
// Avoid constructing std::string from llvm::StringRef more than once
|
||||
const std::string SymName = Name;
|
||||
if (AlsoInProcess) {
|
||||
if (RuntimeDyld::SymbolInfo SymInfo = m_ExeMM->findSymbol(Name))
|
||||
if (RuntimeDyld::SymbolInfo SymInfo = m_ExeMM->findSymbol(SymName))
|
||||
return llvm::orc::JITSymbol(SymInfo.getAddress(),
|
||||
llvm::JITSymbolFlags::Exported);
|
||||
#ifdef LLVM_ON_WIN32
|
||||
if (const void* Sym = platform::LookupSymbol(SymName))
|
||||
return llvm::orc::JITSymbol(llvm::orc::TargetAddress(Sym),
|
||||
llvm::JITSymbolFlags::Exported);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (auto Sym = m_LazyEmitLayer.findSymbol(Name, false))
|
||||
if (auto Sym = m_LazyEmitLayer.findSymbol(SymName, false))
|
||||
return Sym;
|
||||
|
||||
return llvm::orc::JITSymbol(nullptr);
|
||||
|
@ -86,6 +86,49 @@ bool ReportLastError(const char* Prefix) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const void* LookupSymbol(const std::string& Name) {
|
||||
#ifdef _WIN64
|
||||
const DWORD Flags = LIST_MODULES_64BIT;
|
||||
#else
|
||||
const DWORD Flags = LIST_MODULES_32BIT;
|
||||
#endif
|
||||
|
||||
DWORD Bytes;
|
||||
const std::string CStr(Name);
|
||||
std::string ErrStr;
|
||||
llvm::SmallVector<HMODULE, 128> Modules;
|
||||
Modules.resize(Modules.capacity());
|
||||
if (::EnumProcessModulesEx(::GetCurrentProcess(), &Modules[0],
|
||||
Modules.capacity_in_bytes(), &Bytes, Flags) != 0) {
|
||||
// Search the modules we got
|
||||
const DWORD NumNeeded = Bytes/sizeof(HMODULE);
|
||||
const DWORD NumFirst = Modules.size();
|
||||
if (NumNeeded < NumFirst)
|
||||
Modules.resize(NumNeeded);
|
||||
|
||||
// In reverse so user loaded modules are searched first
|
||||
for (auto It = Modules.rbegin(), End = Modules.rend(); It < End; ++It) {
|
||||
if (const void* Addr = ::GetProcAddress(*It, CStr.c_str()))
|
||||
return Addr;
|
||||
}
|
||||
if (NumNeeded > NumFirst) {
|
||||
// The number of modules was too small to get them all, so call again
|
||||
Modules.resize(NumNeeded);
|
||||
if (::EnumProcessModulesEx(::GetCurrentProcess(), &Modules[0],
|
||||
Modules.capacity_in_bytes(), &Bytes, Flags) != 0) {
|
||||
for (DWORD i = NumNeeded-1; i > NumFirst; --i) {
|
||||
if (const void* Addr = ::GetProcAddress(Modules[i], CStr.c_str()))
|
||||
return Addr;
|
||||
}
|
||||
} else
|
||||
ReportLastError("EnumProcessModulesEx");
|
||||
}
|
||||
} else
|
||||
ReportLastError("EnumProcessModulesEx");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Taken from clang/lib/Driver/MSVCToolChain.cpp
|
||||
|
Loading…
x
Reference in New Issue
Block a user