llvm.org GIT mirror llvm / 45400ad
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270716 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 4 years ago
8 changed file(s) with 55 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
144144 return *this;
145145 }
146146
147 SymbolResolverFtor ExternalSymbolResolver;
147 std::unique_ptr ExternalSymbolResolver;
148148 std::unique_ptr> MemMgr;
149149 ModuleAdderFtor ModuleAdder;
150150 };
187187 LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
188188 auto &LDResources = LogicalDylibs.back().getDylibResources();
189189
190 LDResources.ExternalSymbolResolver =
191 [Resolver](const std::string &Name) {
192 return Resolver->findSymbol(Name);
193 };
190 LDResources.ExternalSymbolResolver = std::move(Resolver);
194191
195192 auto &MemMgrRef = *MemMgr;
196193 LDResources.MemMgr =
356353 auto &LMResources = LD.getLogicalModuleResources(LMH);
357354 if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
358355 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
359 return LD.getDylibResources().ExternalSymbolResolver(Name);
356 auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
357 return LDResolver->findSymbolInLogicalDylib(Name);
360358 },
361 [](const std::string &Name) {
362 return RuntimeDyld::SymbolInfo(nullptr);
359 [&LD](const std::string &Name) {
360 auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
361 return LDResolver->findSymbol(Name);
363362 });
364363
365364 auto GVsH =
483482 if (auto Symbol = LD.findSymbolInternally(LMH, Name))
484483 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
485484 Symbol.getFlags());
486 return LD.getDylibResources().ExternalSymbolResolver(Name);
485 auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
486 return LDResolver->findSymbolInLogicalDylib(Name);
487487 },
488 [this, &LD, LMH](const std::string &Name) {
489 if (auto Symbol = LD.findSymbolInternally(LMH, Name))
490 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
491 Symbol.getFlags());
492 return RuntimeDyld::SymbolInfo(nullptr);
488 [this, &LD](const std::string &Name) {
489 auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
490 return LDResolver->findSymbol(Name);
493491 });
494492
495493 return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
2121 namespace llvm {
2222 namespace orc {
2323
24 template ExternalLookupFtorT, typename DylibLookupFtorT>
24 template DylibLookupFtorT, typename ExternalLookupFtorT>
2525 class LambdaResolver : public RuntimeDyld::SymbolResolver {
2626 public:
2727
28 LambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
29 DylibLookupFtorT DylibLookupFtor)
30 : ExternalLookupFtor(ExternalLookupFtor),
31 DylibLookupFtor(DylibLookupFtor) {}
32
33 RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
34 return ExternalLookupFtor(Name);
35 }
28 LambdaResolver(DylibLookupFtorT DylibLookupFtor,
29 ExternalLookupFtorT ExternalLookupFtor)
30 : DylibLookupFtor(DylibLookupFtor),
31 ExternalLookupFtor(ExternalLookupFtor) {}
3632
3733 RuntimeDyld::SymbolInfo
3834 findSymbolInLogicalDylib(const std::string &Name) final {
3935 return DylibLookupFtor(Name);
4036 }
4137
38 RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
39 return ExternalLookupFtor(Name);
40 }
41
4242 private:
43 DylibLookupFtorT DylibLookupFtor;
4344 ExternalLookupFtorT ExternalLookupFtor;
44 DylibLookupFtorT DylibLookupFtor;
4545 };
4646
47 template
48 typename DylibLookupFtorT>
49 std::unique_ptr>
50 createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
51 DylibLookupFtorT DylibLookupFtor) {
52 typedef LambdaResolver LR;
53 return make_unique(std::move(ExternalLookupFtor),
54 std::move(DylibLookupFtor));
47 template
48 typename ExternalLookupFtorT>
49 std::unique_ptr>
50 createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
51 ExternalLookupFtorT ExternalLookupFtor) {
52 typedef LambdaResolver LR;
53 return make_unique(std::move(DylibLookupFtor),
54 std::move(ExternalLookupFtor));
5555 }
5656
5757 } // End namespace orc.
192192 public:
193193 virtual ~SymbolResolver() {}
194194
195 /// This method returns the address of the specified symbol if it exists
196 /// within the logical dynamic library represented by this
197 /// RTDyldMemoryManager. Unlike findSymbol, queries through this
198 /// interface should return addresses for hidden symbols.
199 ///
200 /// This is of particular importance for the Orc JIT APIs, which support lazy
201 /// compilation by breaking up modules: Each of those broken out modules
202 /// must be able to resolve hidden symbols provided by the others. Clients
203 /// writing memory managers for MCJIT can usually ignore this method.
204 ///
205 /// This method will be queried by RuntimeDyld when checking for previous
206 /// definitions of common symbols.
207 virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
208
195209 /// This method returns the address of the specified function or variable.
196210 /// It is used to resolve symbols during module linking.
197211 ///
200214 /// for handling them manually.
201215 virtual SymbolInfo findSymbol(const std::string &Name) = 0;
202216
203 /// This method returns the address of the specified symbol if it exists
204 /// within the logical dynamic library represented by this
205 /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
206 /// interface should return addresses for hidden symbols.
207 ///
208 /// This is of particular importance for the Orc JIT APIs, which support lazy
209 /// compilation by breaking up modules: Each of those broken out modules
210 /// must be able to resolve hidden symbols provided by the others. Clients
211 /// writing memory managers for MCJIT can usually ignore this method.
212 ///
213 /// This method will be queried by RuntimeDyld when checking for previous
214 /// definitions of common symbols. It will *not* be queried by default when
215 /// resolving external symbols (this minimises the link-time overhead for
216 /// MCJIT clients who don't care about Orc features). If you are writing a
217 /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
218 /// search the logical dylib, you should override your getSymbolAddress
219 /// method call this method directly.
220 virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
221217 private:
222218 virtual void anchor();
223219 };
136136 return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
137137 }
138138
139 std::shared_ptr
139 std::unique_ptr
140140 createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
141141 void *ExternalResolverCtx) {
142 auto Resolver = orc::createLambdaResolver(
142 return orc::createLambdaResolver(
143143 [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
144144 // Search order:
145145 // 1. JIT'd symbols.
161161 [](const std::string &Name) {
162162 return RuntimeDyld::SymbolInfo(nullptr);
163163 });
164
165 return std::shared_ptr(std::move(Resolver));
166164 }
167165
168166 template
120120
121121 RuntimeDyld::SymbolInfo
122122 findSymbolInLogicalDylib(const std::string &Name) override {
123 return M.ClientResolver->findSymbolInLogicalDylib(Name);
123 return M.ClientResolver->findSymbol(Name);
124124 }
125125
126126 private:
915915 if (Loc == GlobalSymbolTable.end()) {
916916 // This is an external symbol, try to get its address from the symbol
917917 // resolver.
918 Addr = Resolver.findSymbol(Name.data()).getAddress();
918 // First search for the symbol in this logical dylib.
919 Addr = Resolver.findSymbolInLogicalDylib(Name.data()).getAddress();
920 // If that fails, try searching for an external symbol.
921 if (!Addr)
922 Addr = Resolver.findSymbol(Name.data()).getAddress();
919923 // The call to getSymbolAddress may have caused additional modules to
920924 // be loaded, which may have added new entries to the
921925 // ExternalSymbolRelocations map. Consquently, we need to update our
8181 // 1) Search the JIT symbols.
8282 // 2) Check for C++ runtime overrides.
8383 // 3) Search the host process (LLI)'s symbol table.
84 std::shared_ptr Resolver =
84 auto Resolver =
8585 orc::createLambdaResolver(
8686 [this](const std::string &Name) {
8787 if (auto Sym = CODLayer.findSymbol(Name, true))
661661 // Forward MCJIT's symbol resolution calls to the remote.
662662 static_cast(RTDyldMM)->setResolver(
663663 orc::createLambdaResolver(
664 [](const std::string &Name) { return nullptr; },
664665 [&](const std::string &Name) {
665666 if (auto Addr = ExitOnErr(R.getSymbolAddress(Name)))
666667 return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
667668 return RuntimeDyld::SymbolInfo(nullptr);
668 },
669 [](const std::string &Name) { return nullptr; }
669 }
670670 ));
671671
672672 // Grab the target address of the JIT'd main function on the remote and call