Add platform::DLOpen and platform::DLClose.

Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
Roman Zulak 2016-09-15 14:17:17 -04:00 committed by sftnight
parent fb4769cecb
commit ffadea2c21
4 changed files with 60 additions and 33 deletions

View File

@ -28,6 +28,25 @@ namespace platform {
///
bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths);
///\brief Open a handle to a shared library. On Unix the lib is opened with
/// RTLD_LAZY|RTLD_GLOBAL flags.
///
/// \param [in] Path - Library to open
/// \param [out] Err - Write errors to this string when given
///
/// \returns the library handle
///
const void* DLOpen(const std::string& Path, std::string* Err = nullptr);
///\brief Close a handle to a shared library.
///
/// \param [in] Lib - Handle to library from previous call to DLOpen
/// \param [out] Err - Write errors to this string when given
///
/// \returns the library handle
///
void DLClose(const void* Lib, std::string* Err = nullptr);
///\brief Returns a normalized version of the given Path
///
std::string NormalizePath(const std::string& Path);

View File

@ -18,18 +18,9 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <system_error>
#include <sys/stat.h>
#ifdef LLVM_ON_WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
namespace cling {
DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
: m_Opts(Opts), m_Callbacks(0) {
@ -213,20 +204,10 @@ namespace cling {
if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
return kLoadLibAlreadyLoaded;
std::string errMsg;
// TODO: !permanent case
#if defined(LLVM_ON_WIN32)
HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (!dyLibHandle)
platform::GetLastErrorAsString(errMsg, "LoadLibraryEx");
#else
const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
RTLD_LAZY|RTLD_GLOBAL);
if (const char* DyLibError = dlerror()) {
errMsg = DyLibError;
}
#endif
std::string errMsg;
DyLibHandle dyLibHandle = platform::DLOpen(canonicalLoadedLib, &errMsg);
if (!dyLibHandle) {
llvm::errs() << "cling::DynamicLibraryManager::loadLibrary(): " << errMsg
<< '\n';
@ -258,17 +239,10 @@ namespace cling {
}
}
std::string errMsg;
// TODO: !permanent case
#if defined(LLVM_ON_WIN32)
if (FreeLibrary((HMODULE)dyLibHandle) == 0)
platform::GetLastErrorAsString(errMsg, "FreeLibrary");
#else
dlclose(const_cast<void*>(dyLibHandle));
if (const char* DyLibError = dlerror()) {
errMsg = DyLibError;
}
#endif
std::string errMsg;
platform::DLClose(dyLibHandle, &errMsg);
if (!errMsg.empty()) {
llvm::errs() << "cling::DynamicLibraryManager::unloadLibrary(): "
<< errMsg << '\n';

View File

@ -13,6 +13,7 @@
#include "cling/Utils/Paths.h"
#include <string>
#include <dlfcn.h>
#include <unistd.h>
// PATH_MAX
@ -37,6 +38,23 @@ std::string GetCwd() {
return std::string();
}
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;
}
return Lib;
}
void DLClose(const void* Lib, std::string* Err) {
::dlclose(const_cast<void*>(Lib));
if (Err) {
if (const char* DyLibError = ::dlerror())
*Err = DyLibError;
}
}
std::string NormalizePath(const std::string& Path) {
char Buf[PATH_MAXC];
if (const char* Result = ::realpath(Path.c_str(), Buf))

View File

@ -475,6 +475,22 @@ std::string NormalizePath(const std::string& Path) {
return std::string();
}
const void* DLOpen(const std::string& Path, std::string* Err) {
HMODULE dyLibHandle = ::LoadLibraryExA(Path.c_str(), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (!dyLibHandle && Err)
GetLastErrorAsString(*Err, "LoadLibraryEx");
return reinterpret_cast<void*>(dyLibHandle);
}
void DLClose(const void* Lib, std::string* Err) {
if (::FreeLibrary(reinterpret_cast<HMODULE>(const_cast<void*>(Lib))) == 0) {
if (Err)
GetLastErrorAsString(*Err, "FreeLibrary");
}
}
bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
char Buf[MAX_PATHC];
// Generic form of C:\Windows\System32