diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h b/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h index 1563e97fb08d..8d2f641254b3 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h @@ -27,6 +27,41 @@ Error registerEHFrameSection(const void *EHFrameSectionAddr); /// Deregisters all FDEs in the given eh-frame section with the current process. Error deregisterEHFrameSection(const void *EHFrameSectionAddr); +/// Supports registration/deregistration of EH-frames in a target process. +class EHFrameRegistrar { +public: + virtual ~EHFrameRegistrar(); + virtual Error registerEHFrames(JITTargetAddress EHFrameSectionAddr) = 0; + virtual Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr) = 0; +}; + +/// Registers / Deregisters EH-frames in the current process. +class InProcessEHFrameRegistrar final : public EHFrameRegistrar { +public: + /// Get a reference to the InProcessEHFrameRegistrar singleton. + static InProcessEHFrameRegistrar &getInstance(); + + InProcessEHFrameRegistrar(const InProcessEHFrameRegistrar &) = delete; + InProcessEHFrameRegistrar & + operator=(const InProcessEHFrameRegistrar &) = delete; + + InProcessEHFrameRegistrar(InProcessEHFrameRegistrar &&) = delete; + InProcessEHFrameRegistrar &operator=(InProcessEHFrameRegistrar &&) = delete; + + Error registerEHFrames(JITTargetAddress EHFrameSectionAddr) override { + return registerEHFrameSection( + jitTargetAddressToPointer(EHFrameSectionAddr)); + } + + Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr) override { + return deregisterEHFrameSection( + jitTargetAddressToPointer(EHFrameSectionAddr)); + } + +private: + InProcessEHFrameRegistrar(); +}; + using StoreFrameAddressFunction = std::function; /// Creates a pass that records the address of the EH frame section. If no diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 4a45ad2b92eb..c1e7d27f446e 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -33,6 +33,10 @@ namespace llvm { +namespace jitlink { +class EHFrameRegistrar; +} // namespace jitlink + namespace object { class ObjectFile; } // namespace object @@ -139,8 +143,9 @@ private: std::vector> Plugins; }; -class LocalEHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { +class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { public: + EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar); Error notifyEmitted(MaterializationResponsibility &MR) override; void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, jitlink::PassConfiguration &PassConfig) override; @@ -148,9 +153,10 @@ public: Error notifyRemovingAllModules() override; private: - DenseMap InProcessLinks; - DenseMap TrackedEHFrameAddrs; - std::vector UntrackedEHFrameAddrs; + jitlink::EHFrameRegistrar &Registrar; + DenseMap InProcessLinks; + DenseMap TrackedEHFrameAddrs; + std::vector UntrackedEHFrameAddrs; }; } // end namespace orc diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 17855f36574b..25f0e9040ffe 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -508,6 +508,15 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr) { #endif } +EHFrameRegistrar::~EHFrameRegistrar() {} + +InProcessEHFrameRegistrar &InProcessEHFrameRegistrar::getInstance() { + static InProcessEHFrameRegistrar Instance; + return Instance; +} + +InProcessEHFrameRegistrar::InProcessEHFrameRegistrar() {} + AtomGraphPassFunction createEHFrameRecorderPass(const Triple &TT, StoreFrameAddressFunction StoreFrameAddress) { diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 640d1d922c7b..def0b300eca1 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -409,7 +409,11 @@ Error ObjectLinkingLayer::removeAllModules() { return Err; } -void LocalEHFrameRegistrationPlugin::modifyPassConfig( +EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( + jitlink::EHFrameRegistrar &Registrar) + : Registrar(Registrar) {} + +void EHFrameRegistrationPlugin::modifyPassConfig( MaterializationResponsibility &MR, const Triple &TT, PassConfiguration &PassConfig) { assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?"); @@ -417,18 +421,18 @@ void LocalEHFrameRegistrationPlugin::modifyPassConfig( PassConfig.PostFixupPasses.push_back( createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr) { if (Addr) - InProcessLinks[&MR] = jitTargetAddressToPointer(Addr); + InProcessLinks[&MR] = Addr; })); } -Error LocalEHFrameRegistrationPlugin::notifyEmitted( +Error EHFrameRegistrationPlugin::notifyEmitted( MaterializationResponsibility &MR) { auto EHFrameAddrItr = InProcessLinks.find(&MR); if (EHFrameAddrItr == InProcessLinks.end()) return Error::success(); - const void *EHFrameAddr = EHFrameAddrItr->second; + auto EHFrameAddr = EHFrameAddrItr->second; assert(EHFrameAddr && "eh-frame addr to register can not be null"); InProcessLinks.erase(EHFrameAddrItr); @@ -437,25 +441,25 @@ Error LocalEHFrameRegistrationPlugin::notifyEmitted( else UntrackedEHFrameAddrs.push_back(EHFrameAddr); - return registerEHFrameSection(EHFrameAddr); + return Registrar.registerEHFrames(EHFrameAddr); } -Error LocalEHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { +Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { auto EHFrameAddrItr = TrackedEHFrameAddrs.find(K); if (EHFrameAddrItr == TrackedEHFrameAddrs.end()) return Error::success(); - const void *EHFrameAddr = EHFrameAddrItr->second; + auto EHFrameAddr = EHFrameAddrItr->second; assert(EHFrameAddr && "Tracked eh-frame addr must not be null"); TrackedEHFrameAddrs.erase(EHFrameAddrItr); - return deregisterEHFrameSection(EHFrameAddr); + return Registrar.deregisterEHFrames(EHFrameAddr); } -Error LocalEHFrameRegistrationPlugin::notifyRemovingAllModules() { +Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { - std::vector EHFrameAddrs = std::move(UntrackedEHFrameAddrs); + std::vector EHFrameAddrs = std::move(UntrackedEHFrameAddrs); EHFrameAddrs.reserve(EHFrameAddrs.size() + TrackedEHFrameAddrs.size()); for (auto &KV : TrackedEHFrameAddrs) @@ -466,10 +470,10 @@ Error LocalEHFrameRegistrationPlugin::notifyRemovingAllModules() { Error Err = Error::success(); while (!EHFrameAddrs.empty()) { - const void *EHFrameAddr = EHFrameAddrs.back(); + auto EHFrameAddr = EHFrameAddrs.back(); assert(EHFrameAddr && "Untracked eh-frame addr must not be null"); EHFrameAddrs.pop_back(); - Err = joinErrors(std::move(Err), deregisterEHFrameSection(EHFrameAddr)); + Err = joinErrors(std::move(Err), Registrar.deregisterEHFrames(EHFrameAddr)); } return Err; diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index 97956f6513d2..eff2ec18bc52 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -14,6 +14,7 @@ #include "llvm-jitlink.h" +#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -232,7 +233,8 @@ Session::Session(Triple TT) : ObjLayer(ES, MemMgr), TT(std::move(TT)) { }; if (!NoExec && !TT.isOSWindows()) - ObjLayer.addPlugin(llvm::make_unique()); + ObjLayer.addPlugin(llvm::make_unique( + InProcessEHFrameRegistrar::getInstance())); ObjLayer.addPlugin(llvm::make_unique(*this)); }