Move windows::LookupSymbol to platform::DLSym

Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
Roman Zulak 2016-09-17 18:28:29 -04:00 committed by sftnight
parent 0cf6aec6a7
commit 2bc6a5c66b
5 changed files with 74 additions and 59 deletions

View File

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

View File

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

View File

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

View File

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

View File

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