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: 19*0fca6ea1SDimitry Andric JITDylibSearchOrderResolver(MaterializationResponsibility &MR, 20*0fca6ea1SDimitry Andric SymbolDependenceMap &Deps) 21*0fca6ea1SDimitry Andric : MR(MR), Deps(Deps) {} 220b57cec5SDimitry Andric 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 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 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 88480093f4SDimitry Andric RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { 89e8d8bef9SDimitry Andric assert(MemMgrs.empty() && "Layer destroyed with resources still attached"); 905ffd83dbSDimitry Andric } 91480093f4SDimitry Andric 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 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 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 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 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 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 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