xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
1013138422SDimitry Andric #include "llvm/Object/COFF.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric namespace {
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace llvm;
150b57cec5SDimitry Andric using namespace llvm::orc;
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric class JITDylibSearchOrderResolver : public JITSymbolResolver {
180b57cec5SDimitry Andric public:
JITDylibSearchOrderResolver(MaterializationResponsibility & MR,SymbolDependenceMap & Deps)19*0fca6ea1SDimitry Andric   JITDylibSearchOrderResolver(MaterializationResponsibility &MR,
20*0fca6ea1SDimitry Andric                               SymbolDependenceMap &Deps)
21*0fca6ea1SDimitry Andric       : MR(MR), Deps(Deps) {}
220b57cec5SDimitry Andric 
lookup(const LookupSet & Symbols,OnResolvedFunction OnResolved)23e8d8bef9SDimitry Andric   void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override {
240b57cec5SDimitry Andric     auto &ES = MR.getTargetJITDylib().getExecutionSession();
25480093f4SDimitry Andric     SymbolLookupSet InternedSymbols;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric     // Intern the requested symbols: lookup takes interned strings.
280b57cec5SDimitry Andric     for (auto &S : Symbols)
29480093f4SDimitry Andric       InternedSymbols.add(ES.intern(S));
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric     // Build an OnResolve callback to unwrap the interned strings and pass them
320b57cec5SDimitry Andric     // to the OnResolved callback.
330b57cec5SDimitry Andric     auto OnResolvedWithUnwrap =
348bcb0991SDimitry Andric         [OnResolved = std::move(OnResolved)](
358bcb0991SDimitry Andric             Expected<SymbolMap> InternedResult) mutable {
360b57cec5SDimitry Andric           if (!InternedResult) {
370b57cec5SDimitry Andric             OnResolved(InternedResult.takeError());
380b57cec5SDimitry Andric             return;
390b57cec5SDimitry Andric           }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric           LookupResult Result;
420b57cec5SDimitry Andric           for (auto &KV : *InternedResult)
4306c3fb27SDimitry Andric             Result[*KV.first] = {KV.second.getAddress().getValue(),
4406c3fb27SDimitry Andric                                  KV.second.getFlags()};
450b57cec5SDimitry Andric           OnResolved(Result);
460b57cec5SDimitry Andric         };
470b57cec5SDimitry Andric 
485ffd83dbSDimitry Andric     JITDylibSearchOrder LinkOrder;
495ffd83dbSDimitry Andric     MR.getTargetJITDylib().withLinkOrderDo(
505ffd83dbSDimitry Andric         [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
51*0fca6ea1SDimitry Andric     ES.lookup(
52*0fca6ea1SDimitry Andric         LookupKind::Static, LinkOrder, InternedSymbols, SymbolState::Resolved,
53*0fca6ea1SDimitry Andric         std::move(OnResolvedWithUnwrap),
54*0fca6ea1SDimitry Andric         [this](const SymbolDependenceMap &LookupDeps) { Deps = LookupDeps; });
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric 
getResponsibilitySet(const LookupSet & Symbols)57e8d8bef9SDimitry Andric   Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override {
580b57cec5SDimitry Andric     LookupSet Result;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric     for (auto &KV : MR.getSymbols()) {
610b57cec5SDimitry Andric       if (Symbols.count(*KV.first))
620b57cec5SDimitry Andric         Result.insert(*KV.first);
630b57cec5SDimitry Andric     }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric     return Result;
660b57cec5SDimitry Andric   }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric private:
690b57cec5SDimitry Andric   MaterializationResponsibility &MR;
70*0fca6ea1SDimitry Andric   SymbolDependenceMap &Deps;
710b57cec5SDimitry Andric };
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric } // end anonymous namespace
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric namespace llvm {
760b57cec5SDimitry Andric namespace orc {
770b57cec5SDimitry Andric 
78fe6060f1SDimitry Andric char RTDyldObjectLinkingLayer::ID;
79fe6060f1SDimitry Andric 
80fe6060f1SDimitry Andric using BaseT = RTTIExtends<RTDyldObjectLinkingLayer, ObjectLayer>;
81fe6060f1SDimitry Andric 
RTDyldObjectLinkingLayer(ExecutionSession & ES,GetMemoryManagerFunction GetMemoryManager)820b57cec5SDimitry Andric RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
830b57cec5SDimitry Andric     ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager)
84bdd1243dSDimitry Andric     : BaseT(ES), GetMemoryManager(std::move(GetMemoryManager)) {
85e8d8bef9SDimitry Andric   ES.registerResourceManager(*this);
86e8d8bef9SDimitry Andric }
870b57cec5SDimitry Andric 
~RTDyldObjectLinkingLayer()88480093f4SDimitry Andric RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
89e8d8bef9SDimitry Andric   assert(MemMgrs.empty() && "Layer destroyed with resources still attached");
905ffd83dbSDimitry Andric }
91480093f4SDimitry Andric 
emit(std::unique_ptr<MaterializationResponsibility> R,std::unique_ptr<MemoryBuffer> O)92e8d8bef9SDimitry Andric void RTDyldObjectLinkingLayer::emit(
93e8d8bef9SDimitry Andric     std::unique_ptr<MaterializationResponsibility> R,
940b57cec5SDimitry Andric     std::unique_ptr<MemoryBuffer> O) {
950b57cec5SDimitry Andric   assert(O && "Object must not be null");
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   auto &ES = getExecutionSession();
980b57cec5SDimitry Andric 
995ffd83dbSDimitry Andric   auto Obj = object::ObjectFile::createObjectFile(*O);
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   if (!Obj) {
1020b57cec5SDimitry Andric     getExecutionSession().reportError(Obj.takeError());
103e8d8bef9SDimitry Andric     R->failMaterialization();
1040b57cec5SDimitry Andric     return;
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   // Collect the internal symbols from the object file: We will need to
1080b57cec5SDimitry Andric   // filter these later.
1090b57cec5SDimitry Andric   auto InternalSymbols = std::make_shared<std::set<StringRef>>();
1100b57cec5SDimitry Andric   {
111bdd1243dSDimitry Andric     SymbolFlagsMap ExtraSymbolsToClaim;
1120b57cec5SDimitry Andric     for (auto &Sym : (*Obj)->symbols()) {
1135ffd83dbSDimitry Andric 
1145ffd83dbSDimitry Andric       // Skip file symbols.
1155ffd83dbSDimitry Andric       if (auto SymType = Sym.getType()) {
1165ffd83dbSDimitry Andric         if (*SymType == object::SymbolRef::ST_File)
1175ffd83dbSDimitry Andric           continue;
1185ffd83dbSDimitry Andric       } else {
1195ffd83dbSDimitry Andric         ES.reportError(SymType.takeError());
120e8d8bef9SDimitry Andric         R->failMaterialization();
1215ffd83dbSDimitry Andric         return;
1225ffd83dbSDimitry Andric       }
1235ffd83dbSDimitry Andric 
1245ffd83dbSDimitry Andric       Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
1255ffd83dbSDimitry Andric       if (!SymFlagsOrErr) {
1265ffd83dbSDimitry Andric         // TODO: Test this error.
1275ffd83dbSDimitry Andric         ES.reportError(SymFlagsOrErr.takeError());
128e8d8bef9SDimitry Andric         R->failMaterialization();
1295ffd83dbSDimitry Andric         return;
1305ffd83dbSDimitry Andric       }
1315ffd83dbSDimitry Andric 
132bdd1243dSDimitry Andric       // Try to claim responsibility of weak symbols
133bdd1243dSDimitry Andric       // if AutoClaimObjectSymbols flag is set.
134bdd1243dSDimitry Andric       if (AutoClaimObjectSymbols &&
135bdd1243dSDimitry Andric           (*SymFlagsOrErr & object::BasicSymbolRef::SF_Weak)) {
136bdd1243dSDimitry Andric         auto SymName = Sym.getName();
137bdd1243dSDimitry Andric         if (!SymName) {
138bdd1243dSDimitry Andric           ES.reportError(SymName.takeError());
139bdd1243dSDimitry Andric           R->failMaterialization();
140bdd1243dSDimitry Andric           return;
141bdd1243dSDimitry Andric         }
142bdd1243dSDimitry Andric 
143bdd1243dSDimitry Andric         // Already included in responsibility set, skip it
144bdd1243dSDimitry Andric         SymbolStringPtr SymbolName = ES.intern(*SymName);
145bdd1243dSDimitry Andric         if (R->getSymbols().count(SymbolName))
146bdd1243dSDimitry Andric           continue;
147bdd1243dSDimitry Andric 
148bdd1243dSDimitry Andric         auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
149bdd1243dSDimitry Andric         if (!SymFlags) {
150bdd1243dSDimitry Andric           ES.reportError(SymFlags.takeError());
151bdd1243dSDimitry Andric           R->failMaterialization();
152bdd1243dSDimitry Andric           return;
153bdd1243dSDimitry Andric         }
154bdd1243dSDimitry Andric 
155bdd1243dSDimitry Andric         ExtraSymbolsToClaim[SymbolName] = *SymFlags;
156bdd1243dSDimitry Andric         continue;
157bdd1243dSDimitry Andric       }
158bdd1243dSDimitry Andric 
1595ffd83dbSDimitry Andric       // Don't include symbols that aren't global.
1605ffd83dbSDimitry Andric       if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) {
1610b57cec5SDimitry Andric         if (auto SymName = Sym.getName())
1620b57cec5SDimitry Andric           InternalSymbols->insert(*SymName);
1630b57cec5SDimitry Andric         else {
1640b57cec5SDimitry Andric           ES.reportError(SymName.takeError());
165e8d8bef9SDimitry Andric           R->failMaterialization();
1660b57cec5SDimitry Andric           return;
1670b57cec5SDimitry Andric         }
1680b57cec5SDimitry Andric       }
1690b57cec5SDimitry Andric     }
170bdd1243dSDimitry Andric 
171bdd1243dSDimitry Andric     if (!ExtraSymbolsToClaim.empty()) {
172bdd1243dSDimitry Andric       if (auto Err = R->defineMaterializing(ExtraSymbolsToClaim)) {
173bdd1243dSDimitry Andric         ES.reportError(std::move(Err));
174bdd1243dSDimitry Andric         R->failMaterialization();
175bdd1243dSDimitry Andric       }
176bdd1243dSDimitry Andric     }
1770b57cec5SDimitry Andric   }
1780b57cec5SDimitry Andric 
179e8d8bef9SDimitry Andric   auto MemMgr = GetMemoryManager();
180e8d8bef9SDimitry Andric   auto &MemMgrRef = *MemMgr;
1810b57cec5SDimitry Andric 
182e8d8bef9SDimitry Andric   // Switch to shared ownership of MR so that it can be captured by both
183e8d8bef9SDimitry Andric   // lambdas below.
184e8d8bef9SDimitry Andric   std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
185*0fca6ea1SDimitry Andric   auto Deps = std::make_unique<SymbolDependenceMap>();
1860b57cec5SDimitry Andric 
187*0fca6ea1SDimitry Andric   JITDylibSearchOrderResolver Resolver(*SharedR, *Deps);
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   jitLinkForORC(
1905ffd83dbSDimitry Andric       object::OwningBinary<object::ObjectFile>(std::move(*Obj), std::move(O)),
191e8d8bef9SDimitry Andric       MemMgrRef, Resolver, ProcessAllSections,
192e8d8bef9SDimitry Andric       [this, SharedR, &MemMgrRef, InternalSymbols](
1935ffd83dbSDimitry Andric           const object::ObjectFile &Obj,
194e8d8bef9SDimitry Andric           RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
1950b57cec5SDimitry Andric           std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
196e8d8bef9SDimitry Andric         return onObjLoad(*SharedR, Obj, MemMgrRef, LoadedObjInfo,
1970b57cec5SDimitry Andric                          ResolvedSymbols, *InternalSymbols);
1980b57cec5SDimitry Andric       },
199*0fca6ea1SDimitry Andric       [this, SharedR, MemMgr = std::move(MemMgr), Deps = std::move(Deps)](
200e8d8bef9SDimitry Andric           object::OwningBinary<object::ObjectFile> Obj,
201e8d8bef9SDimitry Andric           std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
2025ffd83dbSDimitry Andric           Error Err) mutable {
203e8d8bef9SDimitry Andric         onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
204*0fca6ea1SDimitry Andric                   std::move(LoadedObjInfo), std::move(Deps), std::move(Err));
2050b57cec5SDimitry Andric       });
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
registerJITEventListener(JITEventListener & L)2085ffd83dbSDimitry Andric void RTDyldObjectLinkingLayer::registerJITEventListener(JITEventListener &L) {
2095ffd83dbSDimitry Andric   std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
210e8d8bef9SDimitry Andric   assert(!llvm::is_contained(EventListeners, &L) &&
2115ffd83dbSDimitry Andric          "Listener has already been registered");
2125ffd83dbSDimitry Andric   EventListeners.push_back(&L);
2135ffd83dbSDimitry Andric }
2145ffd83dbSDimitry Andric 
unregisterJITEventListener(JITEventListener & L)2155ffd83dbSDimitry Andric void RTDyldObjectLinkingLayer::unregisterJITEventListener(JITEventListener &L) {
2165ffd83dbSDimitry Andric   std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
2175ffd83dbSDimitry Andric   auto I = llvm::find(EventListeners, &L);
2185ffd83dbSDimitry Andric   assert(I != EventListeners.end() && "Listener not registered");
2195ffd83dbSDimitry Andric   EventListeners.erase(I);
2205ffd83dbSDimitry Andric }
2215ffd83dbSDimitry Andric 
onObjLoad(MaterializationResponsibility & R,const object::ObjectFile & Obj,RuntimeDyld::MemoryManager & MemMgr,RuntimeDyld::LoadedObjectInfo & LoadedObjInfo,std::map<StringRef,JITEvaluatedSymbol> Resolved,std::set<StringRef> & InternalSymbols)2220b57cec5SDimitry Andric Error RTDyldObjectLinkingLayer::onObjLoad(
223e8d8bef9SDimitry Andric     MaterializationResponsibility &R, const object::ObjectFile &Obj,
224e8d8bef9SDimitry Andric     RuntimeDyld::MemoryManager &MemMgr,
225e8d8bef9SDimitry Andric     RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
2260b57cec5SDimitry Andric     std::map<StringRef, JITEvaluatedSymbol> Resolved,
2270b57cec5SDimitry Andric     std::set<StringRef> &InternalSymbols) {
2280b57cec5SDimitry Andric   SymbolFlagsMap ExtraSymbolsToClaim;
2290b57cec5SDimitry Andric   SymbolMap Symbols;
23013138422SDimitry Andric 
23113138422SDimitry Andric   // Hack to support COFF constant pool comdats introduced during compilation:
23213138422SDimitry Andric   // (See http://llvm.org/PR40074)
23313138422SDimitry Andric   if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) {
23413138422SDimitry Andric     auto &ES = getExecutionSession();
23513138422SDimitry Andric 
2365f757f3fSDimitry Andric     // For all resolved symbols that are not already in the responsibility set:
23713138422SDimitry Andric     // check whether the symbol is in a comdat section and if so mark it as
23813138422SDimitry Andric     // weak.
23913138422SDimitry Andric     for (auto &Sym : COFFObj->symbols()) {
2405ffd83dbSDimitry Andric       // getFlags() on COFF symbols can't fail.
2415ffd83dbSDimitry Andric       uint32_t SymFlags = cantFail(Sym.getFlags());
2425ffd83dbSDimitry Andric       if (SymFlags & object::BasicSymbolRef::SF_Undefined)
24313138422SDimitry Andric         continue;
24413138422SDimitry Andric       auto Name = Sym.getName();
24513138422SDimitry Andric       if (!Name)
24613138422SDimitry Andric         return Name.takeError();
24713138422SDimitry Andric       auto I = Resolved.find(*Name);
24813138422SDimitry Andric 
24913138422SDimitry Andric       // Skip unresolved symbols, internal symbols, and symbols that are
25013138422SDimitry Andric       // already in the responsibility set.
25113138422SDimitry Andric       if (I == Resolved.end() || InternalSymbols.count(*Name) ||
25213138422SDimitry Andric           R.getSymbols().count(ES.intern(*Name)))
25313138422SDimitry Andric         continue;
25413138422SDimitry Andric       auto Sec = Sym.getSection();
25513138422SDimitry Andric       if (!Sec)
25613138422SDimitry Andric         return Sec.takeError();
25713138422SDimitry Andric       if (*Sec == COFFObj->section_end())
25813138422SDimitry Andric         continue;
25913138422SDimitry Andric       auto &COFFSec = *COFFObj->getCOFFSection(**Sec);
26013138422SDimitry Andric       if (COFFSec.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
26113138422SDimitry Andric         I->second.setFlags(I->second.getFlags() | JITSymbolFlags::Weak);
26213138422SDimitry Andric     }
263bdd1243dSDimitry Andric 
264bdd1243dSDimitry Andric     // Handle any aliases.
265bdd1243dSDimitry Andric     for (auto &Sym : COFFObj->symbols()) {
266bdd1243dSDimitry Andric       uint32_t SymFlags = cantFail(Sym.getFlags());
267bdd1243dSDimitry Andric       if (SymFlags & object::BasicSymbolRef::SF_Undefined)
268bdd1243dSDimitry Andric         continue;
269bdd1243dSDimitry Andric       auto Name = Sym.getName();
270bdd1243dSDimitry Andric       if (!Name)
271bdd1243dSDimitry Andric         return Name.takeError();
272bdd1243dSDimitry Andric       auto I = Resolved.find(*Name);
273bdd1243dSDimitry Andric 
274bdd1243dSDimitry Andric       // Skip already-resolved symbols, and symbols that we're not responsible
275bdd1243dSDimitry Andric       // for.
276bdd1243dSDimitry Andric       if (I != Resolved.end() || !R.getSymbols().count(ES.intern(*Name)))
277bdd1243dSDimitry Andric         continue;
278bdd1243dSDimitry Andric 
279bdd1243dSDimitry Andric       // Skip anything other than weak externals.
280bdd1243dSDimitry Andric       auto COFFSym = COFFObj->getCOFFSymbol(Sym);
281bdd1243dSDimitry Andric       if (!COFFSym.isWeakExternal())
282bdd1243dSDimitry Andric         continue;
283bdd1243dSDimitry Andric       auto *WeakExternal = COFFSym.getAux<object::coff_aux_weak_external>();
284bdd1243dSDimitry Andric       if (WeakExternal->Characteristics != COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS)
285bdd1243dSDimitry Andric         continue;
286bdd1243dSDimitry Andric 
287bdd1243dSDimitry Andric       // We found an alias. Reuse the resolution of the alias target for the
288bdd1243dSDimitry Andric       // alias itself.
289bdd1243dSDimitry Andric       Expected<object::COFFSymbolRef> TargetSymbol =
290bdd1243dSDimitry Andric           COFFObj->getSymbol(WeakExternal->TagIndex);
291bdd1243dSDimitry Andric       if (!TargetSymbol)
292bdd1243dSDimitry Andric         return TargetSymbol.takeError();
293bdd1243dSDimitry Andric       Expected<StringRef> TargetName = COFFObj->getSymbolName(*TargetSymbol);
294bdd1243dSDimitry Andric       if (!TargetName)
295bdd1243dSDimitry Andric         return TargetName.takeError();
296bdd1243dSDimitry Andric       auto J = Resolved.find(*TargetName);
297bdd1243dSDimitry Andric       if (J == Resolved.end())
298bdd1243dSDimitry Andric         return make_error<StringError>("Could alias target " + *TargetName +
299bdd1243dSDimitry Andric                                            " not resolved",
300bdd1243dSDimitry Andric                                        inconvertibleErrorCode());
301bdd1243dSDimitry Andric       Resolved[*Name] = J->second;
302bdd1243dSDimitry Andric     }
30313138422SDimitry Andric   }
30413138422SDimitry Andric 
3050b57cec5SDimitry Andric   for (auto &KV : Resolved) {
3060b57cec5SDimitry Andric     // Scan the symbols and add them to the Symbols map for resolution.
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric     // We never claim internal symbols.
3090b57cec5SDimitry Andric     if (InternalSymbols.count(KV.first))
3100b57cec5SDimitry Andric       continue;
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric     auto InternedName = getExecutionSession().intern(KV.first);
3130b57cec5SDimitry Andric     auto Flags = KV.second.getFlags();
314bdd1243dSDimitry Andric     auto I = R.getSymbols().find(InternedName);
315bdd1243dSDimitry Andric     if (I != R.getSymbols().end()) {
3160b57cec5SDimitry Andric       // Override object flags and claim responsibility for symbols if
3170b57cec5SDimitry Andric       // requested.
318bdd1243dSDimitry Andric       if (OverrideObjectFlags)
3190b57cec5SDimitry Andric         Flags = I->second;
320bdd1243dSDimitry Andric       else {
321bdd1243dSDimitry Andric         // RuntimeDyld/MCJIT's weak tracking isn't compatible with ORC's. Even
322bdd1243dSDimitry Andric         // if we're not overriding flags in general we should set the weak flag
323bdd1243dSDimitry Andric         // according to the MaterializationResponsibility object symbol table.
324bdd1243dSDimitry Andric         if (I->second.isWeak())
325bdd1243dSDimitry Andric           Flags |= JITSymbolFlags::Weak;
3260b57cec5SDimitry Andric       }
327bdd1243dSDimitry Andric     } else if (AutoClaimObjectSymbols)
328bdd1243dSDimitry Andric       ExtraSymbolsToClaim[InternedName] = Flags;
3290b57cec5SDimitry Andric 
33006c3fb27SDimitry Andric     Symbols[InternedName] = {ExecutorAddr(KV.second.getAddress()), Flags};
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric 
33313138422SDimitry Andric   if (!ExtraSymbolsToClaim.empty()) {
3340b57cec5SDimitry Andric     if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim))
3350b57cec5SDimitry Andric       return Err;
3360b57cec5SDimitry Andric 
33713138422SDimitry Andric     // If we claimed responsibility for any weak symbols but were rejected then
33813138422SDimitry Andric     // we need to remove them from the resolved set.
33913138422SDimitry Andric     for (auto &KV : ExtraSymbolsToClaim)
34013138422SDimitry Andric       if (KV.second.isWeak() && !R.getSymbols().count(KV.first))
34113138422SDimitry Andric         Symbols.erase(KV.first);
34213138422SDimitry Andric   }
34313138422SDimitry Andric 
3448bcb0991SDimitry Andric   if (auto Err = R.notifyResolved(Symbols)) {
3458bcb0991SDimitry Andric     R.failMaterialization();
3468bcb0991SDimitry Andric     return Err;
3478bcb0991SDimitry Andric   }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   if (NotifyLoaded)
350e8d8bef9SDimitry Andric     NotifyLoaded(R, Obj, LoadedObjInfo);
3515ffd83dbSDimitry Andric 
3520b57cec5SDimitry Andric   return Error::success();
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
onObjEmit(MaterializationResponsibility & R,object::OwningBinary<object::ObjectFile> O,std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,std::unique_ptr<SymbolDependenceMap> Deps,Error Err)3550b57cec5SDimitry Andric void RTDyldObjectLinkingLayer::onObjEmit(
356e8d8bef9SDimitry Andric     MaterializationResponsibility &R,
3575ffd83dbSDimitry Andric     object::OwningBinary<object::ObjectFile> O,
358e8d8bef9SDimitry Andric     std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
359*0fca6ea1SDimitry Andric     std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
360*0fca6ea1SDimitry Andric     std::unique_ptr<SymbolDependenceMap> Deps, Error Err) {
3610b57cec5SDimitry Andric   if (Err) {
3620b57cec5SDimitry Andric     getExecutionSession().reportError(std::move(Err));
3630b57cec5SDimitry Andric     R.failMaterialization();
3640b57cec5SDimitry Andric     return;
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
367*0fca6ea1SDimitry Andric   SymbolDependenceGroup SDG;
368*0fca6ea1SDimitry Andric   for (auto &[Sym, Flags] : R.getSymbols())
369*0fca6ea1SDimitry Andric     SDG.Symbols.insert(Sym);
370*0fca6ea1SDimitry Andric   SDG.Dependencies = std::move(*Deps);
371*0fca6ea1SDimitry Andric 
372*0fca6ea1SDimitry Andric   if (auto Err = R.notifyEmitted(SDG)) {
3738bcb0991SDimitry Andric     getExecutionSession().reportError(std::move(Err));
3748bcb0991SDimitry Andric     R.failMaterialization();
3758bcb0991SDimitry Andric     return;
3768bcb0991SDimitry Andric   }
3770b57cec5SDimitry Andric 
3785ffd83dbSDimitry Andric   std::unique_ptr<object::ObjectFile> Obj;
3795ffd83dbSDimitry Andric   std::unique_ptr<MemoryBuffer> ObjBuffer;
3805ffd83dbSDimitry Andric   std::tie(Obj, ObjBuffer) = O.takeBinary();
3815ffd83dbSDimitry Andric 
3825ffd83dbSDimitry Andric   // Run EventListener notifyLoaded callbacks.
3835ffd83dbSDimitry Andric   {
3845ffd83dbSDimitry Andric     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
3855ffd83dbSDimitry Andric     for (auto *L : EventListeners)
386e8d8bef9SDimitry Andric       L->notifyObjectLoaded(pointerToJITTargetAddress(MemMgr.get()), *Obj,
387e8d8bef9SDimitry Andric                             *LoadedObjInfo);
3885ffd83dbSDimitry Andric   }
3895ffd83dbSDimitry Andric 
3900b57cec5SDimitry Andric   if (NotifyEmitted)
391e8d8bef9SDimitry Andric     NotifyEmitted(R, std::move(ObjBuffer));
392e8d8bef9SDimitry Andric 
393e8d8bef9SDimitry Andric   if (auto Err = R.withResourceKeyDo(
394e8d8bef9SDimitry Andric           [&](ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
395e8d8bef9SDimitry Andric     getExecutionSession().reportError(std::move(Err));
396e8d8bef9SDimitry Andric     R.failMaterialization();
397e8d8bef9SDimitry Andric   }
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric 
handleRemoveResources(JITDylib & JD,ResourceKey K)400bdd1243dSDimitry Andric Error RTDyldObjectLinkingLayer::handleRemoveResources(JITDylib &JD,
401bdd1243dSDimitry Andric                                                       ResourceKey K) {
402e8d8bef9SDimitry Andric 
403e8d8bef9SDimitry Andric   std::vector<MemoryManagerUP> MemMgrsToRemove;
404e8d8bef9SDimitry Andric 
405e8d8bef9SDimitry Andric   getExecutionSession().runSessionLocked([&] {
406e8d8bef9SDimitry Andric     auto I = MemMgrs.find(K);
407e8d8bef9SDimitry Andric     if (I != MemMgrs.end()) {
408e8d8bef9SDimitry Andric       std::swap(MemMgrsToRemove, I->second);
409e8d8bef9SDimitry Andric       MemMgrs.erase(I);
410e8d8bef9SDimitry Andric     }
411e8d8bef9SDimitry Andric   });
412e8d8bef9SDimitry Andric 
413e8d8bef9SDimitry Andric   {
414e8d8bef9SDimitry Andric     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
415e8d8bef9SDimitry Andric     for (auto &MemMgr : MemMgrsToRemove) {
416e8d8bef9SDimitry Andric       for (auto *L : EventListeners)
417e8d8bef9SDimitry Andric         L->notifyFreeingObject(pointerToJITTargetAddress(MemMgr.get()));
418e8d8bef9SDimitry Andric       MemMgr->deregisterEHFrames();
419e8d8bef9SDimitry Andric     }
420e8d8bef9SDimitry Andric   }
421e8d8bef9SDimitry Andric 
422e8d8bef9SDimitry Andric   return Error::success();
423e8d8bef9SDimitry Andric }
424e8d8bef9SDimitry Andric 
handleTransferResources(JITDylib & JD,ResourceKey DstKey,ResourceKey SrcKey)425bdd1243dSDimitry Andric void RTDyldObjectLinkingLayer::handleTransferResources(JITDylib &JD,
426bdd1243dSDimitry Andric                                                        ResourceKey DstKey,
427e8d8bef9SDimitry Andric                                                        ResourceKey SrcKey) {
428e8d8bef9SDimitry Andric   auto I = MemMgrs.find(SrcKey);
429e8d8bef9SDimitry Andric   if (I != MemMgrs.end()) {
430e8d8bef9SDimitry Andric     auto &SrcMemMgrs = I->second;
431e8d8bef9SDimitry Andric     auto &DstMemMgrs = MemMgrs[DstKey];
432e8d8bef9SDimitry Andric     DstMemMgrs.reserve(DstMemMgrs.size() + SrcMemMgrs.size());
433e8d8bef9SDimitry Andric     for (auto &MemMgr : SrcMemMgrs)
434e8d8bef9SDimitry Andric       DstMemMgrs.push_back(std::move(MemMgr));
435e8d8bef9SDimitry Andric 
436e8d8bef9SDimitry Andric     // Erase SrcKey entry using value rather than iterator I: I may have been
437e8d8bef9SDimitry Andric     // invalidated when we looked up DstKey.
438e8d8bef9SDimitry Andric     MemMgrs.erase(SrcKey);
439e8d8bef9SDimitry Andric   }
440e8d8bef9SDimitry Andric }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric } // End namespace orc.
4430b57cec5SDimitry Andric } // End namespace llvm.
444