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