Move windows::LookupSymbol to platform::DLSym
Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
parent
0cf6aec6a7
commit
2bc6a5c66b
@ -38,6 +38,12 @@ namespace platform {
|
||||
///
|
||||
const void* DLOpen(const std::string& Path, std::string* Err = nullptr);
|
||||
|
||||
///\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* DLSym(const std::string& Name, std::string* Err = nullptr);
|
||||
|
||||
///\brief Close a handle to a shared library.
|
||||
///
|
||||
/// \param [in] Lib - Handle to library from previous call to DLOpen
|
||||
@ -96,12 +102,6 @@ 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.
|
||||
|
@ -225,7 +225,7 @@ IncrementalJIT::getSymbolAddressWithoutMangling(llvm::StringRef Name,
|
||||
return llvm::orc::JITSymbol(SymInfo.getAddress(),
|
||||
llvm::JITSymbolFlags::Exported);
|
||||
#ifdef LLVM_ON_WIN32
|
||||
if (const void* Sym = platform::LookupSymbol(SymName))
|
||||
if (const void* Sym = platform::DLSym(SymName))
|
||||
return llvm::orc::JITSymbol(llvm::orc::TargetAddress(Sym),
|
||||
llvm::JITSymbolFlags::Exported);
|
||||
#endif
|
||||
|
@ -124,7 +124,7 @@ bool GetISysRoot(std::string& sysRoot, bool Verbose) {
|
||||
"/System/Library/Frameworks/CoreServices.framework/CoreServices",
|
||||
RTLD_LAZY)) {
|
||||
typedef ::OSErr (*GestaltProc)(::OSType, ::SInt32 *);
|
||||
if (GestaltProc Gestalt = (GestaltProc)dlsym(core, "Gestalt")) {
|
||||
if (GestaltProc Gestalt = (GestaltProc)::dlsym(core, "Gestalt")) {
|
||||
if (Gestalt(gestaltSystemVersionMajor, &majorVers) == ::noErr) {
|
||||
if (Gestalt(gestaltSystemVersionMinor, &minorVers) != ::noErr)
|
||||
minorVers = -1;
|
||||
|
@ -42,21 +42,37 @@ std::string GetCwd() {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static void DLErr(std::string* Err) {
|
||||
if (!Err)
|
||||
return;
|
||||
if (const char* DyLibError = ::dlerror())
|
||||
*Err = DyLibError;
|
||||
}
|
||||
|
||||
const void* DLOpen(const std::string& Path, std::string* Err) {
|
||||
void* Lib = dlopen(Path.c_str(), RTLD_LAZY|RTLD_GLOBAL);
|
||||
if (Err) {
|
||||
if (const char* DyLibError = ::dlerror())
|
||||
*Err = DyLibError;
|
||||
}
|
||||
DLErr(Err);
|
||||
return Lib;
|
||||
}
|
||||
|
||||
const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
if (const void* Self = ::dlopen(nullptr, RTLD_GLOBAL)) {
|
||||
// get dlopen error if there is one
|
||||
DLErr(Err);
|
||||
const void* Sym = ::dlsym(const_cast<void*>(Self), Name.c_str());
|
||||
// overwrite error if dlsym caused one
|
||||
DLErr(Err);
|
||||
// only get dlclose error if dlopen & dlsym haven't emited one
|
||||
DLClose(Self, Err && Err->empty() ? Err : nullptr);
|
||||
return Sym;
|
||||
}
|
||||
DLErr(Err);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DLClose(const void* Lib, std::string* Err) {
|
||||
::dlclose(const_cast<void*>(Lib));
|
||||
if (Err) {
|
||||
if (const char* DyLibError = ::dlerror())
|
||||
*Err = DyLibError;
|
||||
}
|
||||
DLErr(Err);
|
||||
}
|
||||
|
||||
std::string NormalizePath(const std::string& Path) {
|
||||
|
@ -86,49 +86,6 @@ 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
|
||||
@ -554,6 +511,48 @@ const void* DLOpen(const std::string& Path, std::string* Err) {
|
||||
return reinterpret_cast<void*>(dyLibHandle);
|
||||
}
|
||||
|
||||
const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
#ifdef _WIN64
|
||||
const DWORD Flags = LIST_MODULES_64BIT;
|
||||
#else
|
||||
const DWORD Flags = LIST_MODULES_32BIT;
|
||||
#endif
|
||||
|
||||
DWORD Bytes;
|
||||
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, Name.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], Name.c_str()))
|
||||
return Addr;
|
||||
}
|
||||
} else if (Err)
|
||||
GetLastErrorAsString(*Err, "EnumProcessModulesEx");
|
||||
}
|
||||
} else if (Err)
|
||||
GetLastErrorAsString(*Err, "EnumProcessModulesEx");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DLClose(const void* Lib, std::string* Err) {
|
||||
if (::FreeLibrary(reinterpret_cast<HMODULE>(const_cast<void*>(Lib))) == 0) {
|
||||
if (Err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user