Lookup Windows functions in process.

Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
Roman Zulak 2016-09-15 14:34:58 -04:00 committed by sftnight
parent b2ab0a55e0
commit 0cf6aec6a7
3 changed files with 59 additions and 2 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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