return *this;
}
- SymbolResolverFtor ExternalSymbolResolver;
+ std::unique_ptr<RuntimeDyld::SymbolResolver> ExternalSymbolResolver;
std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
ModuleAdderFtor ModuleAdder;
};
LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
auto &LDResources = LogicalDylibs.back().getDylibResources();
- LDResources.ExternalSymbolResolver =
- [Resolver](const std::string &Name) {
- return Resolver->findSymbol(Name);
- };
+ LDResources.ExternalSymbolResolver = std::move(Resolver);
auto &MemMgrRef = *MemMgr;
LDResources.MemMgr =
auto &LMResources = LD.getLogicalModuleResources(LMH);
if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
- return LD.getDylibResources().ExternalSymbolResolver(Name);
+ auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+ return LDResolver->findSymbolInLogicalDylib(Name);
},
- [](const std::string &Name) {
- return RuntimeDyld::SymbolInfo(nullptr);
+ [&LD](const std::string &Name) {
+ auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+ return LDResolver->findSymbol(Name);
});
auto GVsH =
if (auto Symbol = LD.findSymbolInternally(LMH, Name))
return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
Symbol.getFlags());
- return LD.getDylibResources().ExternalSymbolResolver(Name);
+ auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+ return LDResolver->findSymbolInLogicalDylib(Name);
},
- [this, &LD, LMH](const std::string &Name) {
- if (auto Symbol = LD.findSymbolInternally(LMH, Name))
- return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
- Symbol.getFlags());
- return RuntimeDyld::SymbolInfo(nullptr);
+ [this, &LD](const std::string &Name) {
+ auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+ return LDResolver->findSymbol(Name);
});
return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
namespace llvm {
namespace orc {
-template <typename ExternalLookupFtorT, typename DylibLookupFtorT>
+template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
class LambdaResolver : public RuntimeDyld::SymbolResolver {
public:
- LambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
- DylibLookupFtorT DylibLookupFtor)
- : ExternalLookupFtor(ExternalLookupFtor),
- DylibLookupFtor(DylibLookupFtor) {}
-
- RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
- return ExternalLookupFtor(Name);
- }
+ LambdaResolver(DylibLookupFtorT DylibLookupFtor,
+ ExternalLookupFtorT ExternalLookupFtor)
+ : DylibLookupFtor(DylibLookupFtor),
+ ExternalLookupFtor(ExternalLookupFtor) {}
RuntimeDyld::SymbolInfo
findSymbolInLogicalDylib(const std::string &Name) final {
return DylibLookupFtor(Name);
}
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
+ return ExternalLookupFtor(Name);
+ }
+
private:
- ExternalLookupFtorT ExternalLookupFtor;
DylibLookupFtorT DylibLookupFtor;
+ ExternalLookupFtorT ExternalLookupFtor;
};
-template <typename ExternalLookupFtorT,
- typename DylibLookupFtorT>
-std::unique_ptr<LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT>>
-createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
- DylibLookupFtorT DylibLookupFtor) {
- typedef LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT> LR;
- return make_unique<LR>(std::move(ExternalLookupFtor),
- std::move(DylibLookupFtor));
+template <typename DylibLookupFtorT,
+ typename ExternalLookupFtorT>
+std::unique_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
+createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
+ ExternalLookupFtorT ExternalLookupFtor) {
+ typedef LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT> LR;
+ return make_unique<LR>(std::move(DylibLookupFtor),
+ std::move(ExternalLookupFtor));
}
} // End namespace orc.
public:
virtual ~SymbolResolver() {}
- /// This method returns the address of the specified function or variable.
- /// It is used to resolve symbols during module linking.
- ///
- /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
- /// skip all relocations for that symbol, and the client will be responsible
- /// for handling them manually.
- virtual SymbolInfo findSymbol(const std::string &Name) = 0;
-
/// This method returns the address of the specified symbol if it exists
/// within the logical dynamic library represented by this
- /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
+ /// RTDyldMemoryManager. Unlike findSymbol, queries through this
/// interface should return addresses for hidden symbols.
///
/// This is of particular importance for the Orc JIT APIs, which support lazy
/// writing memory managers for MCJIT can usually ignore this method.
///
/// This method will be queried by RuntimeDyld when checking for previous
- /// definitions of common symbols. It will *not* be queried by default when
- /// resolving external symbols (this minimises the link-time overhead for
- /// MCJIT clients who don't care about Orc features). If you are writing a
- /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
- /// search the logical dylib, you should override your getSymbolAddress
- /// method call this method directly.
+ /// definitions of common symbols.
virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
+
+ /// This method returns the address of the specified function or variable.
+ /// It is used to resolve symbols during module linking.
+ ///
+ /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
+ /// skip all relocations for that symbol, and the client will be responsible
+ /// for handling them manually.
+ virtual SymbolInfo findSymbol(const std::string &Name) = 0;
+
private:
virtual void anchor();
};
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
}
- std::shared_ptr<RuntimeDyld::SymbolResolver>
+ std::unique_ptr<RuntimeDyld::SymbolResolver>
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
- auto Resolver = orc::createLambdaResolver(
+ return orc::createLambdaResolver(
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
// Search order:
// 1. JIT'd symbols.
[](const std::string &Name) {
return RuntimeDyld::SymbolInfo(nullptr);
});
-
- return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
}
template <typename LayerT>
RuntimeDyld::SymbolInfo
findSymbolInLogicalDylib(const std::string &Name) override {
- return M.ClientResolver->findSymbolInLogicalDylib(Name);
+ return M.ClientResolver->findSymbol(Name);
}
private:
if (Loc == GlobalSymbolTable.end()) {
// This is an external symbol, try to get its address from the symbol
// resolver.
- Addr = Resolver.findSymbol(Name.data()).getAddress();
+ // First search for the symbol in this logical dylib.
+ Addr = Resolver.findSymbolInLogicalDylib(Name.data()).getAddress();
+ // If that fails, try searching for an external symbol.
+ if (!Addr)
+ Addr = Resolver.findSymbol(Name.data()).getAddress();
// The call to getSymbolAddress may have caused additional modules to
// be loaded, which may have added new entries to the
// ExternalSymbolRelocations map. Consquently, we need to update our
// 1) Search the JIT symbols.
// 2) Check for C++ runtime overrides.
// 3) Search the host process (LLI)'s symbol table.
- std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver =
+ auto Resolver =
orc::createLambdaResolver(
[this](const std::string &Name) {
if (auto Sym = CODLayer.findSymbol(Name, true))
// Forward MCJIT's symbol resolution calls to the remote.
static_cast<ForwardingMemoryManager*>(RTDyldMM)->setResolver(
orc::createLambdaResolver(
+ [](const std::string &Name) { return nullptr; },
[&](const std::string &Name) {
if (auto Addr = ExitOnErr(R.getSymbolAddress(Name)))
return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
return RuntimeDyld::SymbolInfo(nullptr);
- },
- [](const std::string &Name) { return nullptr; }
+ }
));
// Grab the target address of the JIT'd main function on the remote and call