xref: /llvm-project/llvm/lib/ExecutionEngine/Orc/EHFrameRegistrationPlugin.cpp (revision 6d12b954a7df11e32acf110950d88bac282079b8)
1*6d12b954SLang Hames //===--------- EHFrameRegistrationPlugin.cpp - Register eh-frames ---------===//
2*6d12b954SLang Hames //
3*6d12b954SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*6d12b954SLang Hames // See https://llvm.org/LICENSE.txt for license information.
5*6d12b954SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*6d12b954SLang Hames //
7*6d12b954SLang Hames //===----------------------------------------------------------------------===//
8*6d12b954SLang Hames 
9*6d12b954SLang Hames #include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
10*6d12b954SLang Hames 
11*6d12b954SLang Hames #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
12*6d12b954SLang Hames 
13*6d12b954SLang Hames #define DEBUG_TYPE "orc"
14*6d12b954SLang Hames 
15*6d12b954SLang Hames using namespace llvm::jitlink;
16*6d12b954SLang Hames 
17*6d12b954SLang Hames namespace llvm::orc {
18*6d12b954SLang Hames 
19*6d12b954SLang Hames EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
20*6d12b954SLang Hames     ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar)
21*6d12b954SLang Hames     : ES(ES), Registrar(std::move(Registrar)) {}
22*6d12b954SLang Hames 
23*6d12b954SLang Hames void EHFrameRegistrationPlugin::modifyPassConfig(
24*6d12b954SLang Hames     MaterializationResponsibility &MR, LinkGraph &G,
25*6d12b954SLang Hames     PassConfiguration &PassConfig) {
26*6d12b954SLang Hames 
27*6d12b954SLang Hames   PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass(
28*6d12b954SLang Hames       G.getTargetTriple(), [this, &MR](ExecutorAddr Addr, size_t Size) {
29*6d12b954SLang Hames         if (Addr) {
30*6d12b954SLang Hames           std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
31*6d12b954SLang Hames           assert(!InProcessLinks.count(&MR) &&
32*6d12b954SLang Hames                  "Link for MR already being tracked?");
33*6d12b954SLang Hames           InProcessLinks[&MR] = {Addr, Size};
34*6d12b954SLang Hames         }
35*6d12b954SLang Hames       }));
36*6d12b954SLang Hames }
37*6d12b954SLang Hames 
38*6d12b954SLang Hames Error EHFrameRegistrationPlugin::notifyEmitted(
39*6d12b954SLang Hames     MaterializationResponsibility &MR) {
40*6d12b954SLang Hames 
41*6d12b954SLang Hames   ExecutorAddrRange EmittedRange;
42*6d12b954SLang Hames   {
43*6d12b954SLang Hames     std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
44*6d12b954SLang Hames 
45*6d12b954SLang Hames     auto EHFrameRangeItr = InProcessLinks.find(&MR);
46*6d12b954SLang Hames     if (EHFrameRangeItr == InProcessLinks.end())
47*6d12b954SLang Hames       return Error::success();
48*6d12b954SLang Hames 
49*6d12b954SLang Hames     EmittedRange = EHFrameRangeItr->second;
50*6d12b954SLang Hames     assert(EmittedRange.Start && "eh-frame addr to register can not be null");
51*6d12b954SLang Hames     InProcessLinks.erase(EHFrameRangeItr);
52*6d12b954SLang Hames   }
53*6d12b954SLang Hames 
54*6d12b954SLang Hames   if (auto Err = MR.withResourceKeyDo(
55*6d12b954SLang Hames           [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
56*6d12b954SLang Hames     return Err;
57*6d12b954SLang Hames 
58*6d12b954SLang Hames   return Registrar->registerEHFrames(EmittedRange);
59*6d12b954SLang Hames }
60*6d12b954SLang Hames 
61*6d12b954SLang Hames Error EHFrameRegistrationPlugin::notifyFailed(
62*6d12b954SLang Hames     MaterializationResponsibility &MR) {
63*6d12b954SLang Hames   std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
64*6d12b954SLang Hames   InProcessLinks.erase(&MR);
65*6d12b954SLang Hames   return Error::success();
66*6d12b954SLang Hames }
67*6d12b954SLang Hames 
68*6d12b954SLang Hames Error EHFrameRegistrationPlugin::notifyRemovingResources(JITDylib &JD,
69*6d12b954SLang Hames                                                          ResourceKey K) {
70*6d12b954SLang Hames   std::vector<ExecutorAddrRange> RangesToRemove;
71*6d12b954SLang Hames 
72*6d12b954SLang Hames   ES.runSessionLocked([&] {
73*6d12b954SLang Hames     auto I = EHFrameRanges.find(K);
74*6d12b954SLang Hames     if (I != EHFrameRanges.end()) {
75*6d12b954SLang Hames       RangesToRemove = std::move(I->second);
76*6d12b954SLang Hames       EHFrameRanges.erase(I);
77*6d12b954SLang Hames     }
78*6d12b954SLang Hames   });
79*6d12b954SLang Hames 
80*6d12b954SLang Hames   Error Err = Error::success();
81*6d12b954SLang Hames   while (!RangesToRemove.empty()) {
82*6d12b954SLang Hames     auto RangeToRemove = RangesToRemove.back();
83*6d12b954SLang Hames     RangesToRemove.pop_back();
84*6d12b954SLang Hames     assert(RangeToRemove.Start && "Untracked eh-frame range must not be null");
85*6d12b954SLang Hames     Err = joinErrors(std::move(Err),
86*6d12b954SLang Hames                      Registrar->deregisterEHFrames(RangeToRemove));
87*6d12b954SLang Hames   }
88*6d12b954SLang Hames 
89*6d12b954SLang Hames   return Err;
90*6d12b954SLang Hames }
91*6d12b954SLang Hames 
92*6d12b954SLang Hames void EHFrameRegistrationPlugin::notifyTransferringResources(
93*6d12b954SLang Hames     JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) {
94*6d12b954SLang Hames   auto SI = EHFrameRanges.find(SrcKey);
95*6d12b954SLang Hames   if (SI == EHFrameRanges.end())
96*6d12b954SLang Hames     return;
97*6d12b954SLang Hames 
98*6d12b954SLang Hames   auto DI = EHFrameRanges.find(DstKey);
99*6d12b954SLang Hames   if (DI != EHFrameRanges.end()) {
100*6d12b954SLang Hames     auto &SrcRanges = SI->second;
101*6d12b954SLang Hames     auto &DstRanges = DI->second;
102*6d12b954SLang Hames     DstRanges.reserve(DstRanges.size() + SrcRanges.size());
103*6d12b954SLang Hames     for (auto &SrcRange : SrcRanges)
104*6d12b954SLang Hames       DstRanges.push_back(std::move(SrcRange));
105*6d12b954SLang Hames     EHFrameRanges.erase(SI);
106*6d12b954SLang Hames   } else {
107*6d12b954SLang Hames     // We need to move SrcKey's ranges over without invalidating the SI
108*6d12b954SLang Hames     // iterator.
109*6d12b954SLang Hames     auto Tmp = std::move(SI->second);
110*6d12b954SLang Hames     EHFrameRanges.erase(SI);
111*6d12b954SLang Hames     EHFrameRanges[DstKey] = std::move(Tmp);
112*6d12b954SLang Hames   }
113*6d12b954SLang Hames }
114*6d12b954SLang Hames 
115*6d12b954SLang Hames } // namespace llvm::orc
116