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 328bcb0991SDimitry Andric ~ObjectLinkingLayerJITLinkContext() { 338bcb0991SDimitry Andric // If there is an object buffer return function then use it to 348bcb0991SDimitry Andric // return ownership of the buffer. 358bcb0991SDimitry Andric if (Layer.ReturnObjectBuffer) 368bcb0991SDimitry Andric Layer.ReturnObjectBuffer(std::move(ObjBuffer)); 378bcb0991SDimitry Andric } 388bcb0991SDimitry Andric 39*480093f4SDimitry 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 50*480093f4SDimitry Andric void lookup(const LookupMap &Symbols, 518bcb0991SDimitry Andric std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { 520b57cec5SDimitry Andric 53*480093f4SDimitry Andric JITDylibSearchOrder SearchOrder; 540b57cec5SDimitry Andric MR.getTargetJITDylib().withSearchOrderDo( 55*480093f4SDimitry Andric [&](const JITDylibSearchOrder &O) { SearchOrder = O; }); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 580b57cec5SDimitry Andric 59*480093f4SDimitry Andric SymbolLookupSet LookupSet; 60*480093f4SDimitry Andric for (auto &KV : Symbols) { 61*480093f4SDimitry Andric orc::SymbolLookupFlags LookupFlags; 62*480093f4SDimitry Andric switch (KV.second) { 63*480093f4SDimitry Andric case jitlink::SymbolLookupFlags::RequiredSymbol: 64*480093f4SDimitry Andric LookupFlags = orc::SymbolLookupFlags::RequiredSymbol; 65*480093f4SDimitry Andric break; 66*480093f4SDimitry Andric case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol: 67*480093f4SDimitry Andric LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol; 68*480093f4SDimitry Andric break; 69*480093f4SDimitry Andric } 70*480093f4SDimitry Andric LookupSet.add(ES.intern(KV.first), LookupFlags); 71*480093f4SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric // OnResolve -- De-intern the symbols and pass the result to the linker. 748bcb0991SDimitry Andric auto OnResolve = [this, LookupContinuation = std::move(LC)]( 758bcb0991SDimitry Andric Expected<SymbolMap> Result) mutable { 768bcb0991SDimitry Andric auto Main = Layer.getExecutionSession().intern("_main"); 770b57cec5SDimitry Andric if (!Result) 788bcb0991SDimitry Andric LookupContinuation->run(Result.takeError()); 790b57cec5SDimitry Andric else { 800b57cec5SDimitry Andric AsyncLookupResult LR; 810b57cec5SDimitry Andric for (auto &KV : *Result) 820b57cec5SDimitry Andric LR[*KV.first] = KV.second; 838bcb0991SDimitry Andric LookupContinuation->run(std::move(LR)); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric }; 860b57cec5SDimitry Andric 87*480093f4SDimitry Andric ES.lookup(LookupKind::Static, SearchOrder, std::move(LookupSet), 88*480093f4SDimitry Andric SymbolState::Resolved, std::move(OnResolve), 89*480093f4SDimitry Andric [this](const SymbolDependenceMap &Deps) { 900b57cec5SDimitry Andric registerDependencies(Deps); 910b57cec5SDimitry Andric }); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 948bcb0991SDimitry Andric void notifyResolved(LinkGraph &G) override { 950b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric SymbolFlagsMap ExtraSymbolsToClaim; 980b57cec5SDimitry Andric bool AutoClaim = Layer.AutoClaimObjectSymbols; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric SymbolMap InternedResult; 1018bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 1028bcb0991SDimitry Andric if (Sym->hasName() && Sym->getScope() != Scope::Local) { 1038bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 1040b57cec5SDimitry Andric JITSymbolFlags Flags; 1050b57cec5SDimitry Andric 1068bcb0991SDimitry Andric if (Sym->isCallable()) 1070b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 1088bcb0991SDimitry Andric if (Sym->getScope() == Scope::Default) 1098bcb0991SDimitry Andric Flags |= JITSymbolFlags::Exported; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric InternedResult[InternedName] = 1128bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1130b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1140b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1150b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1160b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1208bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 1218bcb0991SDimitry Andric if (Sym->hasName()) { 1228bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 1230b57cec5SDimitry Andric JITSymbolFlags Flags; 1240b57cec5SDimitry Andric Flags |= JITSymbolFlags::Absolute; 1258bcb0991SDimitry Andric if (Sym->isCallable()) 1260b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 1278bcb0991SDimitry Andric if (Sym->getLinkage() == Linkage::Weak) 1288bcb0991SDimitry Andric Flags |= JITSymbolFlags::Weak; 1290b57cec5SDimitry Andric InternedResult[InternedName] = 1308bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1310b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1320b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1330b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1340b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric if (!ExtraSymbolsToClaim.empty()) 1390b57cec5SDimitry Andric if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) 1400b57cec5SDimitry Andric return notifyFailed(std::move(Err)); 1418bcb0991SDimitry Andric if (auto Err = MR.notifyResolved(InternedResult)) { 1428bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 1438bcb0991SDimitry Andric MR.failMaterialization(); 1448bcb0991SDimitry Andric return; 1458bcb0991SDimitry Andric } 1460b57cec5SDimitry Andric Layer.notifyLoaded(MR); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric void notifyFinalized( 1500b57cec5SDimitry Andric std::unique_ptr<JITLinkMemoryManager::Allocation> A) override { 1510b57cec5SDimitry Andric if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { 1520b57cec5SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 1530b57cec5SDimitry Andric MR.failMaterialization(); 1540b57cec5SDimitry Andric return; 1550b57cec5SDimitry Andric } 1568bcb0991SDimitry Andric if (auto Err = MR.notifyEmitted()) { 1578bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 1588bcb0991SDimitry Andric MR.failMaterialization(); 1598bcb0991SDimitry Andric } 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1628bcb0991SDimitry Andric LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override { 1638bcb0991SDimitry Andric return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); }; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { 1670b57cec5SDimitry Andric // Add passes to mark duplicate defs as should-discard, and to walk the 1688bcb0991SDimitry Andric // link graph to build the symbol dependence graph. 1690b57cec5SDimitry Andric Config.PrePrunePasses.push_back( 1708bcb0991SDimitry Andric [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); 1710b57cec5SDimitry Andric Config.PostPrunePasses.push_back( 1728bcb0991SDimitry Andric [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric Layer.modifyPassConfig(MR, TT, Config); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric return Error::success(); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric private: 1808bcb0991SDimitry Andric using AnonToNamedDependenciesMap = DenseMap<const Symbol *, SymbolNameSet>; 1810b57cec5SDimitry Andric 1828bcb0991SDimitry Andric Error externalizeWeakAndCommonSymbols(LinkGraph &G) { 1830b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 1848bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 1858bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 1868bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 1878bcb0991SDimitry Andric G.makeExternal(*Sym); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1908bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 1918bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 1928bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 1938bcb0991SDimitry Andric G.makeExternal(*Sym); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric return Error::success(); 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 1998bcb0991SDimitry Andric Error markResponsibilitySymbolsLive(LinkGraph &G) const { 2000b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 2018bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 2028bcb0991SDimitry Andric if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) 2038bcb0991SDimitry Andric Sym->setLive(true); 2040b57cec5SDimitry Andric return Error::success(); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2078bcb0991SDimitry Andric Error computeNamedSymbolDependencies(LinkGraph &G) { 2080b57cec5SDimitry Andric auto &ES = MR.getTargetJITDylib().getExecutionSession(); 2090b57cec5SDimitry Andric auto AnonDeps = computeAnonDeps(G); 2100b57cec5SDimitry Andric 2118bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) { 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // Skip anonymous and non-global atoms: we do not need dependencies for 2140b57cec5SDimitry Andric // these. 2158bcb0991SDimitry Andric if (Sym->getScope() == Scope::Local) 2160b57cec5SDimitry Andric continue; 2170b57cec5SDimitry Andric 2188bcb0991SDimitry Andric auto SymName = ES.intern(Sym->getName()); 2198bcb0991SDimitry Andric SymbolNameSet &SymDeps = NamedSymbolDeps[SymName]; 2200b57cec5SDimitry Andric 2218bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 2228bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 2230b57cec5SDimitry Andric 2248bcb0991SDimitry Andric if (TargetSym.getScope() != Scope::Local) 2258bcb0991SDimitry Andric SymDeps.insert(ES.intern(TargetSym.getName())); 2260b57cec5SDimitry Andric else { 2278bcb0991SDimitry Andric assert(TargetSym.isDefined() && 2288bcb0991SDimitry Andric "Anonymous/local symbols must be defined"); 2298bcb0991SDimitry Andric auto I = AnonDeps.find(&TargetSym); 2300b57cec5SDimitry Andric if (I != AnonDeps.end()) 2310b57cec5SDimitry Andric for (auto &S : I->second) 2328bcb0991SDimitry Andric SymDeps.insert(S); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric return Error::success(); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2408bcb0991SDimitry Andric AnonToNamedDependenciesMap computeAnonDeps(LinkGraph &G) { 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric auto &ES = MR.getTargetJITDylib().getExecutionSession(); 2438bcb0991SDimitry Andric AnonToNamedDependenciesMap DepMap; 2440b57cec5SDimitry Andric 2458bcb0991SDimitry Andric // For all anonymous symbols: 2460b57cec5SDimitry Andric // (1) Add their named dependencies. 2470b57cec5SDimitry Andric // (2) Add them to the worklist for further iteration if they have any 2488bcb0991SDimitry Andric // depend on any other anonymous symbols. 2490b57cec5SDimitry Andric struct WorklistEntry { 2508bcb0991SDimitry Andric WorklistEntry(Symbol *Sym, DenseSet<Symbol *> SymAnonDeps) 2518bcb0991SDimitry Andric : Sym(Sym), SymAnonDeps(std::move(SymAnonDeps)) {} 2520b57cec5SDimitry Andric 2538bcb0991SDimitry Andric Symbol *Sym = nullptr; 2548bcb0991SDimitry Andric DenseSet<Symbol *> SymAnonDeps; 2550b57cec5SDimitry Andric }; 2560b57cec5SDimitry Andric std::vector<WorklistEntry> Worklist; 2578bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 2588bcb0991SDimitry Andric if (!Sym->hasName()) { 2598bcb0991SDimitry Andric auto &SymNamedDeps = DepMap[Sym]; 2608bcb0991SDimitry Andric DenseSet<Symbol *> SymAnonDeps; 2610b57cec5SDimitry Andric 2628bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 2638bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 2648bcb0991SDimitry Andric if (TargetSym.hasName()) 2658bcb0991SDimitry Andric SymNamedDeps.insert(ES.intern(TargetSym.getName())); 2660b57cec5SDimitry Andric else { 2678bcb0991SDimitry Andric assert(TargetSym.isDefined() && 2688bcb0991SDimitry Andric "Anonymous symbols must be defined"); 2698bcb0991SDimitry Andric SymAnonDeps.insert(&TargetSym); 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric 2738bcb0991SDimitry Andric if (!SymAnonDeps.empty()) 2748bcb0991SDimitry Andric Worklist.push_back(WorklistEntry(Sym, std::move(SymAnonDeps))); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2778bcb0991SDimitry Andric // Loop over all anonymous symbols with anonymous dependencies, propagating 2780b57cec5SDimitry Andric // their respective *named* dependencies. Iterate until we hit a stable 2790b57cec5SDimitry Andric // state. 2800b57cec5SDimitry Andric bool Changed; 2810b57cec5SDimitry Andric do { 2820b57cec5SDimitry Andric Changed = false; 2830b57cec5SDimitry Andric for (auto &WLEntry : Worklist) { 2848bcb0991SDimitry Andric auto *Sym = WLEntry.Sym; 2858bcb0991SDimitry Andric auto &SymNamedDeps = DepMap[Sym]; 2868bcb0991SDimitry Andric auto &SymAnonDeps = WLEntry.SymAnonDeps; 2870b57cec5SDimitry Andric 2888bcb0991SDimitry Andric for (auto *TargetSym : SymAnonDeps) { 2898bcb0991SDimitry Andric auto I = DepMap.find(TargetSym); 2900b57cec5SDimitry Andric if (I != DepMap.end()) 2910b57cec5SDimitry Andric for (const auto &S : I->second) 2928bcb0991SDimitry Andric Changed |= SymNamedDeps.insert(S).second; 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric } while (Changed); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric return DepMap; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric void registerDependencies(const SymbolDependenceMap &QueryDeps) { 3010b57cec5SDimitry Andric for (auto &NamedDepsEntry : NamedSymbolDeps) { 3020b57cec5SDimitry Andric auto &Name = NamedDepsEntry.first; 3030b57cec5SDimitry Andric auto &NameDeps = NamedDepsEntry.second; 3040b57cec5SDimitry Andric SymbolDependenceMap SymbolDeps; 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric for (const auto &QueryDepsEntry : QueryDeps) { 3070b57cec5SDimitry Andric JITDylib &SourceJD = *QueryDepsEntry.first; 3080b57cec5SDimitry Andric const SymbolNameSet &Symbols = QueryDepsEntry.second; 3090b57cec5SDimitry Andric auto &DepsForJD = SymbolDeps[&SourceJD]; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric for (const auto &S : Symbols) 3120b57cec5SDimitry Andric if (NameDeps.count(S)) 3130b57cec5SDimitry Andric DepsForJD.insert(S); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric if (DepsForJD.empty()) 3160b57cec5SDimitry Andric SymbolDeps.erase(&SourceJD); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric MR.addDependencies(Name, SymbolDeps); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric ObjectLinkingLayer &Layer; 3240b57cec5SDimitry Andric MaterializationResponsibility MR; 3250b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ObjBuffer; 3260b57cec5SDimitry Andric DenseMap<SymbolStringPtr, SymbolNameSet> NamedSymbolDeps; 3270b57cec5SDimitry Andric }; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric ObjectLinkingLayer::Plugin::~Plugin() {} 3300b57cec5SDimitry Andric 331*480093f4SDimitry Andric ObjectLinkingLayer::ObjectLinkingLayer( 332*480093f4SDimitry Andric ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr) 333*480093f4SDimitry Andric : ObjectLayer(ES), MemMgr(std::move(MemMgr)) {} 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric ObjectLinkingLayer::~ObjectLinkingLayer() { 3360b57cec5SDimitry Andric if (auto Err = removeAllModules()) 3370b57cec5SDimitry Andric getExecutionSession().reportError(std::move(Err)); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric void ObjectLinkingLayer::emit(MaterializationResponsibility R, 3410b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> O) { 3420b57cec5SDimitry Andric assert(O && "Object must not be null"); 3438bcb0991SDimitry Andric jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>( 3440b57cec5SDimitry Andric *this, std::move(R), std::move(O))); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR, 3480b57cec5SDimitry Andric const Triple &TT, 3490b57cec5SDimitry Andric PassConfiguration &PassConfig) { 3500b57cec5SDimitry Andric for (auto &P : Plugins) 3510b57cec5SDimitry Andric P->modifyPassConfig(MR, TT, PassConfig); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) { 3550b57cec5SDimitry Andric for (auto &P : Plugins) 3560b57cec5SDimitry Andric P->notifyLoaded(MR); 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR, 3600b57cec5SDimitry Andric AllocPtr Alloc) { 3610b57cec5SDimitry Andric Error Err = Error::success(); 3620b57cec5SDimitry Andric for (auto &P : Plugins) 3630b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyEmitted(MR)); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric if (Err) 3660b57cec5SDimitry Andric return Err; 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric { 3690b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 3700b57cec5SDimitry Andric UntrackedAllocs.push_back(std::move(Alloc)); 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric return Error::success(); 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric Error ObjectLinkingLayer::removeModule(VModuleKey K) { 3770b57cec5SDimitry Andric Error Err = Error::success(); 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric for (auto &P : Plugins) 3800b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingModule(K)); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric AllocPtr Alloc; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric { 3850b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 3860b57cec5SDimitry Andric auto AllocItr = TrackedAllocs.find(K); 3870b57cec5SDimitry Andric Alloc = std::move(AllocItr->second); 3880b57cec5SDimitry Andric TrackedAllocs.erase(AllocItr); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric assert(Alloc && "No allocation for key K"); 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric return joinErrors(std::move(Err), Alloc->deallocate()); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric Error ObjectLinkingLayer::removeAllModules() { 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric Error Err = Error::success(); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric for (auto &P : Plugins) 4010b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingAllModules()); 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric std::vector<AllocPtr> Allocs; 4040b57cec5SDimitry Andric { 4050b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 4060b57cec5SDimitry Andric Allocs = std::move(UntrackedAllocs); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric for (auto &KV : TrackedAllocs) 4090b57cec5SDimitry Andric Allocs.push_back(std::move(KV.second)); 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric TrackedAllocs.clear(); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric while (!Allocs.empty()) { 4150b57cec5SDimitry Andric Err = joinErrors(std::move(Err), Allocs.back()->deallocate()); 4160b57cec5SDimitry Andric Allocs.pop_back(); 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric return Err; 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( 4238bcb0991SDimitry Andric EHFrameRegistrar &Registrar) 4240b57cec5SDimitry Andric : Registrar(Registrar) {} 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric void EHFrameRegistrationPlugin::modifyPassConfig( 4270b57cec5SDimitry Andric MaterializationResponsibility &MR, const Triple &TT, 4280b57cec5SDimitry Andric PassConfiguration &PassConfig) { 4290b57cec5SDimitry Andric assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?"); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric PassConfig.PostFixupPasses.push_back( 4328bcb0991SDimitry Andric createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr, 4338bcb0991SDimitry Andric size_t Size) { 4340b57cec5SDimitry Andric if (Addr) 4358bcb0991SDimitry Andric InProcessLinks[&MR] = { Addr, Size }; 4360b57cec5SDimitry Andric })); 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyEmitted( 4400b57cec5SDimitry Andric MaterializationResponsibility &MR) { 4410b57cec5SDimitry Andric 4428bcb0991SDimitry Andric auto EHFrameRangeItr = InProcessLinks.find(&MR); 4438bcb0991SDimitry Andric if (EHFrameRangeItr == InProcessLinks.end()) 4440b57cec5SDimitry Andric return Error::success(); 4450b57cec5SDimitry Andric 4468bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 4478bcb0991SDimitry Andric assert(EHFrameRange.Addr && 4488bcb0991SDimitry Andric "eh-frame addr to register can not be null"); 4490b57cec5SDimitry Andric 4508bcb0991SDimitry Andric InProcessLinks.erase(EHFrameRangeItr); 4510b57cec5SDimitry Andric if (auto Key = MR.getVModuleKey()) 4528bcb0991SDimitry Andric TrackedEHFrameRanges[Key] = EHFrameRange; 4530b57cec5SDimitry Andric else 4548bcb0991SDimitry Andric UntrackedEHFrameRanges.push_back(EHFrameRange); 4550b57cec5SDimitry Andric 4568bcb0991SDimitry Andric return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { 4608bcb0991SDimitry Andric auto EHFrameRangeItr = TrackedEHFrameRanges.find(K); 4618bcb0991SDimitry Andric if (EHFrameRangeItr == TrackedEHFrameRanges.end()) 4620b57cec5SDimitry Andric return Error::success(); 4630b57cec5SDimitry Andric 4648bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 4658bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null"); 4660b57cec5SDimitry Andric 4678bcb0991SDimitry Andric TrackedEHFrameRanges.erase(EHFrameRangeItr); 4680b57cec5SDimitry Andric 4698bcb0991SDimitry Andric return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { 4730b57cec5SDimitry Andric 4748bcb0991SDimitry Andric std::vector<EHFrameRange> EHFrameRanges = 4758bcb0991SDimitry Andric std::move(UntrackedEHFrameRanges); 4768bcb0991SDimitry Andric EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size()); 4770b57cec5SDimitry Andric 4788bcb0991SDimitry Andric for (auto &KV : TrackedEHFrameRanges) 4798bcb0991SDimitry Andric EHFrameRanges.push_back(KV.second); 4800b57cec5SDimitry Andric 4818bcb0991SDimitry Andric TrackedEHFrameRanges.clear(); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric Error Err = Error::success(); 4840b57cec5SDimitry Andric 4858bcb0991SDimitry Andric while (!EHFrameRanges.empty()) { 4868bcb0991SDimitry Andric auto EHFrameRange = EHFrameRanges.back(); 4878bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null"); 4888bcb0991SDimitry Andric EHFrameRanges.pop_back(); 4898bcb0991SDimitry Andric Err = joinErrors(std::move(Err), 4908bcb0991SDimitry Andric Registrar.deregisterEHFrames(EHFrameRange.Addr, 4918bcb0991SDimitry Andric EHFrameRange.Size)); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric return Err; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric } // End namespace orc. 4980b57cec5SDimitry Andric } // End namespace llvm. 499