10b57cec5SDimitry Andric //===------- ObjectLinkingLayer.cpp - JITLink 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/ObjectLinkingLayer.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 120b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include <vector> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define DEBUG_TYPE "orc" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace llvm; 190b57cec5SDimitry Andric using namespace llvm::jitlink; 200b57cec5SDimitry Andric using namespace llvm::orc; 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace llvm { 230b57cec5SDimitry Andric namespace orc { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, 280b57cec5SDimitry Andric MaterializationResponsibility MR, 290b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ObjBuffer) 300b57cec5SDimitry Andric : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} 310b57cec5SDimitry Andric 32*8bcb0991SDimitry Andric ~ObjectLinkingLayerJITLinkContext() { 33*8bcb0991SDimitry Andric // If there is an object buffer return function then use it to 34*8bcb0991SDimitry Andric // return ownership of the buffer. 35*8bcb0991SDimitry Andric if (Layer.ReturnObjectBuffer) 36*8bcb0991SDimitry Andric Layer.ReturnObjectBuffer(std::move(ObjBuffer)); 37*8bcb0991SDimitry Andric } 38*8bcb0991SDimitry Andric 390b57cec5SDimitry Andric JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric MemoryBufferRef getObjectBuffer() const override { 420b57cec5SDimitry Andric return ObjBuffer->getMemBufferRef(); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void notifyFailed(Error Err) override { 460b57cec5SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 470b57cec5SDimitry Andric MR.failMaterialization(); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void lookup(const DenseSet<StringRef> &Symbols, 51*8bcb0991SDimitry Andric std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric JITDylibSearchList SearchOrder; 540b57cec5SDimitry Andric MR.getTargetJITDylib().withSearchOrderDo( 550b57cec5SDimitry Andric [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; }); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric SymbolNameSet InternedSymbols; 600b57cec5SDimitry Andric for (auto &S : Symbols) 610b57cec5SDimitry Andric InternedSymbols.insert(ES.intern(S)); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // OnResolve -- De-intern the symbols and pass the result to the linker. 64*8bcb0991SDimitry Andric auto OnResolve = [this, LookupContinuation = std::move(LC)]( 65*8bcb0991SDimitry Andric Expected<SymbolMap> Result) mutable { 66*8bcb0991SDimitry Andric auto Main = Layer.getExecutionSession().intern("_main"); 670b57cec5SDimitry Andric if (!Result) 68*8bcb0991SDimitry Andric LookupContinuation->run(Result.takeError()); 690b57cec5SDimitry Andric else { 700b57cec5SDimitry Andric AsyncLookupResult LR; 710b57cec5SDimitry Andric for (auto &KV : *Result) 720b57cec5SDimitry Andric LR[*KV.first] = KV.second; 73*8bcb0991SDimitry Andric LookupContinuation->run(std::move(LR)); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric }; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved, 780b57cec5SDimitry Andric std::move(OnResolve), [this](const SymbolDependenceMap &Deps) { 790b57cec5SDimitry Andric registerDependencies(Deps); 800b57cec5SDimitry Andric }); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 83*8bcb0991SDimitry Andric void notifyResolved(LinkGraph &G) override { 840b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric SymbolFlagsMap ExtraSymbolsToClaim; 870b57cec5SDimitry Andric bool AutoClaim = Layer.AutoClaimObjectSymbols; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric SymbolMap InternedResult; 90*8bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 91*8bcb0991SDimitry Andric if (Sym->hasName() && Sym->getScope() != Scope::Local) { 92*8bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 930b57cec5SDimitry Andric JITSymbolFlags Flags; 940b57cec5SDimitry Andric 95*8bcb0991SDimitry Andric if (Sym->isCallable()) 960b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 97*8bcb0991SDimitry Andric if (Sym->getScope() == Scope::Default) 98*8bcb0991SDimitry Andric Flags |= JITSymbolFlags::Exported; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric InternedResult[InternedName] = 101*8bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1020b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1030b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1040b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1050b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 109*8bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 110*8bcb0991SDimitry Andric if (Sym->hasName()) { 111*8bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 1120b57cec5SDimitry Andric JITSymbolFlags Flags; 1130b57cec5SDimitry Andric Flags |= JITSymbolFlags::Absolute; 114*8bcb0991SDimitry Andric if (Sym->isCallable()) 1150b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 116*8bcb0991SDimitry Andric if (Sym->getLinkage() == Linkage::Weak) 117*8bcb0991SDimitry Andric Flags |= JITSymbolFlags::Weak; 1180b57cec5SDimitry Andric InternedResult[InternedName] = 119*8bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1200b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1210b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1220b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1230b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric if (!ExtraSymbolsToClaim.empty()) 1280b57cec5SDimitry Andric if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) 1290b57cec5SDimitry Andric return notifyFailed(std::move(Err)); 130*8bcb0991SDimitry Andric if (auto Err = MR.notifyResolved(InternedResult)) { 131*8bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 132*8bcb0991SDimitry Andric MR.failMaterialization(); 133*8bcb0991SDimitry Andric return; 134*8bcb0991SDimitry Andric } 1350b57cec5SDimitry Andric Layer.notifyLoaded(MR); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric void notifyFinalized( 1390b57cec5SDimitry Andric std::unique_ptr<JITLinkMemoryManager::Allocation> A) override { 1400b57cec5SDimitry Andric if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { 1410b57cec5SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 1420b57cec5SDimitry Andric MR.failMaterialization(); 1430b57cec5SDimitry Andric return; 1440b57cec5SDimitry Andric } 145*8bcb0991SDimitry Andric if (auto Err = MR.notifyEmitted()) { 146*8bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 147*8bcb0991SDimitry Andric MR.failMaterialization(); 148*8bcb0991SDimitry Andric } 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 151*8bcb0991SDimitry Andric LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override { 152*8bcb0991SDimitry Andric return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); }; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { 1560b57cec5SDimitry Andric // Add passes to mark duplicate defs as should-discard, and to walk the 157*8bcb0991SDimitry Andric // link graph to build the symbol dependence graph. 1580b57cec5SDimitry Andric Config.PrePrunePasses.push_back( 159*8bcb0991SDimitry Andric [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); 1600b57cec5SDimitry Andric Config.PostPrunePasses.push_back( 161*8bcb0991SDimitry Andric [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric Layer.modifyPassConfig(MR, TT, Config); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric return Error::success(); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric private: 169*8bcb0991SDimitry Andric using AnonToNamedDependenciesMap = DenseMap<const Symbol *, SymbolNameSet>; 1700b57cec5SDimitry Andric 171*8bcb0991SDimitry Andric Error externalizeWeakAndCommonSymbols(LinkGraph &G) { 1720b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 173*8bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 174*8bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 175*8bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 176*8bcb0991SDimitry Andric G.makeExternal(*Sym); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 179*8bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 180*8bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 181*8bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 182*8bcb0991SDimitry Andric G.makeExternal(*Sym); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric return Error::success(); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 188*8bcb0991SDimitry Andric Error markResponsibilitySymbolsLive(LinkGraph &G) const { 1890b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 190*8bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 191*8bcb0991SDimitry Andric if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) 192*8bcb0991SDimitry Andric Sym->setLive(true); 1930b57cec5SDimitry Andric return Error::success(); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 196*8bcb0991SDimitry Andric Error computeNamedSymbolDependencies(LinkGraph &G) { 1970b57cec5SDimitry Andric auto &ES = MR.getTargetJITDylib().getExecutionSession(); 1980b57cec5SDimitry Andric auto AnonDeps = computeAnonDeps(G); 1990b57cec5SDimitry Andric 200*8bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) { 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric // Skip anonymous and non-global atoms: we do not need dependencies for 2030b57cec5SDimitry Andric // these. 204*8bcb0991SDimitry Andric if (Sym->getScope() == Scope::Local) 2050b57cec5SDimitry Andric continue; 2060b57cec5SDimitry Andric 207*8bcb0991SDimitry Andric auto SymName = ES.intern(Sym->getName()); 208*8bcb0991SDimitry Andric SymbolNameSet &SymDeps = NamedSymbolDeps[SymName]; 2090b57cec5SDimitry Andric 210*8bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 211*8bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 2120b57cec5SDimitry Andric 213*8bcb0991SDimitry Andric if (TargetSym.getScope() != Scope::Local) 214*8bcb0991SDimitry Andric SymDeps.insert(ES.intern(TargetSym.getName())); 2150b57cec5SDimitry Andric else { 216*8bcb0991SDimitry Andric assert(TargetSym.isDefined() && 217*8bcb0991SDimitry Andric "Anonymous/local symbols must be defined"); 218*8bcb0991SDimitry Andric auto I = AnonDeps.find(&TargetSym); 2190b57cec5SDimitry Andric if (I != AnonDeps.end()) 2200b57cec5SDimitry Andric for (auto &S : I->second) 221*8bcb0991SDimitry Andric SymDeps.insert(S); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric return Error::success(); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 229*8bcb0991SDimitry Andric AnonToNamedDependenciesMap computeAnonDeps(LinkGraph &G) { 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric auto &ES = MR.getTargetJITDylib().getExecutionSession(); 232*8bcb0991SDimitry Andric AnonToNamedDependenciesMap DepMap; 2330b57cec5SDimitry Andric 234*8bcb0991SDimitry Andric // For all anonymous symbols: 2350b57cec5SDimitry Andric // (1) Add their named dependencies. 2360b57cec5SDimitry Andric // (2) Add them to the worklist for further iteration if they have any 237*8bcb0991SDimitry Andric // depend on any other anonymous symbols. 2380b57cec5SDimitry Andric struct WorklistEntry { 239*8bcb0991SDimitry Andric WorklistEntry(Symbol *Sym, DenseSet<Symbol *> SymAnonDeps) 240*8bcb0991SDimitry Andric : Sym(Sym), SymAnonDeps(std::move(SymAnonDeps)) {} 2410b57cec5SDimitry Andric 242*8bcb0991SDimitry Andric Symbol *Sym = nullptr; 243*8bcb0991SDimitry Andric DenseSet<Symbol *> SymAnonDeps; 2440b57cec5SDimitry Andric }; 2450b57cec5SDimitry Andric std::vector<WorklistEntry> Worklist; 246*8bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 247*8bcb0991SDimitry Andric if (!Sym->hasName()) { 248*8bcb0991SDimitry Andric auto &SymNamedDeps = DepMap[Sym]; 249*8bcb0991SDimitry Andric DenseSet<Symbol *> SymAnonDeps; 2500b57cec5SDimitry Andric 251*8bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 252*8bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 253*8bcb0991SDimitry Andric if (TargetSym.hasName()) 254*8bcb0991SDimitry Andric SymNamedDeps.insert(ES.intern(TargetSym.getName())); 2550b57cec5SDimitry Andric else { 256*8bcb0991SDimitry Andric assert(TargetSym.isDefined() && 257*8bcb0991SDimitry Andric "Anonymous symbols must be defined"); 258*8bcb0991SDimitry Andric SymAnonDeps.insert(&TargetSym); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 262*8bcb0991SDimitry Andric if (!SymAnonDeps.empty()) 263*8bcb0991SDimitry Andric Worklist.push_back(WorklistEntry(Sym, std::move(SymAnonDeps))); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 266*8bcb0991SDimitry Andric // Loop over all anonymous symbols with anonymous dependencies, propagating 2670b57cec5SDimitry Andric // their respective *named* dependencies. Iterate until we hit a stable 2680b57cec5SDimitry Andric // state. 2690b57cec5SDimitry Andric bool Changed; 2700b57cec5SDimitry Andric do { 2710b57cec5SDimitry Andric Changed = false; 2720b57cec5SDimitry Andric for (auto &WLEntry : Worklist) { 273*8bcb0991SDimitry Andric auto *Sym = WLEntry.Sym; 274*8bcb0991SDimitry Andric auto &SymNamedDeps = DepMap[Sym]; 275*8bcb0991SDimitry Andric auto &SymAnonDeps = WLEntry.SymAnonDeps; 2760b57cec5SDimitry Andric 277*8bcb0991SDimitry Andric for (auto *TargetSym : SymAnonDeps) { 278*8bcb0991SDimitry Andric auto I = DepMap.find(TargetSym); 2790b57cec5SDimitry Andric if (I != DepMap.end()) 2800b57cec5SDimitry Andric for (const auto &S : I->second) 281*8bcb0991SDimitry Andric Changed |= SymNamedDeps.insert(S).second; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric } while (Changed); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric return DepMap; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric void registerDependencies(const SymbolDependenceMap &QueryDeps) { 2900b57cec5SDimitry Andric for (auto &NamedDepsEntry : NamedSymbolDeps) { 2910b57cec5SDimitry Andric auto &Name = NamedDepsEntry.first; 2920b57cec5SDimitry Andric auto &NameDeps = NamedDepsEntry.second; 2930b57cec5SDimitry Andric SymbolDependenceMap SymbolDeps; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric for (const auto &QueryDepsEntry : QueryDeps) { 2960b57cec5SDimitry Andric JITDylib &SourceJD = *QueryDepsEntry.first; 2970b57cec5SDimitry Andric const SymbolNameSet &Symbols = QueryDepsEntry.second; 2980b57cec5SDimitry Andric auto &DepsForJD = SymbolDeps[&SourceJD]; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric for (const auto &S : Symbols) 3010b57cec5SDimitry Andric if (NameDeps.count(S)) 3020b57cec5SDimitry Andric DepsForJD.insert(S); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric if (DepsForJD.empty()) 3050b57cec5SDimitry Andric SymbolDeps.erase(&SourceJD); 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric MR.addDependencies(Name, SymbolDeps); 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric ObjectLinkingLayer &Layer; 3130b57cec5SDimitry Andric MaterializationResponsibility MR; 3140b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ObjBuffer; 3150b57cec5SDimitry Andric DenseMap<SymbolStringPtr, SymbolNameSet> NamedSymbolDeps; 3160b57cec5SDimitry Andric }; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric ObjectLinkingLayer::Plugin::~Plugin() {} 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES, 3210b57cec5SDimitry Andric JITLinkMemoryManager &MemMgr) 3220b57cec5SDimitry Andric : ObjectLayer(ES), MemMgr(MemMgr) {} 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric ObjectLinkingLayer::~ObjectLinkingLayer() { 3250b57cec5SDimitry Andric if (auto Err = removeAllModules()) 3260b57cec5SDimitry Andric getExecutionSession().reportError(std::move(Err)); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric void ObjectLinkingLayer::emit(MaterializationResponsibility R, 3300b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> O) { 3310b57cec5SDimitry Andric assert(O && "Object must not be null"); 332*8bcb0991SDimitry Andric jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>( 3330b57cec5SDimitry Andric *this, std::move(R), std::move(O))); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR, 3370b57cec5SDimitry Andric const Triple &TT, 3380b57cec5SDimitry Andric PassConfiguration &PassConfig) { 3390b57cec5SDimitry Andric for (auto &P : Plugins) 3400b57cec5SDimitry Andric P->modifyPassConfig(MR, TT, PassConfig); 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) { 3440b57cec5SDimitry Andric for (auto &P : Plugins) 3450b57cec5SDimitry Andric P->notifyLoaded(MR); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR, 3490b57cec5SDimitry Andric AllocPtr Alloc) { 3500b57cec5SDimitry Andric Error Err = Error::success(); 3510b57cec5SDimitry Andric for (auto &P : Plugins) 3520b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyEmitted(MR)); 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric if (Err) 3550b57cec5SDimitry Andric return Err; 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric { 3580b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 3590b57cec5SDimitry Andric UntrackedAllocs.push_back(std::move(Alloc)); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric return Error::success(); 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric Error ObjectLinkingLayer::removeModule(VModuleKey K) { 3660b57cec5SDimitry Andric Error Err = Error::success(); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric for (auto &P : Plugins) 3690b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingModule(K)); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric AllocPtr Alloc; 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric { 3740b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 3750b57cec5SDimitry Andric auto AllocItr = TrackedAllocs.find(K); 3760b57cec5SDimitry Andric Alloc = std::move(AllocItr->second); 3770b57cec5SDimitry Andric TrackedAllocs.erase(AllocItr); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric assert(Alloc && "No allocation for key K"); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric return joinErrors(std::move(Err), Alloc->deallocate()); 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric Error ObjectLinkingLayer::removeAllModules() { 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric Error Err = Error::success(); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric for (auto &P : Plugins) 3900b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingAllModules()); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric std::vector<AllocPtr> Allocs; 3930b57cec5SDimitry Andric { 3940b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 3950b57cec5SDimitry Andric Allocs = std::move(UntrackedAllocs); 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric for (auto &KV : TrackedAllocs) 3980b57cec5SDimitry Andric Allocs.push_back(std::move(KV.second)); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric TrackedAllocs.clear(); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric while (!Allocs.empty()) { 4040b57cec5SDimitry Andric Err = joinErrors(std::move(Err), Allocs.back()->deallocate()); 4050b57cec5SDimitry Andric Allocs.pop_back(); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric return Err; 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( 412*8bcb0991SDimitry Andric EHFrameRegistrar &Registrar) 4130b57cec5SDimitry Andric : Registrar(Registrar) {} 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric void EHFrameRegistrationPlugin::modifyPassConfig( 4160b57cec5SDimitry Andric MaterializationResponsibility &MR, const Triple &TT, 4170b57cec5SDimitry Andric PassConfiguration &PassConfig) { 4180b57cec5SDimitry Andric assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?"); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric PassConfig.PostFixupPasses.push_back( 421*8bcb0991SDimitry Andric createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr, 422*8bcb0991SDimitry Andric size_t Size) { 4230b57cec5SDimitry Andric if (Addr) 424*8bcb0991SDimitry Andric InProcessLinks[&MR] = { Addr, Size }; 4250b57cec5SDimitry Andric })); 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyEmitted( 4290b57cec5SDimitry Andric MaterializationResponsibility &MR) { 4300b57cec5SDimitry Andric 431*8bcb0991SDimitry Andric auto EHFrameRangeItr = InProcessLinks.find(&MR); 432*8bcb0991SDimitry Andric if (EHFrameRangeItr == InProcessLinks.end()) 4330b57cec5SDimitry Andric return Error::success(); 4340b57cec5SDimitry Andric 435*8bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 436*8bcb0991SDimitry Andric assert(EHFrameRange.Addr && 437*8bcb0991SDimitry Andric "eh-frame addr to register can not be null"); 4380b57cec5SDimitry Andric 439*8bcb0991SDimitry Andric InProcessLinks.erase(EHFrameRangeItr); 4400b57cec5SDimitry Andric if (auto Key = MR.getVModuleKey()) 441*8bcb0991SDimitry Andric TrackedEHFrameRanges[Key] = EHFrameRange; 4420b57cec5SDimitry Andric else 443*8bcb0991SDimitry Andric UntrackedEHFrameRanges.push_back(EHFrameRange); 4440b57cec5SDimitry Andric 445*8bcb0991SDimitry Andric return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { 449*8bcb0991SDimitry Andric auto EHFrameRangeItr = TrackedEHFrameRanges.find(K); 450*8bcb0991SDimitry Andric if (EHFrameRangeItr == TrackedEHFrameRanges.end()) 4510b57cec5SDimitry Andric return Error::success(); 4520b57cec5SDimitry Andric 453*8bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 454*8bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null"); 4550b57cec5SDimitry Andric 456*8bcb0991SDimitry Andric TrackedEHFrameRanges.erase(EHFrameRangeItr); 4570b57cec5SDimitry Andric 458*8bcb0991SDimitry Andric return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { 4620b57cec5SDimitry Andric 463*8bcb0991SDimitry Andric std::vector<EHFrameRange> EHFrameRanges = 464*8bcb0991SDimitry Andric std::move(UntrackedEHFrameRanges); 465*8bcb0991SDimitry Andric EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size()); 4660b57cec5SDimitry Andric 467*8bcb0991SDimitry Andric for (auto &KV : TrackedEHFrameRanges) 468*8bcb0991SDimitry Andric EHFrameRanges.push_back(KV.second); 4690b57cec5SDimitry Andric 470*8bcb0991SDimitry Andric TrackedEHFrameRanges.clear(); 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric Error Err = Error::success(); 4730b57cec5SDimitry Andric 474*8bcb0991SDimitry Andric while (!EHFrameRanges.empty()) { 475*8bcb0991SDimitry Andric auto EHFrameRange = EHFrameRanges.back(); 476*8bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null"); 477*8bcb0991SDimitry Andric EHFrameRanges.pop_back(); 478*8bcb0991SDimitry Andric Err = joinErrors(std::move(Err), 479*8bcb0991SDimitry Andric Registrar.deregisterEHFrames(EHFrameRange.Addr, 480*8bcb0991SDimitry Andric EHFrameRange.Size)); 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric return Err; 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric } // End namespace orc. 4870b57cec5SDimitry Andric } // End namespace llvm. 488