mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[RuntimeDyld] Call the SymbolResolver::findSymbolInLogicalDylib method when
searching for external symbols, and fall back to the SymbolResolver::findSymbol method if the former returns null. This makes RuntimeDyld behave more like a static linker: Symbol definitions from within the current module's "logical dylib" will be preferred to external definitions. We can build on this behavior in the future to properly support weak symbol handling. Custom symbol resolvers that override the findSymbolInLogicalDylib method may notice changes due to this patch. Clients who have not overridden this method should generally be unaffected, however users of the OrcMCJITReplacement class may notice changes. llvm-svn: 270716
This commit is contained in:
parent
8544c01533
commit
0a4d39f9bf
@ -145,7 +145,7 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
SymbolResolverFtor ExternalSymbolResolver;
|
||||
std::unique_ptr<RuntimeDyld::SymbolResolver> ExternalSymbolResolver;
|
||||
std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
|
||||
ModuleAdderFtor ModuleAdder;
|
||||
};
|
||||
@ -188,10 +188,7 @@ public:
|
||||
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 =
|
||||
@ -357,10 +354,12 @@ private:
|
||||
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 =
|
||||
@ -484,13 +483,12 @@ private:
|
||||
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),
|
||||
|
@ -22,37 +22,37 @@
|
||||
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.
|
||||
|
@ -193,17 +193,9 @@ public:
|
||||
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
|
||||
@ -212,13 +204,17 @@ public:
|
||||
/// 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();
|
||||
};
|
||||
|
@ -137,10 +137,10 @@ public:
|
||||
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.
|
||||
@ -162,8 +162,6 @@ public:
|
||||
[](const std::string &Name) {
|
||||
return RuntimeDyld::SymbolInfo(nullptr);
|
||||
});
|
||||
|
||||
return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
|
||||
}
|
||||
|
||||
template <typename LayerT>
|
||||
|
@ -121,7 +121,7 @@ class OrcMCJITReplacement : public ExecutionEngine {
|
||||
|
||||
RuntimeDyld::SymbolInfo
|
||||
findSymbolInLogicalDylib(const std::string &Name) override {
|
||||
return M.ClientResolver->findSymbolInLogicalDylib(Name);
|
||||
return M.ClientResolver->findSymbol(Name);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -916,7 +916,11 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
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
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
// 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))
|
||||
|
@ -662,12 +662,12 @@ int main(int argc, char **argv, char * const *envp) {
|
||||
// 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user