1 //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 10 11 #include "llvm/ADT/Optional.h" 12 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 13 14 #include <vector> 15 16 #define DEBUG_TYPE "orc" 17 18 using namespace llvm; 19 using namespace llvm::jitlink; 20 using namespace llvm::orc; 21 22 namespace llvm { 23 namespace orc { 24 25 class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { 26 public: 27 ObjectLinkingLayerJITLinkContext( 28 ObjectLinkingLayer &Layer, 29 std::unique_ptr<MaterializationResponsibility> MR, 30 std::unique_ptr<MemoryBuffer> ObjBuffer) 31 : JITLinkContext(&MR->getTargetJITDylib()), Layer(Layer), 32 MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} 33 34 ~ObjectLinkingLayerJITLinkContext() { 35 // If there is an object buffer return function then use it to 36 // return ownership of the buffer. 37 if (Layer.ReturnObjectBuffer && ObjBuffer) 38 Layer.ReturnObjectBuffer(std::move(ObjBuffer)); 39 } 40 41 JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; } 42 43 void notifyFailed(Error Err) override { 44 for (auto &P : Layer.Plugins) 45 Err = joinErrors(std::move(Err), P->notifyFailed(*MR)); 46 Layer.getExecutionSession().reportError(std::move(Err)); 47 MR->failMaterialization(); 48 } 49 50 void lookup(const LookupMap &Symbols, 51 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { 52 53 JITDylibSearchOrder LinkOrder; 54 MR->getTargetJITDylib().withLinkOrderDo( 55 [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); 56 57 auto &ES = Layer.getExecutionSession(); 58 59 SymbolLookupSet LookupSet; 60 for (auto &KV : Symbols) { 61 orc::SymbolLookupFlags LookupFlags; 62 switch (KV.second) { 63 case jitlink::SymbolLookupFlags::RequiredSymbol: 64 LookupFlags = orc::SymbolLookupFlags::RequiredSymbol; 65 break; 66 case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol: 67 LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol; 68 break; 69 } 70 LookupSet.add(ES.intern(KV.first), LookupFlags); 71 } 72 73 // OnResolve -- De-intern the symbols and pass the result to the linker. 74 auto OnResolve = [LookupContinuation = 75 std::move(LC)](Expected<SymbolMap> Result) mutable { 76 if (!Result) 77 LookupContinuation->run(Result.takeError()); 78 else { 79 AsyncLookupResult LR; 80 for (auto &KV : *Result) 81 LR[*KV.first] = KV.second; 82 LookupContinuation->run(std::move(LR)); 83 } 84 }; 85 86 for (auto &KV : InternalNamedSymbolDeps) { 87 SymbolDependenceMap InternalDeps; 88 InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second); 89 MR->addDependencies(KV.first, InternalDeps); 90 } 91 92 ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), 93 SymbolState::Resolved, std::move(OnResolve), 94 [this](const SymbolDependenceMap &Deps) { 95 registerDependencies(Deps); 96 }); 97 } 98 99 Error notifyResolved(LinkGraph &G) override { 100 auto &ES = Layer.getExecutionSession(); 101 102 SymbolFlagsMap ExtraSymbolsToClaim; 103 bool AutoClaim = Layer.AutoClaimObjectSymbols; 104 105 SymbolMap InternedResult; 106 for (auto *Sym : G.defined_symbols()) 107 if (Sym->hasName() && Sym->getScope() != Scope::Local) { 108 auto InternedName = ES.intern(Sym->getName()); 109 JITSymbolFlags Flags; 110 111 if (Sym->isCallable()) 112 Flags |= JITSymbolFlags::Callable; 113 if (Sym->getScope() == Scope::Default) 114 Flags |= JITSymbolFlags::Exported; 115 116 InternedResult[InternedName] = 117 JITEvaluatedSymbol(Sym->getAddress(), Flags); 118 if (AutoClaim && !MR->getSymbols().count(InternedName)) { 119 assert(!ExtraSymbolsToClaim.count(InternedName) && 120 "Duplicate symbol to claim?"); 121 ExtraSymbolsToClaim[InternedName] = Flags; 122 } 123 } 124 125 for (auto *Sym : G.absolute_symbols()) 126 if (Sym->hasName()) { 127 auto InternedName = ES.intern(Sym->getName()); 128 JITSymbolFlags Flags; 129 Flags |= JITSymbolFlags::Absolute; 130 if (Sym->isCallable()) 131 Flags |= JITSymbolFlags::Callable; 132 if (Sym->getLinkage() == Linkage::Weak) 133 Flags |= JITSymbolFlags::Weak; 134 InternedResult[InternedName] = 135 JITEvaluatedSymbol(Sym->getAddress(), Flags); 136 if (AutoClaim && !MR->getSymbols().count(InternedName)) { 137 assert(!ExtraSymbolsToClaim.count(InternedName) && 138 "Duplicate symbol to claim?"); 139 ExtraSymbolsToClaim[InternedName] = Flags; 140 } 141 } 142 143 if (!ExtraSymbolsToClaim.empty()) 144 if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim)) 145 return Err; 146 147 { 148 149 // Check that InternedResult matches up with MR->getSymbols(). 150 // This guards against faulty transformations / compilers / object caches. 151 152 // First check that there aren't any missing symbols. 153 size_t NumMaterializationSideEffectsOnlySymbols = 0; 154 SymbolNameVector ExtraSymbols; 155 SymbolNameVector MissingSymbols; 156 for (auto &KV : MR->getSymbols()) { 157 158 // If this is a materialization-side-effects only symbol then bump 159 // the counter and make sure it's *not* defined, otherwise make 160 // sure that it is defined. 161 if (KV.second.hasMaterializationSideEffectsOnly()) { 162 ++NumMaterializationSideEffectsOnlySymbols; 163 if (InternedResult.count(KV.first)) 164 ExtraSymbols.push_back(KV.first); 165 continue; 166 } else if (!InternedResult.count(KV.first)) 167 MissingSymbols.push_back(KV.first); 168 } 169 170 // If there were missing symbols then report the error. 171 if (!MissingSymbols.empty()) 172 return make_error<MissingSymbolDefinitions>(G.getName(), 173 std::move(MissingSymbols)); 174 175 // If there are more definitions than expected, add them to the 176 // ExtraSymbols vector. 177 if (InternedResult.size() > 178 MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { 179 for (auto &KV : InternedResult) 180 if (!MR->getSymbols().count(KV.first)) 181 ExtraSymbols.push_back(KV.first); 182 } 183 184 // If there were extra definitions then report the error. 185 if (!ExtraSymbols.empty()) 186 return make_error<UnexpectedSymbolDefinitions>(G.getName(), 187 std::move(ExtraSymbols)); 188 } 189 190 if (auto Err = MR->notifyResolved(InternedResult)) 191 return Err; 192 193 Layer.notifyLoaded(*MR); 194 return Error::success(); 195 } 196 197 void notifyFinalized( 198 std::unique_ptr<JITLinkMemoryManager::Allocation> A) override { 199 if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) { 200 Layer.getExecutionSession().reportError(std::move(Err)); 201 MR->failMaterialization(); 202 return; 203 } 204 if (auto Err = MR->notifyEmitted()) { 205 Layer.getExecutionSession().reportError(std::move(Err)); 206 MR->failMaterialization(); 207 } 208 } 209 210 LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override { 211 return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); }; 212 } 213 214 Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { 215 // Add passes to mark duplicate defs as should-discard, and to walk the 216 // link graph to build the symbol dependence graph. 217 Config.PrePrunePasses.push_back([this](LinkGraph &G) { 218 return claimOrExternalizeWeakAndCommonSymbols(G); 219 }); 220 221 Layer.modifyPassConfig(*MR, TT, Config); 222 223 Config.PostPrunePasses.push_back( 224 [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); 225 226 return Error::success(); 227 } 228 229 private: 230 struct LocalSymbolNamedDependencies { 231 SymbolNameSet Internal, External; 232 }; 233 234 using LocalSymbolNamedDependenciesMap = 235 DenseMap<const Symbol *, LocalSymbolNamedDependencies>; 236 237 Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) { 238 auto &ES = Layer.getExecutionSession(); 239 240 SymbolFlagsMap NewSymbolsToClaim; 241 std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym; 242 243 auto ProcessSymbol = [&](Symbol *Sym) { 244 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 245 auto Name = ES.intern(Sym->getName()); 246 if (!MR->getSymbols().count(ES.intern(Sym->getName()))) { 247 JITSymbolFlags SF = JITSymbolFlags::Weak; 248 if (Sym->getScope() == Scope::Default) 249 SF |= JITSymbolFlags::Exported; 250 NewSymbolsToClaim[Name] = SF; 251 NameToSym.push_back(std::make_pair(std::move(Name), Sym)); 252 } 253 } 254 }; 255 256 for (auto *Sym : G.defined_symbols()) 257 ProcessSymbol(Sym); 258 for (auto *Sym : G.absolute_symbols()) 259 ProcessSymbol(Sym); 260 261 // Attempt to claim all weak defs that we're not already responsible for. 262 // This cannot fail -- any clashes will just result in rejection of our 263 // claim, at which point we'll externalize that symbol. 264 cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim))); 265 266 for (auto &KV : NameToSym) 267 if (!MR->getSymbols().count(KV.first)) 268 G.makeExternal(*KV.second); 269 270 return Error::success(); 271 } 272 273 Error markResponsibilitySymbolsLive(LinkGraph &G) const { 274 auto &ES = Layer.getExecutionSession(); 275 for (auto *Sym : G.defined_symbols()) 276 if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName()))) 277 Sym->setLive(true); 278 return Error::success(); 279 } 280 281 Error computeNamedSymbolDependencies(LinkGraph &G) { 282 auto &ES = MR->getTargetJITDylib().getExecutionSession(); 283 auto LocalDeps = computeLocalDeps(G); 284 285 // Compute dependencies for symbols defined in the JITLink graph. 286 for (auto *Sym : G.defined_symbols()) { 287 288 // Skip local symbols: we do not track dependencies for these. 289 if (Sym->getScope() == Scope::Local) 290 continue; 291 assert(Sym->hasName() && 292 "Defined non-local jitlink::Symbol should have a name"); 293 294 SymbolNameSet ExternalSymDeps, InternalSymDeps; 295 296 // Find internal and external named symbol dependencies. 297 for (auto &E : Sym->getBlock().edges()) { 298 auto &TargetSym = E.getTarget(); 299 300 if (TargetSym.getScope() != Scope::Local) { 301 if (TargetSym.isExternal()) 302 ExternalSymDeps.insert(ES.intern(TargetSym.getName())); 303 else if (&TargetSym != Sym) 304 InternalSymDeps.insert(ES.intern(TargetSym.getName())); 305 } else { 306 assert(TargetSym.isDefined() && 307 "local symbols must be defined"); 308 auto I = LocalDeps.find(&TargetSym); 309 if (I != LocalDeps.end()) { 310 for (auto &S : I->second.External) 311 ExternalSymDeps.insert(S); 312 for (auto &S : I->second.Internal) 313 InternalSymDeps.insert(S); 314 } 315 } 316 } 317 318 if (ExternalSymDeps.empty() && InternalSymDeps.empty()) 319 continue; 320 321 auto SymName = ES.intern(Sym->getName()); 322 if (!ExternalSymDeps.empty()) 323 ExternalNamedSymbolDeps[SymName] = std::move(ExternalSymDeps); 324 if (!InternalSymDeps.empty()) 325 InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps); 326 } 327 328 for (auto &P : Layer.Plugins) { 329 auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR); 330 if (SyntheticLocalDeps.empty()) 331 continue; 332 333 for (auto &KV : SyntheticLocalDeps) { 334 auto &Name = KV.first; 335 auto &LocalDepsForName = KV.second; 336 for (auto *Local : LocalDepsForName) { 337 assert(Local->getScope() == Scope::Local && 338 "Dependence on non-local symbol"); 339 auto LocalNamedDepsItr = LocalDeps.find(Local); 340 if (LocalNamedDepsItr == LocalDeps.end()) 341 continue; 342 for (auto &S : LocalNamedDepsItr->second.Internal) 343 InternalNamedSymbolDeps[Name].insert(S); 344 for (auto &S : LocalNamedDepsItr->second.External) 345 ExternalNamedSymbolDeps[Name].insert(S); 346 } 347 } 348 } 349 350 return Error::success(); 351 } 352 353 LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) { 354 DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap; 355 356 // For all local symbols: 357 // (1) Add their named dependencies. 358 // (2) Add them to the worklist for further iteration if they have any 359 // depend on any other local symbols. 360 struct WorklistEntry { 361 WorklistEntry(Symbol *Sym, DenseSet<Symbol *> LocalDeps) 362 : Sym(Sym), LocalDeps(std::move(LocalDeps)) {} 363 364 Symbol *Sym = nullptr; 365 DenseSet<Symbol *> LocalDeps; 366 }; 367 std::vector<WorklistEntry> Worklist; 368 for (auto *Sym : G.defined_symbols()) 369 if (Sym->getScope() == Scope::Local) { 370 auto &SymNamedDeps = DepMap[Sym]; 371 DenseSet<Symbol *> LocalDeps; 372 373 for (auto &E : Sym->getBlock().edges()) { 374 auto &TargetSym = E.getTarget(); 375 if (TargetSym.getScope() != Scope::Local) 376 SymNamedDeps.insert(&TargetSym); 377 else { 378 assert(TargetSym.isDefined() && 379 "local symbols must be defined"); 380 LocalDeps.insert(&TargetSym); 381 } 382 } 383 384 if (!LocalDeps.empty()) 385 Worklist.push_back(WorklistEntry(Sym, std::move(LocalDeps))); 386 } 387 388 // Loop over all local symbols with local dependencies, propagating 389 // their respective non-local dependencies. Iterate until we hit a stable 390 // state. 391 bool Changed; 392 do { 393 Changed = false; 394 for (auto &WLEntry : Worklist) { 395 auto *Sym = WLEntry.Sym; 396 auto &NamedDeps = DepMap[Sym]; 397 auto &LocalDeps = WLEntry.LocalDeps; 398 399 for (auto *TargetSym : LocalDeps) { 400 auto I = DepMap.find(TargetSym); 401 if (I != DepMap.end()) 402 for (const auto &S : I->second) 403 Changed |= NamedDeps.insert(S).second; 404 } 405 } 406 } while (Changed); 407 408 // Intern the results to produce a mapping of jitlink::Symbol* to internal 409 // and external symbol names. 410 auto &ES = Layer.getExecutionSession(); 411 LocalSymbolNamedDependenciesMap Result; 412 for (auto &KV : DepMap) { 413 auto *Local = KV.first; 414 assert(Local->getScope() == Scope::Local && 415 "DepMap keys should all be local symbols"); 416 auto &LocalNamedDeps = Result[Local]; 417 for (auto *Named : KV.second) { 418 assert(Named->getScope() != Scope::Local && 419 "DepMap values should all be non-local symbol sets"); 420 if (Named->isExternal()) 421 LocalNamedDeps.External.insert(ES.intern(Named->getName())); 422 else 423 LocalNamedDeps.Internal.insert(ES.intern(Named->getName())); 424 } 425 } 426 427 return Result; 428 } 429 430 void registerDependencies(const SymbolDependenceMap &QueryDeps) { 431 for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) { 432 auto &Name = NamedDepsEntry.first; 433 auto &NameDeps = NamedDepsEntry.second; 434 SymbolDependenceMap SymbolDeps; 435 436 for (const auto &QueryDepsEntry : QueryDeps) { 437 JITDylib &SourceJD = *QueryDepsEntry.first; 438 const SymbolNameSet &Symbols = QueryDepsEntry.second; 439 auto &DepsForJD = SymbolDeps[&SourceJD]; 440 441 for (const auto &S : Symbols) 442 if (NameDeps.count(S)) 443 DepsForJD.insert(S); 444 445 if (DepsForJD.empty()) 446 SymbolDeps.erase(&SourceJD); 447 } 448 449 MR->addDependencies(Name, SymbolDeps); 450 } 451 } 452 453 ObjectLinkingLayer &Layer; 454 std::unique_ptr<MaterializationResponsibility> MR; 455 std::unique_ptr<MemoryBuffer> ObjBuffer; 456 DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps; 457 DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps; 458 }; 459 460 ObjectLinkingLayer::Plugin::~Plugin() {} 461 462 char ObjectLinkingLayer::ID; 463 464 using BaseT = RTTIExtends<ObjectLinkingLayer, ObjectLayer>; 465 466 ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES, 467 JITLinkMemoryManager &MemMgr) 468 : BaseT(ES), MemMgr(MemMgr) { 469 ES.registerResourceManager(*this); 470 } 471 472 ObjectLinkingLayer::ObjectLinkingLayer( 473 ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr) 474 : BaseT(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) { 475 ES.registerResourceManager(*this); 476 } 477 478 ObjectLinkingLayer::~ObjectLinkingLayer() { 479 assert(Allocs.empty() && "Layer destroyed with resources still attached"); 480 getExecutionSession().deregisterResourceManager(*this); 481 } 482 483 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R, 484 std::unique_ptr<MemoryBuffer> O) { 485 assert(O && "Object must not be null"); 486 auto ObjBuffer = O->getMemBufferRef(); 487 auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>( 488 *this, std::move(R), std::move(O)); 489 if (auto G = createLinkGraphFromObject(std::move(ObjBuffer))) 490 link(std::move(*G), std::move(Ctx)); 491 else 492 Ctx->notifyFailed(G.takeError()); 493 } 494 495 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R, 496 std::unique_ptr<LinkGraph> G) { 497 link(std::move(G), std::make_unique<ObjectLinkingLayerJITLinkContext>( 498 *this, std::move(R), nullptr)); 499 } 500 501 void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR, 502 const Triple &TT, 503 PassConfiguration &PassConfig) { 504 for (auto &P : Plugins) 505 P->modifyPassConfig(MR, TT, PassConfig); 506 } 507 508 void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) { 509 for (auto &P : Plugins) 510 P->notifyLoaded(MR); 511 } 512 513 Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR, 514 AllocPtr Alloc) { 515 Error Err = Error::success(); 516 for (auto &P : Plugins) 517 Err = joinErrors(std::move(Err), P->notifyEmitted(MR)); 518 519 if (Err) 520 return Err; 521 522 return MR.withResourceKeyDo( 523 [&](ResourceKey K) { Allocs[K].push_back(std::move(Alloc)); }); 524 } 525 526 Error ObjectLinkingLayer::handleRemoveResources(ResourceKey K) { 527 528 Error Err = Error::success(); 529 530 for (auto &P : Plugins) 531 Err = joinErrors(std::move(Err), P->notifyRemovingResources(K)); 532 533 std::vector<AllocPtr> AllocsToRemove; 534 getExecutionSession().runSessionLocked([&] { 535 auto I = Allocs.find(K); 536 if (I != Allocs.end()) { 537 std::swap(AllocsToRemove, I->second); 538 Allocs.erase(I); 539 } 540 }); 541 542 while (!AllocsToRemove.empty()) { 543 Err = joinErrors(std::move(Err), AllocsToRemove.back()->deallocate()); 544 AllocsToRemove.pop_back(); 545 } 546 547 return Err; 548 } 549 550 void ObjectLinkingLayer::handleTransferResources(ResourceKey DstKey, 551 ResourceKey SrcKey) { 552 auto I = Allocs.find(SrcKey); 553 if (I != Allocs.end()) { 554 auto &SrcAllocs = I->second; 555 auto &DstAllocs = Allocs[DstKey]; 556 DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size()); 557 for (auto &Alloc : SrcAllocs) 558 DstAllocs.push_back(std::move(Alloc)); 559 560 // Erase SrcKey entry using value rather than iterator I: I may have been 561 // invalidated when we looked up DstKey. 562 Allocs.erase(SrcKey); 563 } 564 565 for (auto &P : Plugins) 566 P->notifyTransferringResources(DstKey, SrcKey); 567 } 568 569 EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( 570 ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar) 571 : ES(ES), Registrar(std::move(Registrar)) {} 572 573 void EHFrameRegistrationPlugin::modifyPassConfig( 574 MaterializationResponsibility &MR, const Triple &TT, 575 PassConfiguration &PassConfig) { 576 577 PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass( 578 TT, [this, &MR](JITTargetAddress Addr, size_t Size) { 579 if (Addr) { 580 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 581 assert(!InProcessLinks.count(&MR) && 582 "Link for MR already being tracked?"); 583 InProcessLinks[&MR] = {Addr, Size}; 584 } 585 })); 586 } 587 588 Error EHFrameRegistrationPlugin::notifyEmitted( 589 MaterializationResponsibility &MR) { 590 591 EHFrameRange EmittedRange; 592 { 593 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 594 595 auto EHFrameRangeItr = InProcessLinks.find(&MR); 596 if (EHFrameRangeItr == InProcessLinks.end()) 597 return Error::success(); 598 599 EmittedRange = EHFrameRangeItr->second; 600 assert(EmittedRange.Addr && "eh-frame addr to register can not be null"); 601 InProcessLinks.erase(EHFrameRangeItr); 602 } 603 604 if (auto Err = MR.withResourceKeyDo( 605 [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); })) 606 return Err; 607 608 return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size); 609 } 610 611 Error EHFrameRegistrationPlugin::notifyFailed( 612 MaterializationResponsibility &MR) { 613 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 614 InProcessLinks.erase(&MR); 615 return Error::success(); 616 } 617 618 Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) { 619 std::vector<EHFrameRange> RangesToRemove; 620 621 ES.runSessionLocked([&] { 622 auto I = EHFrameRanges.find(K); 623 if (I != EHFrameRanges.end()) { 624 RangesToRemove = std::move(I->second); 625 EHFrameRanges.erase(I); 626 } 627 }); 628 629 Error Err = Error::success(); 630 while (!RangesToRemove.empty()) { 631 auto RangeToRemove = RangesToRemove.back(); 632 RangesToRemove.pop_back(); 633 assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null"); 634 Err = joinErrors( 635 std::move(Err), 636 Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size)); 637 } 638 639 return Err; 640 } 641 642 void EHFrameRegistrationPlugin::notifyTransferringResources( 643 ResourceKey DstKey, ResourceKey SrcKey) { 644 auto SI = EHFrameRanges.find(SrcKey); 645 if (SI != EHFrameRanges.end()) { 646 auto &SrcRanges = SI->second; 647 auto &DstRanges = EHFrameRanges[DstKey]; 648 DstRanges.reserve(DstRanges.size() + SrcRanges.size()); 649 for (auto &SrcRange : SrcRanges) 650 DstRanges.push_back(std::move(SrcRange)); 651 EHFrameRanges.erase(SI); 652 } 653 } 654 655 } // End namespace orc. 656 } // End namespace llvm. 657