Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef CLING_DYNAMIC_LIBRARY_MANAGER_H
#define CLING_DYNAMIC_LIBRARY_MANAGER_H

#include "llvm/ExecutionEngine/Orc/Shared/LibraryResolver.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
Expand Down Expand Up @@ -66,6 +67,8 @@ namespace cling {

Dyld* m_Dyld = nullptr;

std::unique_ptr<llvm::orc::LibraryResolutionDriver> m_DyldController;

///\brief Concatenates current include paths and the system include paths
/// and performs a lookup for the filename.
/// See more information for RPATH and RUNPATH: https://en.wikipedia.org/wiki/Rpath
Expand Down Expand Up @@ -128,6 +131,10 @@ namespace cling {
return;
auto pos = prepend ? m_SearchPaths.begin() : m_SearchPaths.end();
m_SearchPaths.insert(pos, SearchPathInfo{dir.str(), isUser});
if (m_DyldController)
m_DyldController->addScanPath(dir.str(),
isUser ? llvm::orc::PathType::User
: llvm::orc::PathType::System);
}
}

Expand Down
7 changes: 7 additions & 0 deletions interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ namespace cling {
#endif
};

// m_DyldController = llvm::orc::LibraryResolutionDriver::create(
// llvm::orc::LibraryResolver::Setup::create({}));

// Behaviour is to not add paths that don't exist...In an interpreted env
// does this make sense? Path could pop into existance at any time.
for (const char* Var : kSysLibraryEnv) {
Expand Down Expand Up @@ -393,6 +396,8 @@ namespace cling {
if (!insRes.second)
return kLoadLibAlreadyLoaded;
m_LoadedLibraries.insert(canonicalLoadedLib);
if (m_DyldController)
m_DyldController->markLibraryLoaded(canonicalLoadedLib);
return kLoadLibSuccess;
}

Expand Down Expand Up @@ -424,6 +429,8 @@ namespace cling {

m_DyLibs.erase(dyLibHandle);
m_LoadedLibraries.erase(canonicalLoadedLib);
if (m_DyldController)
m_DyldController->markLibraryUnLoaded(canonicalLoadedLib);
}

bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
Expand Down
70 changes: 58 additions & 12 deletions interpreter/cling/lib/Interpreter/DynamicLibraryManagerSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1335,29 +1335,75 @@ namespace cling {
}

DynamicLibraryManager::~DynamicLibraryManager() {
static_assert(sizeof(Dyld) > 0, "Incomplete type");
delete m_Dyld;
// static_assert(sizeof(Dyld) > 0, "Incomplete type");
// delete m_Dyld;
}

void DynamicLibraryManager::initializeDyld(
std::function<bool(llvm::StringRef)> shouldPermanentlyIgnore) {
//assert(!m_Dyld && "Already initialized!");
if (m_Dyld)
delete m_Dyld;
// assert(!m_Dyld && "Already initialized!");
// if (m_Dyld)
// delete m_Dyld;
if (m_DyldController)
m_DyldController.reset();

llvm::orc::LibraryResolver::Setup S =
llvm::orc::LibraryResolver::Setup::create({});
S.ShouldScanCall = [&,
shouldPermanentlyIgnore](llvm::StringRef lib) -> bool {
if (shouldPermanentlyIgnore) {
return !shouldPermanentlyIgnore(lib) || !isLibraryLoaded(lib);
}
// fallback behavior if no callback provided
return !isLibraryLoaded(lib);
};
m_DyldController = llvm::orc::LibraryResolutionDriver::create(S);

for (const auto& info : m_SearchPaths) {
m_DyldController->addScanPath(info.Path,
info.IsUser ? llvm::orc::PathType::User
: llvm::orc::PathType::System);
}

for (const auto& lib : m_LoadedLibraries) {
m_DyldController->markLibraryLoaded(lib.first());
}

std::string exeP = GetExecutablePath();
auto ObjF =
cantFail(llvm::object::ObjectFile::createObjectFile(exeP));
// std::string exeP = GetExecutablePath();
// auto ObjF =
// cantFail(llvm::object::ObjectFile::createObjectFile(exeP));

m_Dyld = new Dyld(*this, shouldPermanentlyIgnore,
ObjF.getBinary()->getFileFormatName());
// m_Dyld = new Dyld(*this, shouldPermanentlyIgnore,
// ObjF.getBinary()->getFileFormatName());
}

std::string
DynamicLibraryManager::searchLibrariesForSymbol(StringRef mangledName,
bool searchSystem/* = true*/) const {
assert(m_Dyld && "Must call initialize dyld before!");
return m_Dyld->searchLibrariesForSymbol(mangledName, searchSystem);
assert(m_DyldController && "Must call initialize dyld before!");
std::string res = "";
std::vector<std::string> sym;
sym.push_back(mangledName.str());
llvm::orc::SearchConfig config;
config.Policy = {{{llvm::orc::LibraryManager::LibState::Queried,
llvm::orc::PathType::User},
{llvm::orc::LibraryManager::LibState::Unloaded,
llvm::orc::PathType::User},
{llvm::orc::LibraryManager::LibState::Queried,
llvm::orc::PathType::System},
{llvm::orc::LibraryManager::LibState::Unloaded,
llvm::orc::PathType::System}}};
config.Options.FilterFlags =
llvm::orc::SymbolEnumeratorOptions::IgnoreUndefined;
m_DyldController->resolveSymbols(
sym,
[&](llvm::orc::LibraryResolver::SymbolQuery& Q) {
if (auto s = Q.getResolvedLib(mangledName))
res = *s;
},
config);
return res;
// return m_Dyld->searchLibrariesForSymbol(mangledName, searchSystem);
}

std::string DynamicLibraryManager::getSymbolLocation(void *func) {
Expand Down
Loading
Loading